<?php

namespace Opencart\Extension\Alsendo\DTO\Unified;

require_once(DIR_EXTENSION . 'alsendo/src/Models/WrapperResult.php');

use Opencart\Extension\Alsendo\Models\WrapperResult;

class OrderSubmitResultDTO
{
    public ?string $id = null;
    public ?int $serviceId = null;
    public ?string $serviceName = null;
    public array $waybillNumbers = [];
    public array $trackingUrls = [];
    public ?string $status = null;
    public ?int $shipmentsCount = null;
    public ?string $content = null;
    public ?string $comment = null;

    // Receiver fields
    public ?string $receiverName = null;
    public ?string $receiverContactPerson = null;
    public ?string $receiverEmail = null;
    public ?string $receiverPhone = null;
    public ?string $receiverLine1 = null;
    public ?string $receiverLine2 = null;
    public ?string $receiverPostalCode = null;
    public ?string $receiverCity = null;
    public ?string $receiverCountryCode = null;
    public ?bool $receiverHasMapPoint = null;
    public ?string $receiverMapPointId = null;

    public array $shipments = [];

    public ?string $createdDate = null;
    public ?string $createdTimezone = null;

    /** @var array<mixed> */
    public array $additional = [];
    public static function fromWrapperResult(WrapperResult $wrapperResult): self
    {
        $data = $wrapperResult->getData();
        $dto = new self();

        // Top-level fields
        $dto->id = $data['id'] ?? null;
        $dto->serviceId = isset($data['service_id']) ? (int)$data['service_id'] : null;
        $dto->serviceName = $data['service_name'] ?? null;
        $dto->status = $data['status'] ?? null;
        $dto->shipmentsCount = $data['shipments_count'] ?? null;
        $dto->content = $data['content'] ?? null;
        $dto->comment = $data['comment'] ?? null;

        $dto->waybillNumbers = isset($data['waybill_number']) ? [$data['waybill_number']] : [];
        $dto->trackingUrls = isset($data['tracking_url']) ? [$data['tracking_url']] : [];

        if (isset($data['receiver'])) {
            $receiver = $data['receiver'];
            $dto->receiverName = $receiver['name'] ?? null;
            $dto->receiverContactPerson = $receiver['contact_person'] ?? null;
            $dto->receiverEmail = $receiver['email'] ?? null;
            $dto->receiverPhone = $receiver['phone'] ?? null;
            $dto->receiverLine1 = $receiver['line1'] ?? null;
            $dto->receiverLine2 = $receiver['line2'] ?? null;
            $dto->receiverPostalCode = $receiver['postal_code'] ?? null;
            $dto->receiverCity = $receiver['city'] ?? null;
            $dto->receiverCountryCode = $receiver['country_code'] ?? null;
            $dto->receiverHasMapPoint = $receiver['has_map_point'] ?? null;
            $dto->receiverMapPointId = $receiver['map_point_id'] ?? null;
        }

        $dto->shipments = $data['shipments'] ?? [];

        if (isset($data['created'])) {
            $dto->createdDate = $data['created']['date'] ?? null;
            $dto->createdTimezone = $data['created']['timezone'] ?? null;
        }

        return $dto;
    }

    public function toArray(): array
    {
        return $this->convertToArray($this);
    }

    private function convertToArray(mixed $value): array
    {
        if (is_object($value)) {
            $value = get_object_vars($value);
        }

        if (is_array($value)) {
            $result = [];
            foreach ($value as $key => $item) {
                if (is_object($item) || is_array($item)) {
                    $result[$key] = $this->convertToArray($item);
                } else {
                    $result[$key] = $item;
                }
            }
            return $result;
        }

        return [$value];
    }
}