<?php
declare(strict_types=1);

namespace App;

class I18n
{
    private static array $dicts = [];
    private static string $current = 'en';
    private static string $fallback = 'en';

    public static function boot(): void
    {
        $supported = (array) (config('locale.supported') ?? ['en']);
        $session = $_SESSION['locale'] ?? null;
        $default = (string) (config('locale.default') ?? 'en');

        if ($session && in_array($session, $supported, true)) {
            self::$current = $session;
        } else {
            // try Accept-Language
            $accept = strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '');
            if (str_contains($accept, 'es')) {
                self::$current = in_array('es', $supported, true) ? 'es' : $default;
            } else {
                self::$current = $default;
            }
        }
        self::$fallback = $default;
    }

    public static function set(string $code): void
    {
        $supported = (array) (config('locale.supported') ?? ['en']);
        if (in_array($code, $supported, true)) {
            self::$current = $code;
            $_SESSION['locale'] = $code;
        }
    }

    public static function current(): string
    {
        return self::$current ?: 'en';
    }

    public static function t(string $key, array $params = []): string
    {
        $dict = self::load(self::$current);
        $value = self::resolve($dict, $key);
        if ($value === null) {
            $value = self::resolve(self::load(self::$fallback), $key);
        }
        if ($value === null) return $key;
        foreach ($params as $k => $v) {
            $value = str_replace(':' . $k, (string)$v, $value);
        }
        return $value;
    }

    private static function load(string $code): array
    {
        if (isset(self::$dicts[$code])) return self::$dicts[$code];
        $path = __DIR__ . '/i18n/' . $code . '.php';
        self::$dicts[$code] = is_file($path) ? (array) require $path : [];
        return self::$dicts[$code];
    }

    private static function resolve(array $dict, string $key)
    {
        if (array_key_exists($key, $dict)) return $dict[$key];
        $parts = explode('.', $key);
        $cur = $dict;
        foreach ($parts as $p) {
            if (!is_array($cur) || !array_key_exists($p, $cur)) return null;
            $cur = $cur[$p];
        }
        return is_string($cur) ? $cur : null;
    }
}
