<?php
/**
 * Biscotti CMP — Canonical language list (single source of truth)
 *
 * The product ships in exactly 44 canonical locales. Portuguese is split into
 * pt-BR and pt-PT and Chinese into zh (Simplified) and zh-TW (Traditional);
 * a bare `pt` is never used. This class is the ONE place that defines that set,
 * so every language dropdown in the plugin (Gutenberg block, Beaver/Divi/
 * Elementor/Oxygen/WPBakery modules, settings) stays in lock-step — no more
 * per-file hand-maintained lists that drift, omit languages, or use bare `pt`.
 *
 * @package Biscotti_CMP
 * @since 4.2.1
 */

if (!defined('ABSPATH')) {
    exit;
}

class Biscotti_Languages
{
    /**
     * The 44 canonical locales → native name (endonym).
     * Order mirrors the dashboard app's language picker.
     *
     * @var array<string,string>
     */
    const ENDONYMS = [
        'de'    => 'Deutsch',
        'en'    => 'English',
        'fr'    => 'Français',
        'es'    => 'Español',
        'it'    => 'Italiano',
        'nl'    => 'Nederlands',
        'pl'    => 'Polski',
        'pt-BR' => 'Português (Brasil)',
        'pt-PT' => 'Português (Portugal)',
        'da'    => 'Dansk',
        'et'    => 'Eesti',
        'lv'    => 'Latviešu',
        'mt'    => 'Malti',
        'ga'    => 'Gaeilge',
        'ar'    => 'العربية',
        'bg'    => 'Български',
        'bs'    => 'Bosanski',
        'ca'    => 'Català',
        'cs'    => 'Čeština',
        'el'    => 'Ελληνικά',
        'eu'    => 'Euskara',
        'fi'    => 'Suomi',
        'gl'    => 'Galego',
        'he'    => 'עברית',
        'hi'    => 'हिन्दी',
        'hr'    => 'Hrvatski',
        'hu'    => 'Magyar',
        'id'    => 'Bahasa Indonesia',
        'ja'    => '日本語',
        'lt'    => 'Lietuvių',
        'mr'    => 'मराठी',
        'nb'    => 'Norsk Bokmål',
        'ro'    => 'Română',
        'ru'    => 'Русский',
        'sk'    => 'Slovenčina',
        'sl'    => 'Slovenščina',
        'sr'    => 'Српски',
        'sv'    => 'Svenska',
        'th'    => 'ไทย',
        'tr'    => 'Türkçe',
        'uk'    => 'Українська',
        'vi'    => 'Tiếng Việt',
        'zh'    => '中文 (简体)',
        'zh-TW' => '中文 (繁體)',
    ];

    /**
     * The canonical code → native name map.
     *
     * @return array<string,string>
     */
    public static function endonyms()
    {
        return self::ENDONYMS;
    }

    /**
     * The list of canonical codes.
     *
     * @return string[]
     */
    public static function codes()
    {
        return array_keys(self::ENDONYMS);
    }

    /**
     * Build a [code => label] options array for a `<select>`, optionally with a
     * leading "auto" entry. Labels default to the native names.
     *
     * @param bool        $with_auto  Prepend an "Auto (from WordPress)" option.
     * @param string|null $auto_label Override the auto label (already translated).
     * @return array<string,string>
     */
    public static function select_options($with_auto = true, $auto_label = null)
    {
        $opts = [];
        if ($with_auto) {
            $opts['auto'] = $auto_label !== null
                ? $auto_label
                : __('Auto (from WordPress)', 'biscotti-cmp');
        }
        foreach (self::ENDONYMS as $code => $name) {
            $opts[$code] = $name;
        }
        return $opts;
    }

    /**
     * Normalise any locale/language input to one of the 44 canonical codes.
     * Preserves pt-BR / pt-PT / zh-TW; maps a bare `pt` → pt-BR, `no` → nb,
     * Traditional-Chinese variants → zh-TW; collapses everything else to its
     * 2-letter base. Falls back to 'en' for unknown input.
     *
     * @param string $code
     * @return string canonical code
     */
    public static function canonicalize($code)
    {
        $code = is_string($code) ? trim($code) : '';
        if ($code === '' || strtolower($code) === 'auto') {
            return 'en';
        }
        $norm = str_replace('_', '-', $code);
        $lower = strtolower($norm);

        // Regional variants we keep distinct.
        if ($lower === 'pt-br') return 'pt-BR';
        if ($lower === 'pt-pt') return 'pt-PT';
        if ($lower === 'pt')    return 'pt-BR';
        if ($lower === 'zh-tw' || $lower === 'zh-hant') return 'zh-TW';
        if (strpos($lower, 'zh') === 0) return 'zh';
        if ($lower === 'no' || strpos($lower, 'nb') === 0 || strpos($lower, 'nn') === 0) return 'nb';

        $base = substr($lower, 0, 2);
        return isset(self::ENDONYMS[$base]) ? $base : 'en';
    }

    /**
     * Map a canonical code to the best key available in the legacy in-plugin
     * label tables (class-shortcodes.php), which are keyed on bare codes
     * (`pt`, `zh`, `no`). Guarantees those tables resolve to the right language
     * instead of silently falling back to English.
     *
     * @param string $code canonical code (or anything canonicalize() accepts)
     * @return string legacy table key
     */
    public static function to_legacy($code)
    {
        $canon = self::canonicalize($code);
        switch ($canon) {
            case 'pt-BR':
            case 'pt-PT':
                return 'pt';
            case 'zh-TW':
                return 'zh';
            case 'nb':
                return 'no';
            default:
                return $canon;
        }
    }
}
