<?php

/*
 * This file is part of the VITICORE2 package.
 *
 * (c) CP Creation <web@cpcreation.fr>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CpCreation\VitiCore\Bridge\Symfony\Bundle\EventListener;

use CpCreation\VitiCore\Bridge\Symfony\Bundle\Context\GroupContext;
use CpCreation\VitiCore\Product\Repository\ProductPriceCodeRepository;
use CpCreation\VitiCore\Product\Repository\ProductPriceGroupRepository;
use CpCreation\VitiCore\User\Model\User;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;

#[AsEventListener(event: KernelEvents::REQUEST, priority: 5)]
class GroupContextListener
{
    public function __construct(
        private readonly Security $security,
        private ProductPriceGroupRepository $productPriceGroupRepository,
        private readonly ProductPriceCodeRepository $productPriceCodeRepository,
    ) {}

    public function __invoke(RequestEvent $event): void
    {
        $defaultGroup = $this->productPriceGroupRepository->getGroupByDefault();
        if (!$defaultGroup) {
            throw new \LogicException('Group by default undefined');
        }

        $request = $event->getRequest();
        if ($request->attributes->getBoolean('_stateless')) {
            GroupContext::$groupId = $defaultGroup->getId()->toString();
            GroupContext::$partnerCode = null;

            return;
        }

        $session = $request->hasSession() ? $request->getSession() : null;
        GroupContext::$partnerCode = null;
        $partnerCode = $this->resolvePartnerCode($session?->get('partnerCode'), $session?->get('codePrice'));
        $groupId = $session?->get('groupPrice');

        if (null !== $partnerCode && \is_string($groupId) && '' !== $groupId) {
            $group = $this->productPriceGroupRepository->findOneBy([
                'id' => $groupId,
            ]);
            if ($group) {
                GroupContext::$groupId = $groupId;
                GroupContext::$partnerCode = $partnerCode;
                $session?->set('groupPrice', $groupId);
                $session?->set('partnerCode', $partnerCode);
                $session?->set('groupByDefault', false);

                return;
            }
        }

        $session?->remove('codePrice');
        $session?->remove('partnerCode');

        $user = $this->security->getUser();
        if ($user instanceof User && null !== $user->getGroup()) {
            GroupContext::$groupId = $user->getGroup()->getId()->toString();
            $session?->set('groupPrice', GroupContext::$groupId);
            $session?->set('groupByDefault', true);

            return;
        }

        GroupContext::$groupId = $defaultGroup->getId()->toString();
        $session?->set('groupPrice', GroupContext::$groupId);
        $session?->set('groupByDefault', true);
    }

    private function resolvePartnerCode(mixed $partnerCode, mixed $codePriceId): ?string
    {
        if (\is_string($partnerCode) && '' !== $partnerCode) {
            return $partnerCode;
        }

        if (!\is_string($codePriceId) || '' === $codePriceId) {
            return null;
        }

        $priceCode = $this->productPriceCodeRepository->find($codePriceId);

        return $priceCode?->getCode();
    }
}
