<?php

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

use Myvetshop\Module\Clinique\Adapter\Recommandation\RecommandationCartRuleRepository;
use Myvetshop\Module\Clinique\Adapter\Recommandation\RecommandationProductCombinationSelector;
use Myvetshop\Module\Clinique\Entity\Recommandation;
use Myvetshop\Module\Clinique\Entity\RecommandationProduct;
use Myvetshop\Module\Clinique\Prestashop\Product\ProductPriceComputer;
use Myvetshop\Module\Clinique\Repository\RecommandationRepository;
use PrestaShop\PrestaShop\Adapter\LegacyContext;

class CrokitCartRuleFooterBandListener implements DisplayFooterProductListenerInterface
{
    private LegacyContext $legacyContext;

    private ProductPriceComputer $productPriceComputer;

    private RecommandationCartRuleRepository $recommandationCartRuleRepository;

    private RecommandationProductCombinationSelector $recommandationProductCombinationSelector;

    private RecommandationRepository $recommandationRepository;

    protected function getGroup(int $idGroup): \Group
    {
        return new \Group($idGroup);
    }

    protected function getToken(): string
    {
        return \Tools::getToken(false);
    }

    public function __construct(
        LegacyContext $legacyContext,
        ProductPriceComputer $productPriceComputer,
        RecommandationCartRuleRepository $recommandationCartRuleRepository,
        RecommandationProductCombinationSelector $recommandationProductCombinationSelector,
        RecommandationRepository $recommandationRepository
    ) {
        $this->legacyContext = $legacyContext;
        $this->productPriceComputer = $productPriceComputer;
        $this->recommandationCartRuleRepository = $recommandationCartRuleRepository;
        $this->recommandationProductCombinationSelector = $recommandationProductCombinationSelector;
        $this->recommandationRepository = $recommandationRepository;
    }

    public function displayFooterProduct(\Category $category, \Product $product): string
    {
        $context = $this->legacyContext->getContext();
        if (!$context || !$context->customer->isLogged()) {
            return '';
        }

        $cartRule = $this->recommandationCartRuleRepository->getCartRuleForCustomerAndProduct(
            $context->customer,
            $product
        );

        if (!$cartRule) {
            return '';
        }

        /** @var Recommandation|null $recommandation */
        $recommandation = $this->recommandationRepository->findOneBy(['codeReco' => $cartRule->code]);
        /** @var RecommandationProduct|false $recommandationProduct */
        $recommandationProduct = false;

        if ($recommandation) {
            $recommandationProduct = $recommandation->getProduits()
                ->filter(fn (RecommandationProduct $rc) => $rc->idProduct === (int) $product->id)
                ->first();
        }

        if ($recommandationProduct) {
            // Détermine quelle variante du produit peut être commandée
            $combination = $this->recommandationProductCombinationSelector->findBestCombination(
                $recommandationProduct,
                $product,
            );
        } else {
            $combination = null;
        }

        if ($combination) {
            // Calcul du prix estimé
            $combinationPrice = $this->productPriceComputer->getPrivilegePrice(
                $combination,
                $this->getGroup((int) $context->customer->id_default_group),
            );
            $attributesNames = $combination->getAttributesName($context->language->id);
            if (!\is_array($attributesNames)) {
                $attributesNames = [];
            }

            $combinationVariation = \implode(
                ', ',
                \array_map(
                    function (array $atr): string { return $atr['name']; },
                    $attributesNames
                ),
            );

            if ($cartRule->reduction_percent) {
                $combinationPrice *= (100 - $cartRule->reduction_percent) / 100;
                $combinationPrice = \round($combinationPrice, 2);
            }
        } else {
            $combinationPrice = null;
            $combinationVariation = null;
        }

        return $context->smarty->fetch(
            'module:myvetshopclinique/views/templates/front/product/crokit_cart_rule.tpl',
            [
                'cartRule' => $cartRule,
                'combination' => $combination,
                'combinationPrice' => $combinationPrice,
                'combinationVariation' => $combinationVariation,
                'token' => $this->getToken(),
            ]
        );
    }
}
