<?php

namespace KupShop\ComponentsBundle\GTM\PageViews;

use KupShop\BonusProgramBundle\Utils\BonusProvider;
use KupShop\CatalogBundle\Util\ActiveCategory;
use KupShop\ContentBundle\View\ProductView;
use KupShop\GTMBundle\Utils\PriceComputer;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Context\PriceLevelContext;
use KupShop\KupShopBundle\Context\UserContext;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Views\BaseView;
use KupShop\OrderingBundle\Cart;
use KupShop\PricelistBundle\Context\PricelistContext;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;

class CommonPageData
{
    public function __construct(
        protected Cart $cart,
        protected PriceComputer $priceComputer,
        protected RequestStack $requestStack,
        protected ActiveCategory $activeCategory,
        protected ?LanguageContext $languageContext,
        protected ?PriceLevelContext $priceLevelContext,
        protected ?PricelistContext $pricelistContext,
        protected ?BonusProvider $bonusProvider,
    ) {
    }

    public function getPageData(&$dataContainer, $component)
    {
        if (!empty($dataContainer->page)) {
            $page = &$dataContainer->page;
        } else {
            $page = new \stdClass();
        }

        $page->type = 'other';

        if ($this->languageContext) {
            $page->language = $this->languageContext->getActiveId();
        }

        $page->title = $this->getPageTitle();
        $page->path = $this->getRequest()->server->get('REQUEST_URI') ?? '';
        $page->layout = '@layout';

        $currency = $this->priceComputer->getOutputCurrency();
        $page->currency = $currency->getId();
        $page->currency_rate = $currency->getRate();

        $page->bread_crumbs = $this->getBreadcrumbs();
        $page->environment = isBeta() ? 'beta' : 'live';

        $dataContainer->page = $page;

        $dataContainer->reset_refferrer = false;
        if ($this->getRequest()->get('wpj_utm')) {
            $dataContainer->reset_refferrer = true;
        }

        $dataContainer->event = 'page_view';
    }

    public function getUserData()
    {
        $user = new \stdClass();

        $user->session_id = $this->getRequest()->getSession()->getId() ?: '';

        if ($admin = getAdminUser()) {
            $user->admin = $admin['login'];
        }

        $user->cart_id = \Cart::getCartID();

        $userObj = Contexts::get(UserContext::class)->getActive();
        if ($userObj) {
            $dbcfg = \Settings::getDefault();

            $user->type = 'loggedIn';
            $user->id = $userObj->id;

            if ($this->priceLevelContext->getActive()) {
                $user->price_level = $this->priceLevelContext->getActive()->name;
            }

            if ($userObj->getGroups()) {
                $groups = [];
                foreach ($userObj->getGroups() as $g) {
                    $groups[] = $g['name'];
                }
            }
            $user->groups = $groups ?? [];

            if ($this->pricelistContext && $this->pricelistContext->getActiveId()) {
                $user->price_list = $this->pricelistContext->getActive()?->getName();
            } else {
                $user->price_list = null;
            }

            $user->email = $userObj->email;
            $user->phone = $userObj->phone;
            $user->name = $userObj->name;
            $user->surname = $userObj->surname;

            $user->sha_email = hash('sha256', $userObj->email.($dbcfg->analytics['google_tag_manager']['sha_salt'] ?? false ?: ''));

            if (findModule(\Modules::BONUS_PROGRAM)) {
                // TODO: Potom přidat do pStatu?
                $user->bonusPoints = $this->bonusProvider->getActivePointsAmount($userObj);
            } else {
                $user->bonusPoints = null;
            }
        } else {
            // userlogin cookie uz se nesetuje, jen ro historii. Nevadi ze posilame vsude anonymous (snad)
            if ($this->getRequest()->cookies->get('userlogin')) {
                $user->type = 'loggedOut';
            } else {
                $user->type = 'anonymous';
            }
        }

        $pState = $this->cart->getPurchaseState();

        $user->cart_value = $this->priceComputer->getPrice($pState->getProductsTotalPrice());
        $user->cart_value_with_tax = $this->priceComputer->getPrice($pState->getProductsTotalPrice(), true);
        $user->cart_value_without_tax = $this->priceComputer->getPrice($pState->getProductsTotalPrice(), false);
        $user->cart_items = 0;
        foreach ($pState->getProducts() as $p) {
            $user->cart_items += $p->getPieces();
        }

        return $user;
    }

    protected function getRequest(): Request
    {
        return $this->requestStack->getMainRequest();
    }

    public function getBreadcrumbs(): ?array
    {
        $view = $this->getView();

        $breadcrumbs = [];
        if ($view->getBreadcrumbsNew()) {
            $breadcrumbs = array_values(array_map(function ($cat) {
                return [
                    'id' => $cat['ID'] ?? '',
                    'name' => $cat['text'] ?? '',
                ];
            }, $view->getBreadcrumbsNew()));

            array_shift($breadcrumbs);
            if ($view instanceof ProductView) {
                array_pop($breadcrumbs);
            }
        }

        return $breadcrumbs;
    }

    protected function getPageTitle()
    {
        $view = $this->getView();

        if ($view->getTitle()) {
            return $view->getTitle();
        }

        return null;
    }

    protected function getView(): ?BaseView
    {
        return $this->getRequest()->attributes->get('view') ?? null;
    }

    protected function getCategoriesMap($categories): array
    {
        return array_values(array_map(function ($cat) {
            if (!empty($cat) && is_int($cat)) {
                $cat = $this->activeCategory->getSectionById($cat);
            }

            return [
                'id' => $cat['ID'] ?? '',
                'name' => $cat['text'] ?? $cat['name'] ?? '',
            ];
        }, $categories));
    }
}
