<?php

namespace Zab\ZabSite\ViewHelpers;

use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;

class SearchFiltersViewHelper extends AbstractViewHelper
{
    protected $escapeOutput = false;

    public function initializeArguments(): void
    {
        $this->registerArgument('sword', 'string', 'Search word', true);
        $this->registerArgument('targetPid', 'int', 'Target page UID for search', true);
        $this->registerArgument('as', 'string', 'Variable name for the filters', true);
    }

    public function render(): string
    {
        $sword = (string)($this->arguments['sword'] ?? '');
        $targetPid = (int)$this->arguments['targetPid'];
        $as = $this->arguments['as'];

        $request = $this->renderingContext->getRequest();

        if ($targetPid === 0) {
            $targetPid = $request->getAttribute('routing')?->getPageId() ?? 0;
        }

        $searchParams = $request->getQueryParams()['tx_indexedsearch_pi2']['search'] ?? [];
        $currentFilterPages = (string)($searchParams['filterPages'] ?? '');

        $filters = $this->getSearchFilters($sword, $targetPid, $request, $currentFilterPages);

        $this->renderingContext->getVariableProvider()->add($as, $filters);
        $content = $this->renderChildren();
        $this->renderingContext->getVariableProvider()->remove($as);

        return (string)$content;
    }

    protected function getSearchFilters(string $sword, int $targetPid, object $request, string $currentFilterPages): array
    {
        $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);

        // Find the parent "Search Filters" category
        $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_category');
        $parentCategory = $queryBuilder
            ->select('uid')
            ->from('sys_category')
            ->where(
                $queryBuilder->expr()->eq('title', $queryBuilder->createNamedParameter('Search Filters'))
            )
            ->executeQuery()
            ->fetchAssociative();

        if (!$parentCategory) {
            return [];
        }

        // Get subcategories
        $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_category');
        $subcategories = $queryBuilder
            ->select('uid', 'title', 'color')
            ->from('sys_category')
            ->where(
                $queryBuilder->expr()->eq('parent', $queryBuilder->createNamedParameter($parentCategory['uid'], Connection::PARAM_INT))
            )
            ->orderBy('sorting')
            ->executeQuery()
            ->fetchAllAssociative();

        if (empty($subcategories)) {
            return [];
        }

        $filters = [];
        foreach ($subcategories as $category) {
            // Get pages assigned to this category
            $queryBuilder = $connectionPool->getQueryBuilderForTable('sys_category_record_mm');
            $pages = $queryBuilder
                ->select('uid_foreign')
                ->from('sys_category_record_mm')
                ->where(
                    $queryBuilder->expr()->eq('uid_local', $queryBuilder->createNamedParameter($category['uid'], Connection::PARAM_INT)),
                    $queryBuilder->expr()->eq('tablenames', $queryBuilder->createNamedParameter('pages')),
                    $queryBuilder->expr()->eq('fieldname', $queryBuilder->createNamedParameter('categories'))
                )
                ->executeQuery()
                ->fetchAllAssociative();

            if (empty($pages)) {
                continue;
            }

            $pageUids = array_column($pages, 'uid_foreign');
            $filterPages = implode(',', $pageUids);

            $site = $request->getAttribute('site');
            $href = (string)$site->getRouter()->generateUri(
                (string)$targetPid,
                [
                    'tx_indexedsearch_pi2' => [
                        'action' => 'search',
                        'search' => [
                            'sword' => $sword,
                            'filterPages' => $filterPages,
                        ],
                    ],
                ]
            );

            $filters[] = [
                'title' => $category['title'],
                'color' => $category['color'] ?? '',
                'filterPages' => $filterPages,
                'isActive' => ($filterPages === $currentFilterPages),
                'href' => $href,
            ];
        }

        return $filters;
    }
}
