<?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\Twig\Components\Shop;

use CpCreation\VitiCore\Bridge\Symfony\Bundle\Context\ShopCountryContext;
use CpCreation\VitiCore\Product\Model\Product;
use CpCreation\VitiCore\Product\Model\ProductCategory;
use CpCreation\VitiCore\Product\Model\ProductCollection;
use CpCreation\VitiCore\Shop\Model\ShopConfig;
use CpCreation\VitiCore\Shop\ShopCatalogResolver;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;

#[AsTwigComponent('shop:Catalog', template: '@components/shop/Catalog.html.twig')]
final class Catalog
{
    public string $source = ShopCatalogResolver::SOURCE_SHOP;
    public ?string $categorySlug = null;
    public ?string $collection = null;
    public bool $showTabs = true;
    public string $route = 'shop';
    public string $routeParam = 'slug';
    public string $frame = 'shop-content';
    public ?string $template = null;

    private ?array $catalog = null;

    public function __construct(
        private readonly ShopCatalogResolver $catalogResolver,
        private readonly RequestStack $requestStack,
        private readonly ShopCountryContext $shopCountryContext,
    ) {}

    public function isShopBlocked(): bool
    {
        return ShopCatalogResolver::SOURCE_SHOP === $this->source && $this->shopCountryContext->isBlocked();
    }

    public function getBlockedCountryCode(): ?string
    {
        return $this->shopCountryContext->getCountryCode();
    }

    public function getConfig(): ShopConfig
    {
        return $this->getCatalog()['config'];
    }

    /**
     * @return ProductCategory[]
     */
    public function getCategories(): array
    {
        return $this->getCatalog()['categories'];
    }

    public function getCategory(): ?ProductCategory
    {
        return $this->getCatalog()['category'];
    }

    public function getProductCollection(): ?ProductCollection
    {
        return $this->getCatalog()['collection'];
    }

    public function isShowCategoryMenu(): bool
    {
        return $this->getCatalog()['showCategoryMenu'];
    }

    public function isCurrentCategoryVisible(): bool
    {
        return $this->getCatalog()['isCurrentCategoryVisible'];
    }

    /**
     * @return Product[]
     */
    public function getShopProducts(): array
    {
        return $this->getCatalog()['shopProducts'];
    }

    /**
     * @return array<int, array{category: ProductCategory, products: Product[]}>
     */
    public function getShopProductGroups(): array
    {
        return $this->getCatalog()['shopProductGroups'];
    }

    /**
     * @return Product[]
     */
    public function getAllShopProducts(): array
    {
        return $this->getCatalog()['allShopProducts'];
    }

    /**
     * @return Product[]
     */
    public function getMobileBarProducts(): array
    {
        return $this->getCatalog()['mobileBarProducts'];
    }

    public function shouldDisplayTabs(): bool
    {
        return $this->showTabs && $this->isShowCategoryMenu() && \count($this->getCategories()) >= 2;
    }

    public function getActiveSlug(): string
    {
        $requestSlug = $this->requestStack->getCurrentRequest()?->attributes->get('slug');
        if (\is_string($requestSlug) && '' !== $requestSlug) {
            return $requestSlug;
        }

        $category = $this->getCategory();
        if ($category instanceof ProductCategory && null !== $category->getSlug()) {
            return $category->getSlug();
        }

        $firstCategory = $this->getCategories()[0] ?? null;

        return $firstCategory instanceof ProductCategory ? (string) $firstCategory->getSlug() : '';
    }

    public function getMobileBarLabel(): string
    {
        $category = $this->getCategory();

        return $this->isShowCategoryMenu() && $category instanceof ProductCategory
            ? (string) $category->getName()
            : '';
    }

    public function isCollectionSource(): bool
    {
        return ShopCatalogResolver::SOURCE_COLLECTION === $this->getCatalog()['source'];
    }

    private function getCatalog(): array
    {
        if (null !== $this->catalog) {
            return $this->catalog;
        }

        return $this->catalog = $this->catalogResolver->resolveCatalog(
            $this->source,
            $this->resolveCategorySlug(),
            $this->collection,
        );
    }

    private function resolveCategorySlug(): ?string
    {
        if (null !== $this->categorySlug && '' !== mb_trim($this->categorySlug)) {
            return $this->categorySlug;
        }

        $slug = $this->requestStack->getCurrentRequest()?->attributes->get('slug');

        return \is_string($slug) && '' !== $slug ? $slug : null;
    }
}
