<?php

namespace App\Modules\FactReceipt\Domain;

use App\Modules\FactCurrency\Domain\IdFactCurrency;
use App\Modules\FactPaymentMethod\Domain\IdFactPaymentMethod;
use App\Modules\FactTypeDocument\Domain\IdFactTypeDocument;
use App\Modules\FactTypeReceipt\Domain\IdFactTypeReceipt;
use App\Modules\Shared\Domain\Aggregate\AggregateAttribute;
use App\Modules\Shared\Domain\Aggregate\AggregateRoot;

class FactReceipt extends AggregateRoot
{

    /** @return AgregateAttribute[] */
    protected static function attributes(): array
    {
        return [
            new AggregateAttribute('id', IdFactReceipt::class, 'Id_FactReceipt'),
            new AggregateAttribute('date', FactReceiptDate::class, 'FactReceipt_Date'),
            new AggregateAttribute('dateUpdate', FactReceiptDateUpdate::class, 'FactReceipt_DateUpdate'),
            new AggregateAttribute('dateEmission', FactReceiptDateEmission::class, 'FactReceipt_DateEmission'),
            new AggregateAttribute('noDocument', FactReceiptNoDocument::class, 'FactReceipt_NoDocument'),
            new AggregateAttribute('businessName', FactReceiptBusinessName::class, 'FactReceipt_BusinessName'),
            new AggregateAttribute('email', FactReceiptEmail::class, 'FactReceipt_Email'),
            new AggregateAttribute('address', FactReceiptAddress::class, 'FactReceipt_Address'),
            new AggregateAttribute('licensePlate', FactReceiptLicensePlate::class, 'FactReceipt_LicensePlate'),
            new AggregateAttribute('currency', FactReceiptCurrency::class, 'FactReceipt_Currency'),
            new AggregateAttribute('responseMessage', FactReceiptResponseMessage::class, 'FactReceipt_ResponseMessage'),
            new AggregateAttribute('status', FactReceiptStatus::class, 'FactReceipt_Status'),
            new AggregateAttribute('idFactTypeReceipt', IdFactTypeReceipt::class, 'Id_FactTypeReceipt'),
            new AggregateAttribute('idFactTypeDocument', IdFactTypeDocument::class, 'Id_FactTypeDocument'),
            new AggregateAttribute('idFactPaymentMethod', IdFactPaymentMethod::class, 'Id_FactPaymentMethod'),
            new AggregateAttribute('idFactCurrency', IdFactCurrency::class, 'Id_FactCurrency'),
        ];
    }

    public function __construct(
        private IdFactReceipt $id,
        private FactReceiptDate $date,
        private FactReceiptDateUpdate $dateUpdate,
        private FactReceiptDateEmission $dateEmission,
        private FactReceiptNoDocument $noDocument,
        private FactReceiptBusinessName $businessName,
        private FactReceiptEmail $email,
        private FactReceiptAddress $address,
        private FactReceiptLicensePlate $licensePlate,
        private FactReceiptCurrency $currency,
        private FactReceiptResponseMessage $responseMessage,
        private FactReceiptStatus $status,
        private IdFactTypeReceipt $idFactTypeReceipt,
        private IdFactTypeDocument $idFactTypeDocument,
        private IdFactPaymentMethod $idFactPaymentMethod,
        private IdFactCurrency $idFactCurrency,
    ) {
    }

    public function id(): IdFactReceipt
    {
        return $this->id;
    }

    public function date(): FactReceiptDate
    {
        return $this->date;
    }

    public function dateUpdate(): FactReceiptDateUpdate
    {
        return $this->dateUpdate;
    }

    public function dateEmission(): FactReceiptDateEmission
    {
        return $this->dateEmission;
    }

    public function noDocument(): FactReceiptNoDocument
    {
        return $this->noDocument;
    }

    public function businessName(): FactReceiptBusinessName
    {
        return $this->businessName;
    }

    public function email(): FactReceiptEmail
    {
        return $this->email;
    }

    public function address(): FactReceiptAddress
    {
        return $this->address;
    }

    public function licensePlate(): FactReceiptLicensePlate
    {
        return $this->licensePlate;
    }

    public function currency(): FactReceiptCurrency
    {
        return $this->currency;
    }

    public function responseMessage(): FactReceiptResponseMessage
    {
        return $this->responseMessage;
    }

    public function status(): FactReceiptStatus
    {
        return $this->status;
    }

    public function idFactTypeReceipt(): IdFactTypeReceipt
    {
        return $this->idFactTypeReceipt;
    }

    public function idFactTypeDocument(): IdFactTypeDocument
    {
        return $this->idFactTypeDocument;
    }

    public function idFactPaymentMethod(): IdFactPaymentMethod
    {
        return $this->idFactPaymentMethod;
    }

    public function idFactCurrency(): IdFactCurrency
    {
        return $this->idFactCurrency;
    }

    public function delete()
    {
        $this->status = new FactReceiptStatus(FactReceiptStatus::DELETED);
    }

    public function send()
    {
        $this->status = new FactReceiptStatus(FactReceiptStatus::SENT);
    }

    public function receive(FactReceiptResponseMessage $responseMessage)
    {
        $this->status = new FactReceiptStatus(FactReceiptStatus::RECEIVED);
        $this->responseMessage = $responseMessage;
    }

    public function error(FactReceiptResponseMessage $responseMessage)
    {
        $this->status = new FactReceiptStatus(FactReceiptStatus::ERROR);
        $this->responseMessage = $responseMessage;
    }

    public function generateSyncReceipt()
    {
        $data = (object)[];
        new DTOSyncFacturaBoleta(
            $data->FactTypeReceipt->FactTypeReceipt_Code,
            $data->FactTypeDocument->FactTypeDocument_Code,
            $data->FactReceipt_NoDocument,
            $data->FactReceipt_BusinessName,
            $data->FactReceipt_Email,
            $data->FactReceipt_Address,
            $data->FactReceipt_LicensePlate,
            $data->FactReceipt_Currency,
            $this->generateReceiptItems($data->FactItems),
        );
    }

    public function generateReceipt()
    {
        $data = (object)[];
        new DTOSyncFacturaBoleta(
            $data->FactTypeReceipt->FactTypeReceipt_Code,
            $data->FactTypeDocument->FactTypeDocument_Code,
            $data->FactReceipt_NoDocument,
            $data->FactReceipt_BusinessName,
            $data->FactReceipt_Email,
            $data->FactReceipt_Address,
            $data->FactReceipt_LicensePlate,
            $data->FactReceipt_Currency,
            $this->generateReceiptItems($data->FactItems),
        );
    }

    public function generateReceiptItems($factItems)
    {
        return array_map(
            fn ($item) => new DTOSyncItemFacBo(
                $item->FactProduct->FactProduct_Code,
                $item->FactProduct->FactProduct_Description,
                $item->FactReceiptDetail_Amount,
                $item->FactReceiptDetail_UnitPrice,
                $item->FactReceiptDetail_Discount,
                $item->FactTypeOperation_Code,
                $item->FactProduct->FactUnit->FactUnit_Code
            ),
            $factItems
        );
    }
}
