<?php

namespace Myvetshop\Module\Clinique\Accounting\Export\Exporter\Provider\Vat;

use Myvetshop\Module\Clinique\Accounting\Export\Repository\OrderDetailTaxRepository;
use Myvetshop\Module\Clinique\Accounting\Export\Repository\OrderInvoiceTaxRepository;
use Myvetshop\Module\Clinique\Accounting\Export\Repository\OrderSlipDetailRepository;

/**
 * @implements VatExporterInterface<\OrderSlip>
 */
class OrderSlipVatExporter implements VatExporterInterface
{
    protected OrderDetailTaxRepository $orderDetailTaxRepository;

    protected OrderInvoiceTaxRepository $orderInvoiceTaxRepository;

    protected OrderSlipDetailRepository $orderSlipDetailRepository;

    public function __construct(
        OrderDetailTaxRepository $orderDetailTaxRepository,
        OrderInvoiceTaxRepository $orderInvoiceTaxRepository,
        OrderSlipDetailRepository $orderSlipDetailRepository
    ) {
        $this->orderDetailTaxRepository = $orderDetailTaxRepository;
        $this->orderInvoiceTaxRepository = $orderInvoiceTaxRepository;
        $this->orderSlipDetailRepository = $orderSlipDetailRepository;
    }

    /**
     * @return array<numeric-string, float>
     */
    public function getVatValuesShipping(\OrderSlip $orderSlip): array
    {
        // TODO : Améliorer
        if ($orderSlip->total_shipping_tax_incl == $orderSlip->total_shipping_tax_excl) {
            return [];
        }

        // @phpstan-ignore-next-line
        return [
            '20.000' => \round(
                $orderSlip->total_shipping_tax_incl - $orderSlip->total_shipping_tax_excl,
                2
            ),
        ];
    }

    /**
     * @return array<numeric-string, float>
     */
    public function getVatValuesProducts(\OrderSlip $orderSlip, \Order $order): array
    {
        $orderDetailTax = $this->orderDetailTaxRepository->getByOrder($order);

        return \array_reduce(
            $this->orderSlipDetailRepository->getByOrderSlip($orderSlip),
            function (array $carry, array $row) use ($orderDetailTax) {
                $taxDetail = $orderDetailTax[$row['id_order_detail']] ?? null;

                if (!$taxDetail) {
                    throw new \Exception("Can't get order detail tax");
                }

                $rate = \number_format($taxDetail['rate'], 3, '.', '');

                $carry[$rate] = ($carry[$rate] ?? 0.0) + $row['amount_tax_excl'];

                return $carry;
            },
            []
        );
    }

    public function getVatValues(object $document, \Order $order): array
    {
        $ret = $this->getVatValuesShipping($document);

        foreach ($this->getVatValuesProducts($document, $order) as $rate => $amount) {
            $ret[$rate] = ($ret[$rate] ?? 0.0) + $amount;
        }

        return $ret;
    }
}
