<?php

declare(strict_types=1);

namespace CpCreation\VitiCore\Commerce\Catalog;

use CpCreation\VitiCore\Product\Model\Translation\ProductCategoryTranslation;
use CpCreation\VitiCore\Product\Model\Translation\ProductTranslation;
use CpCreation\VitiCore\Product\Model\Product;
use CpCreation\VitiCore\Shop\Model\ShopConfig;
use Symfony\Component\Routing\Exception\ExceptionInterface as RoutingExceptionInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;

final readonly class CatalogStorefrontUrlGenerator
{
    public function __construct(private RouterInterface $router) {}

    /**
     * @param array<string, string|int|float|bool|null> $parameters
     */
    public function route(string $name, string $locale, array $parameters = []): ?string
    {
        try {
            return $this->router->generate(
                $name,
                ['_locale' => $locale, ...$parameters],
                UrlGeneratorInterface::ABSOLUTE_URL,
            );
        } catch (RoutingExceptionInterface) {
            return null;
        }
    }

    public function product(
        Product $product,
        ProductTranslation $translation,
        ProductCategoryTranslation $categoryTranslation,
        string $locale,
        ?ShopConfig $shopConfig,
    ): ?string {
        $categorySlug = $categoryTranslation->getSlug();
        $productSlug = $translation->getSlug();
        if (!\is_string($categorySlug) || '' === mb_trim($categorySlug) || !\is_string($productSlug) || '' === mb_trim($productSlug)) {
            return null;
        }

        if (true === $shopConfig?->isEnableProductPageFront()) {
            return $this->route('shop_product', $locale, [
                'categorySlug' => $categorySlug,
                'slug' => $productSlug,
            ]);
        }

        $catalogUrl = $this->route('shop', $locale, ['slug' => $categorySlug]);

        return null === $catalogUrl ? null : $catalogUrl . '#' . rawurlencode($productSlug);
    }

    public function origin(?string $absoluteUrl): ?string
    {
        if (null === $absoluteUrl) {
            return null;
        }

        $parts = parse_url($absoluteUrl);
        if (!\is_array($parts) || !isset($parts['scheme'], $parts['host'])) {
            return null;
        }

        $origin = $parts['scheme'] . '://' . $parts['host'];
        if (isset($parts['port'])) {
            $origin .= ':' . $parts['port'];
        }

        return $origin;
    }
}
