<?php
declare(strict_types=1);

namespace Autogedal\Reduceri\Controller;

use Autogedal\Reduceri\Controller\Category\View;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
use Magento\Framework\App\ActionFactory;
use Magento\Framework\App\ActionInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\App\RouterInterface;
use Magento\Framework\Url;
use Magento\Store\Model\StoreManagerInterface;

class Router implements RouterInterface
{
    public function __construct(
        private readonly ActionFactory        $actionFactory,
        private readonly CollectionFactory    $categoryCollectionFactory,
        private readonly StoreManagerInterface $storeManager,
    ) {}

    public function match(RequestInterface $request): ?ActionInterface
    {
        $pathInfo = trim($request->getPathInfo(), '/');
        $parts    = explode('/', $pathInfo);

        if ($parts[0] !== 'reduceri' || count($parts) < 2 || empty($parts[1])) {
            return null;
        }

        $urlKey     = $parts[1];
        $storeId    = (int) $this->storeManager->getStore()->getId();
        $categoryId = $this->resolveCategoryIdByUrlKey($urlKey, $storeId);
        if (!$categoryId) {
            return null;
        }

        // Set request params so the controller and layout handle generation work correctly
        $request->setRouteName('reduceri')
                ->setModuleName('reduceri')
                ->setControllerName('category')
                ->setActionName('view')
                ->setParam('id', (string) $categoryId);

        $request->setAlias(Url::REWRITE_REQUEST_PATH_ALIAS, ltrim($request->getOriginalPathInfo(), '/'));

        return $this->actionFactory->create(View::class);
    }

    private function resolveCategoryIdByUrlKey(string $urlKey, int $storeId): int
    {
        $collection = $this->categoryCollectionFactory->create()
            ->setStoreId($storeId)
            ->addAttributeToFilter('url_key', $urlKey)
            ->addAttributeToFilter('is_active', 1)
            ->addAttributeToFilter('level', ['gteq' => 2])
            ->setPageSize(1);

        return (int) $collection->getFirstItem()->getId();
    }
}
