<?php

namespace Myvetshop\Module\Clinique\Accounting\Export\Repository;

class InvoiceAddressRepository implements BulkRepositoryInterface
{
    protected \Db $db;

    /**
     * @var array<int, \Address>
     */
    protected array $byOrderCache;

    public function __construct(\Db $db)
    {
        $this->db = $db;
        $this->byOrderCache = [];
    }

    /**
     * Preload payment for orders
     *
     * @param \Order[] $orders
     */
    public function preload(array $orders): void
    {
        $orderIds = \array_map(
            fn (\Order $order): int => (int) $order->id,
            $orders
        );

        /**
         * @var list<array{id_order: int, id_order_detail: int, rate: string, amount: string}>|mixed $rows
         */
        $rows = $this->db->executeS(
            'SELECT o.id_order, a.* FROM `' . _DB_PREFIX_ . 'orders` o'
            . ' INNER JOIN `' . _DB_PREFIX_ . 'address` a ON a.id_address = o.id_address_invoice'
            . ' WHERE o.id_order IN (' . \implode(',', $orderIds) . ')',
            true,
            false
        );
        if (!\is_array($rows)) {
            throw new \Exception("Can't preload");
        }

        $this->byOrderCache = \array_reduce(
            $rows,
            function (array $carry, array $row): array {
                $address = new \Address();
                $address->hydrate($row);

                $carry[$row['id_order']] = $address;

                return $carry;
            },
            []
        );
    }

    public function getByOrder(\Order $order): \Address
    {
        $id = (int) $order->id;

        $ret = $this->byOrderCache[$id] ?? null;

        if (null === $ret) {
            $ret = new \Address((int) $order->id_address_invoice);
            $this->byOrderCache[$id] = $ret;
        }

        return $ret;
    }

    public function clear(): void
    {
        $this->byOrderCache = [];
    }
}
