<?php

namespace Picea\Extension;

use Picea\Compiler\Context;
use Picea\Event\Builder\ClassTemplateRenderSectionDone;

class LanguageExtension implements Extension, FunctionExtension {

    public array $tokens = [ "lang",  "_", "language" ];

    public string $currentLanguage = "";

    protected LanguageHandler $languageHandler;

    public function __construct(LanguageHandler $handler) {
        $this->languageHandler = $handler;
    }

    public function exportFunctions(): array
    {
        return [
            '_' => 'relativeLang',
            'lang' => 'absoluteLang',
        ];
    }

    public function parse(\Picea\Compiler\Context &$context, ?string $arguments, string $token, array $options = []) : string
    {
        switch(explode('.', $token)[0]) {
            case "language":
                $cls = $this::class;

                return <<<PHP
                    <?php 
                        (function(\\$cls \$ext) use (\$___class__template, \$__event) {
                            #\$extends = \$___class__template->getParam('extends');
                        
                            if ( \$___class__template->depth === 1 || \$___class__template->sectionStack ) {
                                \$ext->currentLanguage = $arguments; 
                                
                                # @TODO Make sure this event is only registered when we output() a template, if we are in a section, we must attach it a view/section/block output event instead ! 
                                \$__event->eventRegister(\\$cls::outputDoneEvent(\$ext));
                            }
                       })(\$picea->compiler->getExtensionFromToken('$token'));
                    ?>
                PHP;

            case "lang":
                if ( in_array('raw', $options) ) {
                    return "<?php echo \$picea->compiler->getExtensionFromToken('$token')->absoluteLang($arguments) ?>";
                }

                return "<?php echo htmlspecialchars(\$picea->compiler->getExtensionFromToken('$token')->absoluteLang($arguments), \ENT_QUOTES, ini_get('default_charset'), true) ?>";

            case "_":
                if ( in_array('raw', $options) ) {
                    return "<?php echo \$picea->compiler->getExtensionFromToken('$token')->relativeLang($arguments) ?>";
                }

                return "<?php echo htmlspecialchars(\$picea->compiler->getExtensionFromToken('$token')->relativeLang($arguments), \ENT_QUOTES, ini_get('default_charset'), true) ?>";
        }

        return "";
    }

    public function register(Context $context) : void
    {
    }

    public function relativeLang(string $key, array $variables = []) #: array|string
    {
        return $this->languageHandler->languageFromKey("{$this->currentLanguage}.{$key}", $variables);
    }

    public function absoluteLang(string $key, array $variables = []) #: array|string
    {
        return $this->languageHandler->languageFromKey($key, $variables);
    }

    public static function outputDoneEvent(LanguageExtension $languageExtension) : ClassTemplateRenderSectionDone
    {
        return new class($languageExtension) implements ClassTemplateRenderSectionDone {

            protected string $current;

            public function __construct(protected LanguageExtension $languageExtension) {
                 $this->current = $this->languageExtension->currentLanguage;
            }

            public function execute(string $name) : mixed
            {
                return $this->current ? $this->languageExtension->currentLanguage = $this->current : null;
            }
        };
    }
}