<?php
/**
 * One order line covered by a withdrawal declaration.
 *
 * @package SkyServers\Retragere
 */

declare(strict_types=1);

namespace SkyServers\Retragere\Core;

use InvalidArgumentException;

/**
 * Immutable value object.
 */
final class RequestLine
{
    /** @var int */
    private $itemId;

    /** @var int */
    private $productId;

    /** @var int */
    private $variationId;

    /** @var string */
    private $name;

    /** @var int */
    private $qty;

    /** @var string */
    private $sku;

    /**
     * The SKU is optional and last on purpose: records written before it
     * existed deserialise without it, and nothing older breaks.
     */
    public function __construct(
        int $itemId,
        int $productId,
        int $variationId,
        string $name,
        int $qty,
        string $sku = ''
    ) {
        if ($qty < 1) {
            throw new InvalidArgumentException('Withdrawal line quantity must be at least 1.');
        }

        $this->itemId      = $itemId;
        $this->productId   = $productId;
        $this->variationId = $variationId;
        $this->name        = $name;
        $this->qty         = $qty;
        $this->sku         = $sku;
    }

    public function itemId(): int
    {
        return $this->itemId;
    }

    public function productId(): int
    {
        return $this->productId;
    }

    public function variationId(): int
    {
        return $this->variationId;
    }

    public function name(): string
    {
        return $this->name;
    }

    public function qty(): int
    {
        return $this->qty;
    }

    public function sku(): string
    {
        return $this->sku;
    }

    /**
     * @return array{item_id:int,product_id:int,variation_id:int,name:string,qty:int,sku:string}
     */
    public function toArray(): array
    {
        return [
            'item_id'      => $this->itemId,
            'product_id'   => $this->productId,
            'variation_id' => $this->variationId,
            'name'         => $this->name,
            'qty'          => $this->qty,
            'sku'          => $this->sku,
        ];
    }

    /**
     * @param array<string,mixed> $data
     */
    public static function fromArray(array $data): self
    {
        return new self(
            (int) ($data['item_id'] ?? 0),
            (int) ($data['product_id'] ?? 0),
            (int) ($data['variation_id'] ?? 0),
            (string) ($data['name'] ?? ''),
            (int) ($data['qty'] ?? 0),
            (string) ($data['sku'] ?? '')
        );
    }
}
