<?php

declare(strict_types=1);

namespace CloudXM\NFe\DTOs;

use JsonSerializable;

/**
 * Client Data DTO
 * 
 * Represents customer information for invoice
 */
class ClientData implements JsonSerializable
{
    public function __construct(
        public string $name,
        public string $document,
        public string $email,
        public ?string $phone = null,
        public ?AddressData $address = null
    ) {}

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

        if (empty($this->name)) {
            $errors['name'] = 'Client name is required';
        }

        if (empty($this->document)) {
            $errors['document'] = 'Client document is required';
        } elseif (!$this->isValidDocument($this->document)) {
            $errors['document'] = 'Invalid document format (CPF/CNPJ)';
        }

        if (empty($this->email)) {
            $errors['email'] = 'Client email is required';
        } elseif (!filter_var($this->email, FILTER_VALIDATE_EMAIL)) {
            $errors['email'] = 'Invalid email format';
        }

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

        return $errors;
    }

    /**
     * Validate Brazilian CPF or CNPJ document
     */
    private function isValidDocument(string $document): bool
    {
        // Remove non-numeric characters
        $document = preg_replace('/\D/', '', $document);

        // CPF has 11 digits, CNPJ has 14 digits
        return strlen($document) === 11 || strlen($document) === 14;
    }

    /**
     * Serialize to JSON for API request
     */
    public function jsonSerialize(): array
    {
        $data = [
            'name' => $this->name,
            'document' => $this->document,
            'email' => $this->email,
        ];

        if ($this->phone !== null) {
            $data['phone'] = $this->phone;
        }

        if ($this->address !== null) {
            $data['address'] = $this->address->jsonSerialize();
        }

        return $data;
    }
}
