<?php
namespace Misuzu;

use Index\ByteFormat;
use Index\DateTime;
use Index\Environment;
use Misuzu\MisuzuContext;
use Misuzu\Tools;
use Misuzu\Parsers\Parser;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;
use Twig\Environment as TwigEnvironment;

final class TwigMisuzu 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_construct', 'url_construct'),
            new TwigFunction('url', 'url'),
            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('ndx_version', Environment::getIndexVersion(...)),
            new TwigFunction('byte_symbol', ByteFormat::format(...)),
        ];
    }

    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;
    }
}
