<?php

declare(strict_types=1);

namespace CloudXM\NFe\DTOs;

/**
 * Invoice Resource DTO
 * 
 * Represents the v2 API response for invoice operations
 */
class InvoiceResource
{
    public function __construct(
        public ?string $id = null,
        public ?string $status = null,
        public ?string $processing_strategy = null,
        public array $allowed_actions = [],
        public ?LifecycleData $lifecycle = null,
        public ?NfseData $nfse = null,
        public ?DocumentsData $documents = null,
        public ?array $client = null,
        public array $services = [],
        public ?string $order_id = null,
        public ?string $total_amount = null,
        public ?string $municipality_code = null,
        public ?bool $debug = null,
        public ?string $xml = null,
        public ?int $xml_size = null,
        public ?string $dps_id = null,
        public ?string $dps_number = null,
        public ?string $environment = null,
        public ?int $tenant_id = null,
        public ?string $error_message = null
    ) {}

    /**
     * Create from API response array
     * 
     * @throws \InvalidArgumentException if required fields are missing
     */
    public static function fromArray(array $data): self
    {
        // Parse nested objects
        $lifecycle = isset($data['lifecycle']) && is_array($data['lifecycle'])
            ? LifecycleData::fromArray($data['lifecycle'])
            : null;

        $nfse = isset($data['nfse']) && is_array($data['nfse'])
            ? NfseData::fromArray($data['nfse'])
            : null;

        $documents = isset($data['documents']) && is_array($data['documents'])
            ? DocumentsData::fromArray($data['documents'])
            : null;

        return new self(
            id: isset($data['id']) ? (string) $data['id'] : null,
            status: isset($data['status']) ? (string) $data['status'] : null,
            processing_strategy: isset($data['processing_strategy']) ? (string) $data['processing_strategy'] : null,
            allowed_actions: $data['allowed_actions'] ?? [],
            lifecycle: $lifecycle,
            nfse: $nfse,
            documents: $documents,
            client: $data['client'] ?? null,
            services: $data['services'] ?? [],
            order_id: isset($data['order_id']) ? (string) $data['order_id'] : null,
            total_amount: isset($data['total_amount']) ? (string) $data['total_amount'] : null,
            municipality_code: isset($data['municipality_code']) ? (string) $data['municipality_code'] : null,
            debug: $data['debug'] ?? null,
            xml: $data['xml'] ?? null,
            xml_size: $data['xml_size'] ?? null,
            dps_id: isset($data['dps_id']) ? (string) $data['dps_id'] : null,
            dps_number: isset($data['dps_number']) ? (string) $data['dps_number'] : (isset($data['nfse']['dps_number']) ? (string) $data['nfse']['dps_number'] : null),
            environment: isset($data['environment']) ? (string) $data['environment'] : null,
            tenant_id: isset($data['tenant_id']) ? (int) $data['tenant_id'] : null,
            error_message: isset($data['error_message']) ? (string) $data['error_message'] : null
        );
    }

    /**
     * Validate invoice resource
     * 
     * @return array Empty array if valid, array of errors if invalid
     */
    public function validate(): array
    {
        $errors = [];

        // Validate nested objects
        if ($this->lifecycle !== null) {
            $lifecycleErrors = $this->lifecycle->validate();
            if (!empty($lifecycleErrors)) {
                $errors['lifecycle'] = $lifecycleErrors;
            }
        }

        if ($this->nfse !== null) {
            $nfseErrors = $this->nfse->validate();
            if (!empty($nfseErrors)) {
                $errors['nfse'] = $nfseErrors;
            }
        }

        if ($this->documents !== null) {
            $documentsErrors = $this->documents->validate();
            if (!empty($documentsErrors)) {
                $errors['documents'] = $documentsErrors;
            }
        }

        // Validate status values
        $validStatuses = ['processing', 'issued', 'cancelled', 'failed'];
        if ($this->status !== null && !in_array($this->status, $validStatuses, true)) {
            $errors['status'] = 'Invalid status value';
        }

        // Validate processing_strategy values
        $validStrategies = ['synchronous', 'asynchronous', 'debug'];
        if ($this->processing_strategy !== null && !in_array($this->processing_strategy, $validStrategies, true)) {
            $errors['processing_strategy'] = 'Invalid processing strategy value';
        }

        return $errors;
    }
}
