<?php

namespace KupShop\GraphQLBundle\ApiPublic\Util;

use KupShop\CatalogBundle\Section\SectionTree;
use KupShop\ContentBundle\Util\MenuLinksPage;
use KupShop\GraphQLBundle\ApiPublic\Types\Content\Page;
use KupShop\GraphQLBundle\ApiPublic\Types\Menu\MenuItem;
use KupShop\GraphQLBundle\ApiShared\ApiUtil;
use KupShop\RestrictionsBundle\Utils\RestrictionUtil;
use Query\Operator;
use TheCodingMachine\GraphQLite\Exceptions\GraphQLException;

class MenuUtil
{
    public function __construct(
        private readonly SectionTree $sectionTree,
        private readonly MenuLinksPage $menuLinksPage,
        private readonly ?RestrictionUtil $restrictionUtil = null,
    ) {
    }

    public function getPages(?string $label = null, ?int $parentId = null): array
    {
        if ($label) {
            $parentId = sqlQueryBuilder()
                ->select('id')
                ->from('menu_links')
                ->where(Operator::equals(['code' => $label]))
                ->execute()->fetchOne();

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

        $pages = array_filter($this->menuLinksPage->getPages($parentId), function ($page) {
            if ($page->getFigure() === 'N' && !getAdminUser()) {
                return false;
            }

            return true;
        });

        return ApiUtil::wrapItems($pages, Page::class);
    }

    public function getMenu(?int $id = null, ?bool $onlyVisible = true): array
    {
        $filterSpec = function (iterable $sections) use ($onlyVisible) {
            return $this->filterSections($sections, $onlyVisible);
        };

        if ($id) {
            if (!($section = $this->sectionTree->getSectionById($id))) {
                throw new GraphQLException('Section not found', 404);
            }

            return [new MenuItem($section, $filterSpec)];
        }

        $menu = [];
        foreach ($this->filterSections($this->sectionTree->getTree(), $onlyVisible) as $section) {
            $menu[] = new MenuItem($section, $filterSpec);
        }

        return $menu;
    }

    private function filterSections(iterable $sections, ?bool $onlyVisible = true): iterable
    {
        $result = [];

        /** @var \KupShop\CatalogBundle\Entity\Section $section */
        foreach ($sections as $section) {
            if (!$onlyVisible || $section->isVisible()) {
                $result[] = $section;
            }
        }

        if (findModule(\Modules::RESTRICTIONS)) {
            $result = $this->restrictionUtil->restrictSections($result);
        }

        return $result;
    }
}
