<?php

declare(strict_types=1);

namespace KupShop\KupShopBundle\Util\System;

use KupShop\I18nBundle\Translations\MenuLinksTranslation;
use KupShop\I18nBundle\Translations\SectionsTranslation;
use KupShop\KupShopBundle\Context\ContextManager;
use KupShop\KupShopBundle\Context\LanguageContext;
use Query\Operator;
use Query\Translation;
use Symfony\Contracts\Service\Attribute\Required;

class UniqueUrlUtil
{
    public const MENULINKS = 'menu_links';
    public const SECTIONS = 'sections';

    #[Required]
    public LanguageContext $languageContext;

    #[Required]
    public ContextManager $contextManager;

    protected function getTables(): array
    {
        $tables = [];

        if (findModule(\Modules::MENU)) {
            $tables[self::MENULINKS] = [
                'id' => 'ml.id',
                'url' => 'url',
                'alias' => 'ml',
                'translation' => Translation::coalesceTranslatedFields(
                    MenuLinksTranslation::class, ['url']
                ),
            ];
        }

        if (findModule(\Modules::PRODUCTS_SECTIONS)) {
            $tables[self::SECTIONS] = [
                'id' => 's.id',
                'url' => 'url',
                'alias' => 's',
                'translation' => Translation::coalesceTranslatedFields(
                    SectionsTranslation::class, ['url']
                )];
        }

        return $tables;
    }

    public function getSameUrls($type, $id, $url, $lang = null): array
    {
        $lang = $lang ?? $this->languageContext->getDefaultId();

        $tables = $this->contextManager->activateContexts([LanguageContext::class => $lang], function () {
            return $this->getTables();
        });

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

        $qbs = [];

        foreach ($tables as $table => $fields) {
            $qb = sqlQueryBuilder()->select("'{$table}' type, {$fields['id']} oid")
                ->from($table, $fields['alias'] ?? null)
                ->having("{$fields['url']} = :urlValue")
                ->setParameter('urlValue', $url)
                ->andWhere($fields['translation']);

            if ($type == $table) {
                $qb->andWhere(Operator::not(Operator::equals([$fields['id'] => $id])));
            }
            $qbs[] = $qb;
        }

        $values = sqlQueryBuilder()->select('u.*')->from(Operator::union($qbs), 'u')->execute();

        if ($values->rowCount() == 0) {
            return [];
        }

        return $values->fetchAllAssociative();
    }

    public function validateUniqueUrl($type, $id, $url, $lang = null)
    {
        if ($data = $this->getSameUrls($type, $id, $url, $lang)) {
            return "URL '{$url}' koliduje s URL u objektu {$data[0]['type']} s ID {$data[0]['oid']}";
        }

        return false;
    }
}
