<?php

namespace App\DTOs\Production;

use InvalidArgumentException;

/**
 * dynamic_bom JSON 항목 DTO
 *
 * work_order_items.options.dynamic_bom 배열의 각 엔트리를 표현
 */
class DynamicBomEntry
{
    public function __construct(
        public readonly int $child_item_id,
        public readonly string $child_item_code,
        public readonly string $lot_prefix,
        public readonly string $part_type,
        public readonly string $category,
        public readonly string $material_type,
        public readonly int $length_mm,
        public readonly int|float $qty,
    ) {}

    /**
     * 배열에서 DTO 생성
     */
    public static function fromArray(array $data): self
    {
        self::validate($data);

        return new self(
            child_item_id: (int) $data['child_item_id'],
            child_item_code: (string) $data['child_item_code'],
            lot_prefix: (string) $data['lot_prefix'],
            part_type: (string) $data['part_type'],
            category: (string) $data['category'],
            material_type: (string) $data['material_type'],
            length_mm: (int) $data['length_mm'],
            qty: $data['qty'],
        );
    }

    /**
     * DTO → 배열 변환 (JSON 저장용)
     */
    public function toArray(): array
    {
        return [
            'child_item_id' => $this->child_item_id,
            'child_item_code' => $this->child_item_code,
            'lot_prefix' => $this->lot_prefix,
            'part_type' => $this->part_type,
            'category' => $this->category,
            'material_type' => $this->material_type,
            'length_mm' => $this->length_mm,
            'qty' => $this->qty,
        ];
    }

    /**
     * 필수 필드 검증
     *
     * @throws InvalidArgumentException
     */
    public static function validate(array $data): bool
    {
        $required = ['child_item_id', 'child_item_code', 'lot_prefix', 'part_type', 'category', 'material_type', 'length_mm', 'qty'];

        foreach ($required as $field) {
            if (! array_key_exists($field, $data) || $data[$field] === null) {
                throw new InvalidArgumentException("DynamicBomEntry: '{$field}' is required");
            }
        }

        if ((int) $data['child_item_id'] <= 0) {
            throw new InvalidArgumentException('DynamicBomEntry: child_item_id must be positive');
        }

        $validCategories = ['guideRail', 'bottomBar', 'shutterBox', 'smokeBarrier'];
        if (! in_array($data['category'], $validCategories, true)) {
            throw new InvalidArgumentException('DynamicBomEntry: category must be one of: '.implode(', ', $validCategories));
        }

        if ($data['qty'] <= 0) {
            throw new InvalidArgumentException('DynamicBomEntry: qty must be positive');
        }

        return true;
    }

    /**
     * DynamicBomEntry 배열 → JSON 저장용 배열 변환
     *
     * @param  DynamicBomEntry[]  $entries
     */
    public static function toArrayList(array $entries): array
    {
        return array_map(fn (self $e) => $e->toArray(), $entries);
    }
}
