<?php
declare(strict_types=1);

namespace Celena\Plugin\Handbook\Support;

/**
 * Дерево навигации документации. Источник — content/nav.php (PHP-массив).
 *
 * Формат nav.php: список групп верхнего уровня (= разделы в URL):
 *   [
 *     ['key'=>'panel', 'icon'=>'i-layout', 'title'=>['ru'=>..,'uk'=>..,'en'=>..],
 *      'pages'=>[ ['page'=>'intro','file'=>'panel/intro.md','title'=>['ru'=>..,...]], ... ]],
 *     ['key'=>'code',  ...],
 *   ]
 *
 * Заголовки берутся из nav.php по языкам (а не из H1 файла) → меню стабильно,
 * даже если перевод .md ещё не написан.
 */
final class Navigation
{
    /** @var list<array<string,mixed>>|null */
    private ?array $groups = null;

    public function __construct(private readonly string $navFile)
    {
    }

    /** @return list<array<string,mixed>> */
    private function data(): array
    {
        if ($this->groups === null) {
            $data = is_file($this->navFile) ? require $this->navFile : [];
            $this->groups = is_array($data) ? array_values($data) : [];
        }
        return $this->groups;
    }

    /** Локализованный заголовок из карты title с fallback ru → en → first → ''. */
    private function pick(array $titleMap, string $lang): string
    {
        if (isset($titleMap[$lang]) && $titleMap[$lang] !== '') {
            return (string) $titleMap[$lang];
        }
        foreach (['ru', 'en'] as $fb) {
            if (isset($titleMap[$fb]) && $titleMap[$fb] !== '') {
                return (string) $titleMap[$fb];
            }
        }
        $first = reset($titleMap);
        return $first === false ? '' : (string) $first;
    }

    /**
     * Дерево для бокового меню: группы → пункты с флагом активности.
     *
     * @return list<array{key:string,icon:string,title:string,items:list<array{url:string,title:string,is_active:string}>}>
     */
    public function sidebar(string $lang, string $activeSection, string $activePage): array
    {
        $out = [];
        foreach ($this->data() as $group) {
            $key = (string) ($group['key'] ?? '');
            $items = [];
            foreach ((array) ($group['pages'] ?? []) as $p) {
                $page = (string) ($p['page'] ?? '');
                $active = ($key === $activeSection && $page === $activePage) ? '1' : '';
                $items[] = [
                    'url'       => '/docs/' . $key . '/' . $page,
                    'title'     => $this->pick((array) ($p['title'] ?? []), $lang),
                    'is_active' => $active,
                ];
            }
            $out[] = [
                'key'   => $key,
                'icon'  => (string) ($group['icon'] ?? 'i-layout'),
                'title' => $this->pick((array) ($group['title'] ?? []), $lang),
                'items' => $items,
            ];
        }
        return $out;
    }

    /**
     * Карточки для главной /docs: группа + её пункты.
     *
     * @return list<array{key:string,icon:string,title:string,items:list<array{url:string,title:string}>}>
     */
    public function cards(string $lang): array
    {
        $out = [];
        foreach ($this->data() as $group) {
            $key = (string) ($group['key'] ?? '');
            $items = [];
            foreach ((array) ($group['pages'] ?? []) as $p) {
                $items[] = [
                    'url'   => '/docs/' . $key . '/' . (string) ($p['page'] ?? ''),
                    'title' => $this->pick((array) ($p['title'] ?? []), $lang),
                ];
            }
            $out[] = [
                'key'   => $key,
                'icon'  => (string) ($group['icon'] ?? 'i-layout'),
                'title' => $this->pick((array) ($group['title'] ?? []), $lang),
                'items' => $items,
            ];
        }
        return $out;
    }

    /** @return array{section:string,page:string,file:string,title:array<string,string>}|null */
    public function find(string $section, string $page): ?array
    {
        foreach ($this->data() as $group) {
            if ((string) ($group['key'] ?? '') !== $section) {
                continue;
            }
            foreach ((array) ($group['pages'] ?? []) as $p) {
                if ((string) ($p['page'] ?? '') === $page) {
                    return [
                        'section' => $section,
                        'page'    => $page,
                        'file'    => (string) ($p['file'] ?? ''),
                        'title'   => (array) ($p['title'] ?? []),
                    ];
                }
            }
        }
        return null;
    }

    /** Первая страница раздела (для /docs/{section} без page). */
    public function firstPage(string $section): ?string
    {
        foreach ($this->data() as $group) {
            if ((string) ($group['key'] ?? '') === $section) {
                $pages = (array) ($group['pages'] ?? []);
                $first = reset($pages);
                return $first === false ? null : (string) ($first['page'] ?? '');
            }
        }
        return null;
    }

    public function sectionExists(string $section): bool
    {
        foreach ($this->data() as $group) {
            if ((string) ($group['key'] ?? '') === $section) {
                return true;
            }
        }
        return false;
    }

    public function pageTitle(array $entry, string $lang): string
    {
        return $this->pick((array) ($entry['title'] ?? []), $lang);
    }

    public function groupTitle(string $section, string $lang): string
    {
        foreach ($this->data() as $group) {
            if ((string) ($group['key'] ?? '') === $section) {
                return $this->pick((array) ($group['title'] ?? []), $lang);
            }
        }
        return '';
    }

    /**
     * Хлебные крошки: Docs → Группа → Страница.
     *
     * @return list<array{title:string,url:string}>
     */
    public function breadcrumbs(string $lang, string $section, string $page, string $docsTitle): array
    {
        $entry = $this->find($section, $page);
        return [
            ['title' => $docsTitle, 'url' => '/docs/'],
            ['title' => $this->groupTitle($section, $lang), 'url' => '/docs/' . $section],
            ['title' => $entry !== null ? $this->pageTitle($entry, $lang) : $page, 'url' => ''],
        ];
    }
}
