<?php

namespace Myvetshop\Module\Clinique\Prestashop\Hook\ActionObjectCartUpdateBefore;

use Myvetshop\Module\Clinique\Adapter\PrestashopLoggerAdapter;
use Myvetshop\Module\Clinique\Adapter\Recommandation\RecommandationCartRuleRepository;
use PrestaShop\PrestaShop\Adapter\LegacyContext;

class CrokitAutoCartRuleListener implements ActionObjectCartUpdateBeforeInterface
{
    private LegacyContext $legacyContext;

    private RecommandationCartRuleRepository $recommandationCartRuleRepository;

    private PrestashopLoggerAdapter $logger;

    /**
     * @param list<array{obj: \CartRule}> $cartRules
     */
    protected function cartRulesContains(array $cartRules, \CartRule $cartRule): bool
    {
        foreach ($cartRules as $cr) {
            if ((int) $cr['obj']->id === (int) $cartRule->id) {
                return true;
            }
        }

        return false;
    }

    public function __construct(
        LegacyContext $legacyContext,
        PrestashopLoggerAdapter $logger,
        RecommandationCartRuleRepository $recommandationCartRuleRepository
    ) {
        $this->legacyContext = $legacyContext;
        $this->logger = $logger;
        $this->recommandationCartRuleRepository = $recommandationCartRuleRepository;
    }

    public function actionObjectCartUpdateBefore(\Cart $cart): void
    {
        $context = $this->legacyContext->getContext();
        if (!$context || !$context->customer->isLogged() || !\Validate::isLoadedObject($context->cart)) {
            return;
        }

        try {
            /** @var list<int> $productIds */
            $productIds = \array_map(
                fn ($p) => (int) $p['id_product'],
                $cart->getProducts()
            );
        } catch (\Exception $e) {
            $this->logger->error(
                $e->getMessage(),
                [
                    'trace' => $e->getTrace(),
                ]
            );

            return;
        }

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

        $cartRule = $this->recommandationCartRuleRepository->getCartRuleForCustomerAndProducts(
            $context->customer,
            $productIds
        );

        if (!$cartRule) {
            return;
        }

        /** @var list<array{obj: \CartRule}> $cartRules */
        $cartRules = $context->cart->getCartRules(\CartRule::FILTER_ACTION_ALL, false);

        if (!$this->cartRulesContains($cartRules, $cartRule)) {
            // Ajout automatique de la réduction Crokit
            $context->cart->addCartRule((int) $cartRule->id);
        }
    }
}
