<?php
/**
 * Internationalization (i18n) System
 * Complete multi-language support for the entire website
 */

class I18n {
    private static $instance = null;
    private $current_language = 'zh-TW';
    private $default_language = 'zh-TW';
    private $available_languages = [];
    private $translations = [];
    private $loaded_languages = [];
    
    private function __construct() {
        $this->initializeLanguages();
        $this->loadLanguage();
    }
    
    public static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    private function initializeLanguages() {
        $this->available_languages = [
            'zh-TW' => [
                'name' => '繁體中文',
                'native_name' => '繁體中文',
                'code' => 'zh-TW',
                'direction' => 'ltr',
                'date_format' => 'Y-m-d',
                'time_format' => 'H:i:s',
                'currency' => 'TWD',
                'locale' => 'zh_TW.UTF-8'
            ],
            'en-US' => [
                'name' => 'English',
                'native_name' => 'English',
                'code' => 'en-US',
                'direction' => 'ltr',
                'date_format' => 'm/d/Y',
                'time_format' => 'h:i:s A',
                'currency' => 'USD',
                'locale' => 'en_US.UTF-8'
            ],
            'zh-CN' => [
                'name' => '简体中文',
                'native_name' => '简体中文',
                'code' => 'zh-CN',
                'direction' => 'ltr',
                'date_format' => 'Y-m-d',
                'time_format' => 'H:i:s',
                'currency' => 'CNY',
                'locale' => 'zh_CN.UTF-8'
            ],
            'ja-JP' => [
                'name' => '日本語',
                'native_name' => '日本語',
                'code' => 'ja-JP',
                'direction' => 'ltr',
                'date_format' => 'Y/m/d',
                'time_format' => 'H:i:s',
                'currency' => 'JPY',
                'locale' => 'ja_JP.UTF-8'
            ]
        ];
    }
    
    private function loadLanguage() {
        // Start session if not already started
        if (session_status() == PHP_SESSION_NONE) {
            session_start();
        }
        
        // Get language from various sources
        $this->current_language = $this->detectLanguage();
        
        // Load translations
        $this->loadTranslations($this->current_language);
        
        // Set locale
        $this->setLocale();
    }
    
    private function detectLanguage() {
        // Priority order: session > cookie > browser > default
        
        // 1. Check session
        if (isset($_SESSION['language']) && $this->isValidLanguage($_SESSION['language'])) {
            return $_SESSION['language'];
        }
        
        // 2. Check cookie
        if (isset($_COOKIE['language']) && $this->isValidLanguage($_COOKIE['language'])) {
            return $_COOKIE['language'];
        }
        
        // 3. Check browser language
        if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
            $browser_lang = $this->parseBrowserLanguage($_SERVER['HTTP_ACCEPT_LANGUAGE']);
            if ($browser_lang && $this->isValidLanguage($browser_lang)) {
                return $browser_lang;
            }
        }
        
        // 4. Check URL parameter
        if (isset($_GET['lang']) && $this->isValidLanguage($_GET['lang'])) {
            return $_GET['lang'];
        }
        
        // 5. Default language
        return $this->default_language;
    }
    
    private function parseBrowserLanguage($accept_language) {
        $languages = explode(',', $accept_language);
        foreach ($languages as $lang) {
            $lang = trim(explode(';', $lang)[0]);
            $lang = str_replace('-', '_', $lang);
            
            // Map common browser languages to our supported languages
            $mapping = [
                'zh_TW' => 'zh-TW',
                'zh_HK' => 'zh-TW',
                'zh' => 'zh-CN',
                'zh_CN' => 'zh-CN',
                'en' => 'en-US',
                'en_US' => 'en-US',
                'en_GB' => 'en-US',
                'ja' => 'ja-JP',
                'ja_JP' => 'ja-JP'
            ];
            
            if (isset($mapping[$lang])) {
                return $mapping[$lang];
            }
        }
        
        return null;
    }
    
    private function isValidLanguage($language) {
        return array_key_exists($language, $this->available_languages);
    }
    
    private function loadTranslations($language) {
        if (in_array($language, $this->loaded_languages)) {
            return;
        }
        
        $language_file = __DIR__ . "/languages/{$language}.php";
        if (file_exists($language_file)) {
            $this->translations = array_merge($this->translations, include $language_file);
            $this->loaded_languages[] = $language;
        } else {
            // Fallback to default language
            if ($language !== $this->default_language) {
                $this->loadTranslations($this->default_language);
            }
        }
    }
    
    private function setLocale() {
        $locale = $this->available_languages[$this->current_language]['locale'];
        setlocale(LC_ALL, $locale);
    }
    
    public function setLanguage($language) {
        if (!$this->isValidLanguage($language)) {
            return false;
        }
        
        $this->current_language = $language;
        
        // Save to session
        if (session_status() == PHP_SESSION_NONE) {
            session_start();
        }
        $_SESSION['language'] = $language;
        
        // Save to cookie (expires in 1 year)
        setcookie('language', $language, time() + (365 * 24 * 60 * 60), '/');
        
        // Load new translations
        $this->loadTranslations($language);
        
        // Set new locale
        $this->setLocale();
        
        return true;
    }
    
    public function getCurrentLanguage() {
        return $this->current_language;
    }
    
    public function getAvailableLanguages() {
        return $this->available_languages;
    }
    
    public function getLanguageInfo($language = null) {
        if ($language === null) {
            $language = $this->current_language;
        }
        
        return $this->available_languages[$language] ?? null;
    }
    
    public function t($key, $params = [], $default = null) {
        $translation = $this->translations[$key] ?? $default ?? $key;
        
        // Handle parameters
        if (!empty($params) && is_array($params)) {
            foreach ($params as $param_key => $param_value) {
                $translation = str_replace("{{$param_key}}", $param_value, $translation);
            }
        }
        
        return $translation;
    }
    
    public function formatDate($date, $format = null) {
        if ($format === null) {
            $format = $this->available_languages[$this->current_language]['date_format'];
        }
        
        if (is_string($date)) {
            $date = new DateTime($date);
        }
        
        return $date->format($format);
    }
    
    public function formatTime($time, $format = null) {
        if ($format === null) {
            $format = $this->available_languages[$this->current_language]['time_format'];
        }
        
        if (is_string($time)) {
            $time = new DateTime($time);
        }
        
        return $time->format($format);
    }
    
    public function formatCurrency($amount, $currency = null) {
        if ($currency === null) {
            $currency = $this->available_languages[$this->current_language]['currency'];
        }
        
        $symbols = [
            'TWD' => 'NT$',
            'USD' => '$',
            'CNY' => '¥',
            'JPY' => '¥'
        ];
        
        $symbol = $symbols[$currency] ?? $currency;
        
        return $symbol . number_format($amount, 2);
    }
    
    public function getDirection() {
        return $this->available_languages[$this->current_language]['direction'];
    }
    
    public function isRTL() {
        return $this->getDirection() === 'rtl';
    }
    
    public function getLanguageSwitcherHTML($class = 'language-switcher') {
        $html = '<div class="' . $class . '">';
        $html .= '<select onchange="changeLanguage(this.value)" class="language-select">';
        
        foreach ($this->available_languages as $code => $info) {
            $selected = ($code === $this->current_language) ? ' selected' : '';
            $html .= '<option value="' . $code . '"' . $selected . '>';
            $html .= $info['native_name'];
            $html .= '</option>';
        }
        
        $html .= '</select>';
        $html .= '</div>';
        
        return $html;
    }
    
    public function getLanguageSwitcherJS() {
        return '
        <script>
        function changeLanguage(language) {
            // Update URL with language parameter
            const url = new URL(window.location);
            url.searchParams.set("lang", language);
            
            // Redirect to new URL
            window.location.href = url.toString();
        }
        </script>';
    }
}

// Global functions for easy access
function __($key, $params = [], $default = null) {
    return I18n::getInstance()->t($key, $params, $default);
}

function getCurrentLanguage() {
    return I18n::getInstance()->getCurrentLanguage();
}

function setLanguage($language) {
    return I18n::getInstance()->setLanguage($language);
}

function getAvailableLanguages() {
    return I18n::getInstance()->getAvailableLanguages();
}

function formatDate($date, $format = null) {
    return I18n::getInstance()->formatDate($date, $format);
}

function formatTime($time, $format = null) {
    return I18n::getInstance()->formatTime($time, $format);
}

function formatCurrency($amount, $currency = null) {
    return I18n::getInstance()->formatCurrency($amount, $currency);
}

function getLanguageSwitcher($class = 'language-switcher') {
    return I18n::getInstance()->getLanguageSwitcherHTML($class);
}

function getLanguageSwitcherJS() {
    return I18n::getInstance()->getLanguageSwitcherJS();
}
?>
