<?php
namespace Misuzu;

use Index\DateTime;
use Misuzu\MisuzuContext;
use Misuzu\Tools;
use Misuzu\Parsers\Parser;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;

final class MisuzuSasaeExtension extends AbstractExtension {
    private MisuzuContext $ctx;

    public function __construct(MisuzuContext $ctx) {
        $this->ctx = $ctx;
    }

    public function getFilters() {
        return [
            new TwigFilter('country_name', Tools::countryName(...)),
            new TwigFilter('parse_text', fn(string $text, int $parser): string => Parser::instance($parser)->parseText($text)),
            new TwigFilter('time_format', $this->timeFormat(...)),
        ];
    }

    public function getFunctions() {
        return [
            new TwigFunction('url', $this->ctx->getURLs()->format(...)),
            new TwigFunction('csrf_token', CSRF::token(...)),
            new TwigFunction('git_commit_hash', GitInfo::hash(...)),
            new TwigFunction('git_tag', GitInfo::tag(...)),
            new TwigFunction('git_branch', GitInfo::branch(...)),
            new TwigFunction('startup_time', fn(float $time = MSZ_STARTUP) => microtime(true) - $time),
            new TwigFunction('sql_query_count', $this->ctx->getDbQueryCount(...)),
            new TwigFunction('msz_header_menu', $this->getHeaderMenu(...)),
            new TwigFunction('msz_user_menu', $this->getUserMenu(...)),
            new TwigFunction('msz_manage_menu', $this->getManageMenu(...)),
        ];
    }

    public function timeFormat(DateTime|string|int|null $dateTime): string {
        if($dateTime === null)
            return 'never';

        if(is_string($dateTime))
            $dateTime = new DateTime($dateTime);
        elseif(is_int($dateTime))
            $dateTime = DateTime::fromUnixTimeSeconds($dateTime);

        $string = '';
        $now = DateTime::now();

        $isDiffYear = $now->getYear() !== $dateTime->getYear();
        if($isDiffYear || $now->getMonth() !== $dateTime->getMonth() || $now->getDay() !== $dateTime->getDay()) {
            $string .= $dateTime->format('M jS');
            if($isDiffYear)
                $string .= $dateTime->format(' Y');
            $string .= ', ';
        }

        $string .= $dateTime->format('G:i ');
        $string .= $dateTime->isUTC() ? 'UTC' : $dateTime->format('T');

        return $string;
    }

    public function getHeaderMenu(): array {
        $menu = [];
        $urls = $this->ctx->getURLs();
        $authInfo = $this->ctx->getAuthInfo();

        $home = [
            'title' => 'Home',
            'url' => $urls->format('index'),
            'menu' => [],
        ];

        if($authInfo->isLoggedIn())
            $home['menu'][] = [
                'title' => 'Members',
                'url' => $urls->format('user-list'),
            ];

        $home['menu'][] = [
            'title' => 'Changelog',
            'url' => $urls->format('changelog-index'),
        ];
        $home['menu'][] = [
            'title' => 'Contact',
            'url' => $urls->format('info', ['title' => 'contact']),
        ];
        $home['menu'][] = [
            'title' => 'Rules',
            'url' => $urls->format('info', ['title' => 'rules']),
        ];

        $menu[] = $home;

        $menu[] = [
            'title' => 'News',
            'url' => $urls->format('news-index'),
        ];

        $forum = [
            'title' => 'Forum',
            'url' => $urls->format('forum-index'),
            'menu' => [],
        ];

        if($authInfo->getPerms('global')->check(Perm::G_FORUM_LEADERBOARD_VIEW))
            $forum['menu'][] = [
                'title' => 'Leaderboard',
                'url' => $urls->format('forum-leaderboard'),
            ];

        $menu[] = $forum;

        $chatPath = $this->ctx->getChatURL();
        if(!empty($chatPath))
            $menu[] = [
                'title' => 'Chat',
                'url' => $chatPath,
            ];

        return $menu;
    }

    public function getUserMenu(bool $inBroomCloset, string $manageUrl = ''): array {
        $menu = [];
        $urls = $this->ctx->getURLs();
        $authInfo = $this->ctx->getAuthInfo();
        $usersCtx = $this->ctx->getUsersContext();

        if($authInfo->isLoggedIn()) {
            $userInfo = $authInfo->getUserInfo();

            $menu[] = [
                'title' => 'Profile',
                'url' => $urls->format('user-profile', ['user' => $userInfo->getId()]),
                'icon' => 'fas fa-user fa-fw',
            ];
            $menu[] = [
                'title' => 'Settings',
                'url' => $urls->format('settings-index'),
                'icon' => 'fas fa-cog fa-fw',
            ];
            $menu[] = [
                'title' => 'Search',
                'url' => $urls->format('search-index'),
                'icon' => 'fas fa-search fa-fw',
            ];

            if(!$usersCtx->hasActiveBan($userInfo) && $authInfo->getPerms('global')->check(Perm::G_IS_JANITOR)) {
                // restore behaviour where clicking this button switches between
                // site version and broom version
                if($inBroomCloset)
                    $menu[] = [
                        'title' => 'Exit Broom Closet',
                        'url' => $manageUrl === '' ? $urls->format('index') : $manageUrl,
                        'icon' => 'fas fa-door-open fa-fw',
                    ];
                else
                    $menu[] = [
                        'title' => 'Enter Broom Closet',
                        'url' => $manageUrl === '' ? $urls->format('manage-index') : $manageUrl,
                        'icon' => 'fas fa-door-closed fa-fw',
                    ];
            }

            $menu[] = [
                'title' => 'Log out',
                'url' => $urls->format('auth-logout', ['csrf' => CSRF::token()]),
                'icon' => 'fas fa-sign-out-alt fa-fw',
            ];
        } else {
            $menu[] = [
                'title' => 'Register',
                'url' => $urls->format('auth-register'),
                'icon' => 'fas fa-user-plus fa-fw',
            ];
            $menu[] = [
                'title' => 'Log in',
                'url' => $urls->format('auth-login'),
                'icon' => 'fas fa-sign-in-alt fa-fw',
            ];
        }

        return $menu;
    }

    public function getManageMenu(): array {
        $urls = $this->ctx->getURLs();
        $authInfo = $this->ctx->getAuthInfo();
        $globalPerms = $authInfo->getPerms('global');
        if(!$authInfo->isLoggedIn() || !$globalPerms->check(Perm::G_IS_JANITOR))
            return [];

        $menu = [
            'General' => [
                'Overview' => $urls->format('manage-general-overview'),
            ],
        ];

        if($globalPerms->check(Perm::G_LOGS_VIEW))
            $menu['General']['Logs'] = $urls->format('manage-general-logs');
        if($globalPerms->check(Perm::G_EMOTES_MANAGE))
            $menu['General']['Emoticons'] = $urls->format('manage-general-emoticons');
        if($globalPerms->check(Perm::G_CONFIG_MANAGE))
            $menu['General']['Settings'] = $urls->format('manage-general-settings');

        $userPerms = $authInfo->getPerms('user');
        if($userPerms->check(Perm::U_USERS_MANAGE))
            $menu['Users & Roles']['Users'] = $urls->format('manage-users');
        if($userPerms->check(Perm::U_ROLES_MANAGE))
            $menu['Users & Roles']['Roles'] = $urls->format('manage-roles');
        if($userPerms->check(Perm::U_NOTES_MANAGE))
            $menu['Users & Roles']['Notes'] = $urls->format('manage-users-notes');
        if($userPerms->check(Perm::U_WARNINGS_MANAGE))
            $menu['Users & Roles']['Warnings'] = $urls->format('manage-users-warnings');
        if($userPerms->check(Perm::U_BANS_MANAGE))
            $menu['Users & Roles']['Bans'] = $urls->format('manage-users-bans');

        if($globalPerms->check(Perm::G_NEWS_POSTS_MANAGE))
            $menu['News']['Posts'] = $urls->format('manage-news-posts');
        if($globalPerms->check(Perm::G_NEWS_CATEGORIES_MANAGE))
            $menu['News']['Categories'] = $urls->format('manage-news-categories');

        if($globalPerms->check(Perm::G_FORUM_CATEGORIES_MANAGE))
            $menu['Forum']['Permission Calculator'] = $urls->format('manage-forum-categories');
        if($globalPerms->check(Perm::G_FORUM_TOPIC_REDIRS_MANAGE))
            $menu['Forum']['Topic Redirects'] = $urls->format('manage-forum-topic-redirs');

        if($globalPerms->check(Perm::G_CL_CHANGES_MANAGE))
            $menu['Changelog']['Changes'] = $urls->format('manage-changelog-changes');
        if($globalPerms->check(Perm::G_CL_TAGS_MANAGE))
            $menu['Changelog']['Tags'] = $urls->format('manage-changelog-tags');

        return $menu;
    }
}
