<?php

namespace Daniv04\HaciendaPackage\Providers\Hacienda\Data;

use Daniv04\HaciendaPackage\Providers\Hacienda\Data\IdentificationData;

class HaciendaDto
{
    /**
     * Electronic receipt numeric key (50 digits)
     *
     * @var string
     */
    private string $clave;

    /**
     * Receipt date in RFC3339 format (yyyy-MM-dd'T'HH:mm:ssZ)
     *
     * @var string
     */
    private string $fecha;

    /**
     * Issuer identification data
     *
     * @var IdentificationData
     */
    private IdentificationData $emisor;

    /**
     * Recipient identification data (optional)
     *
     * @var IdentificationData|null
     */
    private ?IdentificationData $receptor = null;

    /**
     * Callback URL for Hacienda responses (optional)
     *
     * @var string|null
     */
    private ?string $callbackUrl = null;

    /**
     * Consecutive number for confirmation messages (optional)
     *
     * @var string|null
     */
    private ?string $consecutivoReceptor = null;

    /**
     * Signed electronic receipt in Base64 format
     *
     * @var string
     */
    private string $comprobanteXml;

    /**
     * Constructor
     *
     * @param string $clave Electronic receipt numeric key
     * @param string $fecha Receipt date in RFC3339 format
     * @param IdentificationData $emisor Issuer identification
     * @param string $comprobanteXml Signed XML in Base64 format
     */
    public function __construct(
        string $clave,
        string $fecha,
        IdentificationData $emisor,
        string $comprobanteXml,
        ?string $callbackUrl = null
    ) {
        $this->clave = $clave;
        $this->fecha = $fecha;
        $this->emisor = $emisor;
        $this->comprobanteXml = $comprobanteXml;
        $this->callbackUrl = $callbackUrl;
    }

    /**
     * Get the electronic receipt numeric key
     */
    public function getClave(): string
    {
        return $this->clave;
    }

    /**
     * Get the receipt date
     */
    public function getFecha(): string
    {
        return $this->fecha;
    }

    /**
     * Get the issuer identification data
     */
    public function getEmisor(): IdentificationData
    {
        return $this->emisor;
    }

    /**
     * Get the recipient identification data
     */
    public function getReceptor(): ?IdentificationData
    {
        return $this->receptor;
    }

    /**
     * Set the recipient identification data
     */
    public function setReceptor(IdentificationData $receptor): self
    {
        $this->receptor = $receptor;
        return $this;
    }

    /**
     * Get the callback URL
     */
    public function getCallbackUrl(): ?string
    {
        return $this->callbackUrl;
    }

    /**
     * Set the callback URL
     */
    public function setCallbackUrl(string $callbackUrl): self
    {
        $this->callbackUrl = $callbackUrl;
        return $this;
    }

    /**
     * Get the consecutive receptor number
     */
    public function getConsecutivoReceptor(): ?string
    {
        return $this->consecutivoReceptor;
    }

    /**
     * Set the consecutive receptor number
     */
    public function setConsecutivoReceptor(string $consecutivoReceptor): self
    {
        $this->consecutivoReceptor = $consecutivoReceptor;
        return $this;
    }

    /**
     * Get the signed XML comprobante in Base64 format
     */
    public function getComprobanteXml(): string
    {
        return $this->comprobanteXml;
    }

    /**
     * Convert to array for JSON serialization
     */
    public function toArray(): array
    {
        $data = [
            'clave' => $this->clave,
            'fecha' => $this->fecha,
            'emisor' => $this->emisor->toArray(),
            'comprobanteXml' => $this->comprobanteXml,
        ];

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

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

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

        return $data;
    }

    /**
     * Convert to JSON string
     */
    public function toJson(): string
    {
        return json_encode($this->toArray(), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
    }
}
