<?php

namespace Myvetshop\Module\Clinique\Adapter\Repository;

use Myvetshop\Module\Clinique\Entity\MyvetshopTarifSpecifique;

class SpecificPriceRepository
{
    private \Db $db;

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

    /**
     * @param MyvetshopTarifSpecifique $tarifSpecifique
     * @param list<int> $groupIds
     *
     * @return list<\SpecificPrice>
     */
    public function findByTarifSpecifiqueAndGroups(MyvetshopTarifSpecifique $tarifSpecifique, array $groupIds): array
    {
        $rows = $this->db->executeS(
            'SELECT sp.*
                FROM `' . _DB_PREFIX_ . 'specific_price` sp
                WHERE sp.`id_product` = ' . $tarifSpecifique->idProduct . '
                    AND sp.`id_product_attribute` = ' . (int) $tarifSpecifique->idProductAttribute . '
                    AND sp.`id_cart` = 0
                    AND sp.`id_group` IN (' . \implode(',', $groupIds) . ')'
        );

        if (!\is_array($rows)) {
            $rows = [];
        }

        /** @var list<\SpecificPrice> $specificPrices */
        $specificPrices = \ObjectModel::hydrateCollection(
            \SpecificPrice::class,
            $rows
        );

        return $specificPrices;
    }

    /**
     * @param MyvetshopTarifSpecifique $tarifSpecifique
     *
     * @return list<\SpecificPrice>
     */
    public function findByTarifSpecifique(MyvetshopTarifSpecifique $tarifSpecifique): array
    {
        $rows = $this->db->executeS(
            'SELECT sp.*
                FROM `' . _DB_PREFIX_ . 'specific_price` sp
                WHERE sp.`id_product` = ' . $tarifSpecifique->idProduct . '
                    AND sp.`id_product_attribute` = ' . (int) $tarifSpecifique->idProductAttribute . '
                    AND sp.`id_cart` = 0'
        );

        if (!\is_array($rows)) {
            $rows = [];
        }

        /** @var list<\SpecificPrice> $specificPrices */
        $specificPrices = \ObjectModel::hydrateCollection(
            \SpecificPrice::class,
            $rows
        );

        return $specificPrices;
    }

    /**
     * @param list<array{id_specific_price: int}> $rows
     *
     * @return void
     */
    public function purgeRows(array $rows): void
    {
        /** @var list<int> $ids */
        $ids = \array_map(
            function (array $row): int { return $row['id_specific_price']; },
            $rows
        );

        if (empty($ids)) {
            return;
        }

        $this->db->execute(
            'DELETE FROM `ps_specific_price`'
            . ' WHERE id_specific_price IN (' . \implode(',', $ids) . ')'
        );
    }

    public function purgeOlds(): void
    {
        // Purge par id_product_attribute qui n'existe plus
        do {
            /** @var list<array{id_specific_price: int}> $rows */
            $rows = $this->db->executeS(
                'SELECT id_specific_price FROM `ps_specific_price`'
                . ' WHERE `id_customer` = 0 AND `reduction_type` = "amount"'
                . ' AND `from` = "0000-00-00 00:00:00" AND `to` = "0000-00-00 00:00:00"'
                . ' AND id_product_attribute != 0'
                . ' AND id_product_attribute NOT IN ('
                . '     SELECT id_product_attribute FROM ps_myvetshop_tarif_specifique WHERE id_product_attribute != 0'
                . ')'
                . ' LIMIT 2000'
            );
            $this->purgeRows($rows);
        } while (\count($rows) > 0);

        // Purge par id_product qui n'existe plus
        /** @var list<array{id_specific_price: int}> $rows */
        $rows = $this->db->executeS(
            'SELECT id_specific_price FROM `ps_specific_price`'
            . ' WHERE `id_customer` = 0 AND `reduction_type` = "amount"'
            . ' AND `from` = "0000-00-00 00:00:00" AND `to` = "0000-00-00 00:00:00"'
            . ' AND id_product_attribute = 0'
            . ' AND id_product NOT IN ('
            . '     SELECT id_product FROM ps_myvetshop_tarif_specifique WHERE id_product_attribute = 0'
            . ')'
            . ' LIMIT 2000'
        );
        $this->purgeRows($rows);
    }
}
