<?php
/**
 * Stock data model.
 *
 * @package flo-sync
 *
 * @phpcs:disable Generic.Commenting.DocComment.MissingShort
 */

namespace NMFS\Sync\Items\Articles\Stock\Models;

use Northmill_Online_Shared_Sync\Northmill_Online_Shared\Abstracts\Hub_API\Hub_Accounts\Models\Hub_Account_Model;
use Northmill_Online_Shared_Sync\Northmill_Online_Shared\Abstracts\Hub_API\Hub_Accounts\WP_Repository;
use Northmill_Online_Shared_Sync\Northmill_Online_Shared\Interfaces\JsonUnserializable;
use Northmill_Online_Shared_Sync\Northmill_Online_Shared\Traits\Json_Decode_Trait;

defined( 'ABSPATH' ) || exit;

/**
 * Class Stock_Data_Model
 */
class Stock_Data_Model implements JsonUnserializable {
	use Json_Decode_Trait;

	/**
	 * Constructor.
	 *
	 * @param int                    $hub_account_id        WP post-ID of Hub Account that this stock is for.
	 * @param float                  $quantity              Quantity of the article in stock.
	 * @param bool                   $article_exists_in_hub Whether the article exists in the Hub account.
	 *                                                      Not stored in DB.
	 * @param Hub_Account_Model|null $hub_account           Hub account that this stock is for.
	 */
	public function __construct(
		public int $hub_account_id,
		public float $quantity,
		public bool $article_exists_in_hub,
		public ?Hub_Account_Model $hub_account = null,
	) {}

	/**
	 * Set Hub account property using id.
	 */
	public function load_hub_account(): void {
		if ( empty( $this->hub_account_id ) ) {
			return;
		}

		$this->hub_account = WP_Repository::get_account_by_post_id(
			$this->hub_account_id
		);
	}

	/**
	 * {@inheritDoc}
	 */
	public function jsonSerialize(): array {
		return array(
			'hub_account_id'        => $this->hub_account_id,
			'quantity'              => $this->quantity,
			'article_exists_in_hub' => $this->article_exists_in_hub,
		);
	}

	/**
	 * Takes a JSON string matching what is returned by jsonSerialize() and returns an instance of the class.
	 *
	 * @param string|array $data JSON data. This is either a JSON string or an already decoded array.
	 *
	 * @return static|null The instance of the class, or null if the data is invalid.
	 */
	public static function jsonUnserialize( array|string $data ): ?static {
		$data = self::decode_json_data( $data, array( 'hub_account_id', 'quantity' ) );

		if ( ! is_array( $data ) ) {
			return null;
		}

		return new static(
			$data['hub_account_id'],
			$data['quantity'],
			(bool) $data['article_exists_in_hub'],
		);
	}
}
