<?php

declare(strict_types=1);

namespace KupShop\PreordersBundle\View;

use Doctrine\DBAL\Driver\Exception;
use KupShop\ComponentsBundle\Twig\DataProvider\OrderDataProvider;
use KupShop\ComponentsBundle\View\ComponentsViewInterface;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Context\UserContext;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\Price\TotalPrice;
use KupShop\KupShopBundle\Views\Traits\RequestTrait;
use KupShop\KupShopBundle\Views\View;
use KupShop\PreordersBundle\Dto\UserPreorderWrapper;
use KupShop\PreordersBundle\Entity\UserPreorder;
use KupShop\PreordersBundle\Service\DynamicContexts;
use KupShop\PreordersBundle\Service\PreorderUtil;
use KupShop\PreordersBundle\Twig\ComponentsTemplateOverride;
use Query\Operator as Op;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\Translation\TranslatorInterface;

class UserPreordersView extends View implements ComponentsViewInterface
{
    use RequestTrait;
    use ComponentsTemplateOverride;

    protected string $smartyFallback = 'account';
    protected string $entrypoint = 'account';
    protected $template = 'account/preorders.tpl';

    private ?int $dateId = null;

    public function __construct(
        private readonly UserContext $userContext,
        private readonly PreorderUtil $listUtil,
        private readonly DynamicContexts $contexts,
        private readonly ?OrderDataProvider $orderDataProvider,
        private readonly TranslatorInterface $translator,
    ) {
    }

    public function getTitle(): string
    {
        return translate('preorders', 'preorders');
    }

    /**
     * @throws Exception
     * @throws \Doctrine\DBAL\Exception
     */
    public function getBodyVariables(): array
    {
        $vars = parent::getBodyVariables();
        $userId = $this->userContext->getActiveId();

        $vars['useMultipleDates'] = PreorderUtil::useMultipleDates();
        $vars['hasOpenDates'] = !empty(PreorderUtil::getOpenDates($this->userContext->getActive()));

        if ($this->dateId !== null) {
            $userPreorder = new UserPreorder((int) $userId, (int) $this->dateId);

            if (findModule(\Modules::COMPONENTS)) {
                $priceValue = array_sum(array_column($userPreorder->getItems(withProductPhotos: true), 'price_total'));
                $totalPrice = new TotalPrice(
                    toDecimal($priceValue),
                    toDecimal($priceValue),
                    Contexts::get(CurrencyContext::class)->getOrDefault($userPreorder->getCustomData()->get('currency')),
                );

                $this->orderDataProvider->addOrder(new UserPreorderWrapper(
                    $userPreorder,
                    $totalPrice,
                    $this->translator,
                ));
            }

            $this->contexts->activatePreorder($userPreorder->getPreorder(), $userPreorder->getUser());
            $vars = array_merge($vars, $this->getSingleUserPreorder($userPreorder));
        } else {
            $vars['preorders'] = UserPreorder::getAllUserPreordersQuery()
                ->andWhere(Op::equals(['pi.id_user' => $userId]))
                ->orderBy('pd.date_end', 'DESC')
                ->execute()
                ->fetchAllAssociative();

            if (findModule(\Modules::COMPONENTS)) {
                foreach ($vars['preorders'] as $row) {
                    $userPreorder = new UserPreorder($userId, (int) $row['id_preorder_date']);

                    $totalPrice = new TotalPrice(
                        toDecimal($row['price_total']),
                        toDecimal($row['price_total']),
                        Contexts::get(CurrencyContext::class)->getOrDefault($userPreorder->getCustomData()->get('currency')),
                    );

                    $this->orderDataProvider->addOrder(new UserPreorderWrapper(
                        $userPreorder,
                        $totalPrice,
                        $this->translator,
                    ));
                }

                $vars['preorderDateIds'] = array_column($vars['preorders'], 'id_preorder_date');
            }
        }

        return $vars;
    }

    private function getSingleUserPreorder(UserPreorder $userPreorder): array
    {
        if (findModule(\Modules::COMPONENTS)) {
            return [
                'ID' => $userPreorder->preorderDateId,
                'messages' => $userPreorder->getMessages(),
                'custom_data' => $userPreorder->getCustomData(),
            ];
        }

        $this->contexts->activateUserPreorder($userPreorder, function () use ($userPreorder, &$products) {
            $productList = $this->listUtil->getPreorderProductList($userPreorder->getItems())
                ->fetchVariations(true, false)
                ->addResultModifiers(
                    PreorderUtil::modifierInjectFields($userPreorder->getItems(), [
                        'pieces' => 'pieces',
                        'pieces_sent' => 'pieces_sent',
                        'piece_price' => 'piece_price',
                    ]),
                );

            $products = $productList->getProducts();
        });

        return [
            'preorder' => $userPreorder->getTemplateVars(),
            'products' => $products,
            'user' => $this->userContext->getActive(),
            'messages' => $userPreorder->getMessages(),
            'custom_data' => $userPreorder->getCustomData(),
        ];
    }

    public function getResponse(?Request $request = null): Response
    {
        $dateId = $this->request->attributes->get('_route_params')['id_date'] ?? null;
        if ($dateId !== null) {
            $this->dateId = (int) $dateId;
        }

        return parent::getResponse($request);
    }

    public function getBreadcrumbs(): ?array
    {
        return getReturnNavigation(-1, 'USER', [$this->getTitle()]);
    }
}
