<?php

namespace KupShop\CatalogBundle\Controller;

use KupShop\CatalogBundle\Util\CategoryResponse;
use KupShop\CatalogBundle\View\CategoryListView;
use KupShop\CatalogBundle\View\CategoryView;
use KupShop\CatalogBundle\View\FavoriteView;
use KupShop\CatalogBundle\View\SimpleProductListView;
use KupShop\KupShopBundle\Config;
use KupShop\KupShopBundle\Context\CountryContext;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Exception\PermanentRedirectException;
use KupShop\KupShopBundle\Routing\CampaignRoute;
use KupShop\KupShopBundle\Routing\SimpleTranslatedRoute;
use KupShop\KupShopBundle\Util\RequestUtil;
use KupShop\ShoppingListBundle\Util\ShoppingListUtil;
use KupShop\ShoppingListBundle\View\ShoppingListProductsView;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\Annotation\Route;

class CatalogController extends AbstractController
{
    /** @var CategoryResponse */
    protected $categoryResponse;

    /**
     * @param mixed $categoryResponse
     *
     * @return CatalogController
     *
     * @required
     */
    public function setCategoryResponse(CategoryResponse $categoryResponse)
    {
        $this->categoryResponse = $categoryResponse;

        return $this;
    }

    public function getCategoryResponse(Request $request, ?CategoryView $view = null)
    {
        return $this->categoryResponse->getRequestedView($request, $view);
    }

    #[Route('/_codes/{codes}/')]
    public function productListByCodes(SimpleProductListView $view, string $codes): Response
    {
        $productCodes = array_filter(explode(';', $codes));

        return $view->setFilterData(['productCodes' => $productCodes ?: ['0']])
            ->getResponse();
    }

    /**
     * @SimpleTranslatedRoute("favourite", defaults={"favourite"="1"})
     *
     * @return \Symfony\Component\HttpFoundation\Response
     *
     * @throws PermanentRedirectException
     */
    public function favouriteAction(Request $request, FavoriteView $view,
        ?ShoppingListUtil $shoppingListUtil = null, ?ShoppingListProductsView $shoppingListProductsView = null)
    {
        if (findModule(\Modules::COMPONENTS)) {
            if ($favoritesList = $shoppingListUtil->getFavoritesShoppingList()) {
                $shoppingListProductsView->setRequest($request);
                $shoppingListProductsView->setIdList($favoritesList['id']);

                return $shoppingListProductsView->getResponse();
            }

            addUserMessage('Zatím nemáte žádné oblíbené produkty.');
            $url = $request->headers->get('referer', '/');
            if (empty($url)) {
                $url = '/';
            }

            return new RedirectResponse($url);
        }

        return $this->getCategoryResponse($request, $view);
    }

    /**
     * @CampaignRoute("/{campaign}/", requirements={"campaign"="%kupshop.catalog.campaigns%"})
     *
     * @return \Symfony\Component\HttpFoundation\Response
     *
     * @throws PermanentRedirectException
     */
    public function campaignAction(Request $request)
    {
        return $this->getCategoryResponse($request);
    }

    /**
     * @Route("/{url_producer}_v{id_producer}/{parent_sections}{url_section}_k{id_section}/", requirements={"url_producer"="[-[:alnum:]]+", "id_producer"="\d+", "url_section"="[-[:alnum:]]+", "id_section"="\d+", "parent_sections"="([-[:alnum:]]+_k\d+/)*"})
     *
     * @return \Symfony\Component\HttpFoundation\Response
     *
     * @throws PermanentRedirectException
     */
    public function producerSectionAction(Request $request)
    {
        return $this->getCategoryResponse($request);
    }

    /**
     * @Route("/{url_producer}_v{id_producer}/", requirements={"url_producer"="[-[:alnum:]]+", "id_producer"="\d+"})
     *
     * @CampaignRoute("/{url_producer}_v{id_producer}/{campaign}/", requirements={"url_producer"="[-[:alnum:]]+", "id_producer"="\d+", "campaign"="%kupshop.catalog.campaigns%"})
     *
     * @return \Symfony\Component\HttpFoundation\Response
     *
     * @throws PermanentRedirectException
     *
     * @internal param $id_producer
     */
    public function producerAction(Request $request)
    {
        return $this->getCategoryResponse($request);
    }

    /**
     * @Route("/{url_parameter}_pv{id_parameter_value}/{parent_sections}{url_section}_k{id_section}/", requirements={"url_parameter"="[-[:alnum:]]+", "id_parameter_value"="\d+", "url_section"="[-[:alnum:]]+", "id_section"="\d+", "parent_sections"="([-[:alnum:]]+_k\d+/)*"})
     *
     * @CampaignRoute("/{url_parameter}_pv{id_parameter_value}/{campaign}/", requirements={"url_parameter"="[-[:alnum:]]+", "id_parameter_value"="\d+", "campaign"="%kupshop.catalog.campaigns%"})
     *
     * @return \Symfony\Component\HttpFoundation\Response
     *
     * @throws PermanentRedirectException
     *
     * @internal param $id_parameter_value
     */
    public function parameterValueAction(Request $request)
    {
        return $this->getCategoryResponse($request);
    }

    /**
     * @Route("/{parent_sections}{url_section}_k{id_section}/", requirements={"url_section"="[-[:alnum:]]+", "id_section"="\d+", "parent_sections"="([-[:alnum:]]+_k\d+/)*"})
     *
     * @CampaignRoute("/{parent_sections}{url_section}_k{id_section}/{campaign}/", requirements={"url_section"="[-[:alnum:]]+", "id_section"="\d+", "parent_sections"="([-[:alnum:]]+_k\d+/)*", "campaign"="%kupshop.catalog.campaigns%"})
     *
     * @throws PermanentRedirectException
     */
    public function sectionAction(Request $request)
    {
        return $this->getCategoryResponse($request);
    }

    /**
     * @SimpleTranslatedRoute("category", module="products_sections")
     *
     * @return \Symfony\Component\HttpFoundation\Response
     *
     * @throws PermanentRedirectException
     */
    public function categoryAction(Request $request)
    {
        return $this->getCategoryResponse($request);
    }

    /**
     * @Route("/kategorie/")
     */
    public function categoryListAction(Request $request, CategoryListView $view)
    {
        return $view->getResponse($request);
    }

    /**
     * @Route("/mena/{currency}{url}", requirements={"currency"="[a-zA-Z]{3}", "url"=".*"})
     */
    public function changeCurrencyAction(Request $request, $currency, CurrencyContext $currencyContext, RequestUtil $requestUtil, \Cart $cart, $url = '')
    {
        $cfg = Config::get();

        if (findModule(\Modules::CURRENCIES)) {
            $currency = strtoupper($currency);

            if ($currency && !empty($cfg['Currencies'][$currency])) {
                $currencyContext->remember($currency);
            }

            $cart->invalidatePurchaseState();
        }

        if (!$url || $url == '/') {
            $url = $request->headers->get('referer', '/');
            if (empty($url)) {
                $url = '/';
            }
        }

        if (!$requestUtil->isSafeRedirectUrl($url)) {
            $url = '/';
        }

        if ($queryString = $request->getQueryString()) {
            $url .= '?'.$queryString;
        }

        if (findModule(\Modules::JS_SHOP)) { // for UserEventsCookieListener to force js-shop reload
            $request->getSession()->set('changeCurrency', true);
        }

        return new RedirectResponse($url);
    }

    /**
     * @Route("/zeme/{country}{url}", requirements={"country"="[a-zA-Z]{2}", "url"="(/.+|)"})
     * @Route("/zeme/", defaults={"country":null, "url":null})
     */
    public function changeCountryAction(Request $request, CountryContext $countryContext, \Cart $cart, RequestUtil $requestUtil, $country, $url = '')
    {
        $country = strtoupper($country);

        if (!$country) {
            $country = $request->query->get('country');
        }

        if ($country) {
            $countryContext->remember($country);
            $countryContext->activate($country);
            $cart->invalidatePurchaseState();
        }

        if (findModule(\Modules::JS_SHOP)) { // for UserEventsCookieListener to force js-shop reload
            $request->getSession()->set('changeCountry', true);
        }

        if (!$url) {
            $url = $request->query->get('url');
        }

        if (!$url || $url == '/') {
            $url = $request->headers->get('referer', '/');
            if (empty($url)) {
                $url = '/';
            }
        }

        if (!$requestUtil->isSafeRedirectUrl($url)) {
            $url = '/';
        }

        return new RedirectResponse($url);
    }

    /**
     * @Route("/jazyk/{language}{url}", requirements={"language"="[a-zA-Z]{2}", "url"=".*"})
     * @Route("/jazyk/", defaults={"country":null, "url":null})
     */
    public function changeLanguageAction(Request $request, LanguageContext $languageContext, RequestUtil $requestUtil, $language = null, $url = '')
    {
        if (!$language) {
            $language = $request->query->get('language');
        }

        $language = strtolower($language);

        if ($language) {
            $languageContext->remember($language);
        }

        if (!$url) {
            $url = $request->query->get('url');
        }

        if (!$url || $url == '/') {
            $url = $request->headers->get('referer', '/');
            if (empty($url)) {
                $url = '/';
            }
        }

        if (!$requestUtil->isSafeRedirectUrl($url)) {
            $url = '/';
        }

        return new RedirectResponse($url);
    }

    /**
     * @Route("/dph/{dph}", requirements={"dph"="(0|1)", "url"=".*"})
     */
    public function changeVatAction(Request $request, string $dph, Session $session)
    {
        $url = $request->headers->get('referer', '/');
        if (empty($url)) {
            $url = '/';
        }

        $response = new RedirectResponse($url);
        $response->headers->setCookie(new Cookie('prices_vat', $dph ? 'withVat' : 'withoutVat'));

        return $response;
    }
}
