<?php
declare(strict_types=1);

/**
 * 多语言类
 * 语言包是纯 PHP 数组文件（key => 译文），找不到 key 时原样返回 key 本身兜底
 */
final class Lang
{
    /** @var array<string, string> 当前已加载的语言字典 */
    private static array $dict = [];

    /** 当前语言标识，如 'zh-CN' / 'en' / 'de' */
    private static string $locale = '';

    /** 语言标识 -> 数据库字段语言段（_cn_/_en_/_de_ 等）的特例映射，未命中的走通用规则 */
    private const LOCALE_FIELD_MAP = [
        'zh-cn' => 'cn',
    ];

    /**
     * 加载语言包
     * @param string $locale 语言标识，对应 [langDir]/[locale].php
     * @param string $langDir 语言包所在目录
     */
    public static function load(string $locale, string $langDir): void
    {
        self::$locale = $locale;
        $file = rtrim($langDir, '/') . '/' . $locale . '.php';
        self::$dict = is_file($file) ? require $file : [];
    }

    /**
     * 取译文，找不到时原样返回 $key
     */
    public static function get(string $key): string
    {
        return self::$dict[$key] ?? $key;
    }

    /**
     * 当前语言标识，如 'zh-CN'
     */
    public static function locale(): string
    {
        return self::$locale;
    }

    /**
     * 数据表多语言字段约定：字段名里 `_cn_`/`_en_`/`_de_` 等表示该字段是哪种语言的内容
     * 按当前语言选出该用哪个语言段，找不到对应语言的字段时回退到 _en_，再找不到就用第一个可用的
     * @param array $available 该表实际存在的语言段，如 ['cn','en']
     * @param string $fallback 都找不到时的兜底语言段
     * @return string 语言段，如 'cn'/'en'
     */
    public static function pickField(array $available, string $fallback = 'en'): string
    {
        $segment = self::LOCALE_FIELD_MAP[strtolower(self::$locale)] ?? strtolower(explode('-', self::$locale)[0]);

        if (in_array($segment, $available, true)) {
            return $segment;
        }

        if (in_array($fallback, $available, true)) {
            return $fallback;
        }

        return $available[0] ?? $fallback;
    }
}
