<?php
namespace Misuzu;

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

final class TwigMisuzu extends AbstractExtension {
    private MisuzuContext $ctx;

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

    public function getFilters() {
        return [
            new TwigFilter('html_colour', 'html_colour'),
            new TwigFilter('country_name', 'get_country_name'),
            new TwigFilter('byte_symbol', 'byte_symbol'),
            new TwigFilter('parse_text', fn(string $text, int $parser): string => Parser::instance($parser)->parseText($text)),
            new TwigFilter('perms_check', 'perms_check'),
            new TwigFilter('clamp', 'clamp'),
            new TwigFilter('time_diff', [$this, 'timeDiff'], ['needs_environment' => true]),
        ];
    }

    public function getFunctions() {
        return [
            new TwigFunction('url_construct', 'url_construct'),
            new TwigFunction('url', 'url'),
            new TwigFunction('forum_may_have_children', 'forum_may_have_children'),
            new TwigFunction('forum_may_have_topics', 'forum_may_have_topics'),
            new TwigFunction('csrf_token', fn() => CSRF::token()),
            new TwigFunction('git_commit_hash', fn(bool $long = false) => GitInfo::hash($long)),
            new TwigFunction('git_tag', fn() => GitInfo::tag()),
            new TwigFunction('git_branch', fn() => GitInfo::branch()),
            new TwigFunction('startup_time', fn(float $time = MSZ_STARTUP) => microtime(true) - $time),
            new TwigFunction('sql_query_count', fn() => DB::queries() + $this->ctx->getDbQueryCount()),
            new TwigFunction('ndx_version', fn() => Environment::getIndexVersion()),
        ];
    }

    public static $units = [
        'y' => 'year',
        'm' => 'month',
        'd' => 'day',
        'h' => 'hour',
        'i' => 'minute',
        's' => 'second',
    ];

    // yoinked from https://github.com/twigphp/Twig-extensions/blob/0c7a08e6de42a3c8f6a68af9628f4c8e4e00de93/src/DateExtension.php
    public function timeDiff(TwigEnvironment $env, $date, $now = null) {
        $date = \twig_date_converter($env, $date);
        $now = \twig_date_converter($env, $now);

        $diff = $date->diff($now);

        foreach(self::$units as $attr => $unit) {
            $count = $diff->{$attr};

            if($count !== 0) {
                if($count !== 1)
                    $unit .= 's';
                return $diff->invert ? "in {$count} {$unit}" : "{$count} {$unit} ago";
            }
        }

        return 'just now';
    }
}
