<?php
/**
 * 🌐 LANGUAGE CONTROLLER - V2.2 INTEGRATED
 *
 * Integrates with existing I18nManager and PO/MO files
 * Uses database table for en_US overrides (performance)
 *
 * @package FleekDash\Controllers
 * @since 2.2.0
 */

namespace FleekDash\Controllers;

use WP_REST_Request;
use FleekDash\Services\ResponseService;
use FleekDash\Core\I18nManager;

class LanguageController
{
    /**
     * Language metadata mapping
     */
    private static array $languageMetadata = [
        'en_US' => ['name' => 'English (United States)', 'nativeName' => 'English', 'flag' => '🇺🇸'],
        'pt_BR' => ['name' => 'Português (Brasil)', 'nativeName' => 'Português', 'flag' => '🇧🇷'],
        'es_ES' => ['name' => 'Español (España)', 'nativeName' => 'Español', 'flag' => '🇪🇸'],
        'fr_FR' => ['name' => 'Français (France)', 'nativeName' => 'Français', 'flag' => '🇫🇷'],
        'de_DE' => ['name' => 'Deutsch (Deutschland)', 'nativeName' => 'Deutsch', 'flag' => '🇩🇪'],
        'it_IT' => ['name' => 'Italiano (Italia)', 'nativeName' => 'Italiano', 'flag' => '🇮🇹'],
        'ja' => ['name' => '日本語 (Japanese)', 'nativeName' => '日本語', 'flag' => '🇯🇵'],
        'zh_CN' => ['name' => '简体中文 (Simplified Chinese)', 'nativeName' => '简体中文', 'flag' => '🇨🇳'],
        'zh_TW' => ['name' => '繁體中文 (Traditional Chinese)', 'nativeName' => '繁體中文', 'flag' => '🇹🇼'],
        'ko' => ['name' => '한국어 (Korean)', 'nativeName' => '한국어', 'flag' => '🇰🇷'],
        'ru_RU' => ['name' => 'Русский (Russian)', 'nativeName' => 'Русский', 'flag' => '🇷🇺'],
        'ar' => ['name' => 'العربية (Arabic)', 'nativeName' => 'العربية', 'flag' => '🇸🇦'],
        'nl_NL' => ['name' => 'Nederlands (Dutch)', 'nativeName' => 'Nederlands', 'flag' => '🇳🇱'],
        'pl_PL' => ['name' => 'Polski (Polish)', 'nativeName' => 'Polski', 'flag' => '🇵🇱'],
        'sv_SE' => ['name' => 'Svenska (Swedish)', 'nativeName' => 'Svenska', 'flag' => '🇸🇪'],
        'da_DK' => ['name' => 'Dansk (Danish)', 'nativeName' => 'Dansk', 'flag' => '🇩🇰'],
        'fi' => ['name' => 'Suomi (Finnish)', 'nativeName' => 'Suomi', 'flag' => '🇫🇮'],
        'no' => ['name' => 'Norsk (Norwegian)', 'nativeName' => 'Norsk', 'flag' => '🇳🇴'],
        'tr_TR' => ['name' => 'Türkçe (Turkish)', 'nativeName' => 'Türkçe', 'flag' => '🇹🇷'],
        'el' => ['name' => 'Ελληνικά (Greek)', 'nativeName' => 'Ελληνικά', 'flag' => '🇬🇷'],
        'he_IL' => ['name' => 'עברית (Hebrew)', 'nativeName' => 'עברית', 'flag' => '🇮🇱'],
        'hi_IN' => ['name' => 'हिन्दी (Hindi)', 'nativeName' => 'हिन्दी', 'flag' => '🇮🇳'],
    ];

    /**
     * Get languages from PO/MO files (real system)
     */
    private static function getLanguagesFromFiles(): array
    {
        $i18n_manager = I18nManager::getInstance();
        $available_languages = $i18n_manager->getAvailableLanguages();

        $languages = [];
        $order = 0;

        foreach ($available_languages as $locale => $name) {
            $metadata = self::$languageMetadata[$locale] ?? [
                'name' => $name,
                'nativeName' => $name,
                'flag' => '🌐'
            ];

            // Get translation stats
            $stats = $i18n_manager->getTranslationStats($locale);

            $languages[] = [
                'locale' => $locale,
                'code' => explode('_', $locale)[0],
                'name' => $metadata['name'],
                'nativeName' => $metadata['nativeName'],
                'flag' => $metadata['flag'],
                'isActive' => true, // All installed languages are active
                'translationCount' => $stats['translated'],
                'totalStrings' => $stats['total'],
                'order' => $order++
            ];
        }

        return $languages;
    }

    public function getLanguages()
    {
        try {
            // V2.2 INTEGRATED: Use real PO/MO files
            $languages = self::getLanguagesFromFiles();
            return ResponseService::success('Languages retrieved', ['languages' => $languages]);
        } catch (\Exception $e) {
            return ResponseService::error('Failed to get languages', ['error' => $e->getMessage()], 500);
        }
    }

    public function addLanguage()
    {
        try {
            // V2.2 INTEGRATED: Adding language requires PO/MO file upload
            // This is just a placeholder - actual implementation would involve file upload
            return ResponseService::error(
                'To add a new language, upload PO/MO files to the languages/ directory',
                ['help' => 'Use a translation tool like Poedit to create .po and .mo files'],
                501 // Not implemented
            );
        } catch (\Exception $e) {
            return ResponseService::error('Failed to add language', ['error' => $e->getMessage()], 500);
        }
    }

    public function updateLanguageOrder()
    {
        try {
            // V2.2 INTEGRATED: Order is determined by installation, not dynamic
            return ResponseService::success('Language order cannot be changed with PO files system');
        } catch (\Exception $e) {
            return ResponseService::error('Failed to update order', ['error' => $e->getMessage()], 500);
        }
    }

    public function toggleLanguage()
    {
        try {
            // V2.2 INTEGRATED: All installed PO files are active
            // To disable, remove the PO/MO files from languages/ directory
            return ResponseService::success('Language toggle not available with PO files system');
        } catch (\Exception $e) {
            return ResponseService::error('Failed to toggle language', ['error' => $e->getMessage()], 500);
        }
    }

    public function deleteLanguage(WP_REST_Request $request)
    {
        $validationError = $this->validateLocaleForDeletion($request->get_param('locale'));
        if ($validationError !== null) {
            return $validationError;
        }
        return $this->performLanguageDeletion(\sanitize_text_field($request->get_param('locale')));
    }

    /**
     * Perform the actual PO/MO file deletion. Returns REST response.
     */
    private function performLanguageDeletion(string $locale)
    {
        try {
            $filesInfo = $this->findLanguageFiles($locale);
            $deleted = $this->removeLanguageFiles($filesInfo);
            if (!$deleted) {
                return ResponseService::error('Language files not found', [], 404);
            }
            I18nManager::getInstance()->clearCache();
            return ResponseService::success('Language deleted successfully');
        } catch (\Exception $e) {
            return ResponseService::error('Failed to delete language', ['error' => $e->getMessage()], 500);
        }
    }

    /**
     * Validate locale for deletion. Returns error response or null if valid.
     * Uses getInstalledLanguageFilePaths() as single source of truth so validation
     * and findLanguageFiles are aligned (avoids MO-only passing validation then 404).
     */
    private function validateLocaleForDeletion(?string $locale)
    {
        $result = null;
        if (!$locale) {
            $result = ResponseService::error('Locale is required', [], 400);
        } else {
            $sanitized = \sanitize_text_field($locale);
            if (!\preg_match('/^[a-z]{2,3}(_[A-Z]{2})?$/', $sanitized)) {
                $result = ResponseService::error('Invalid locale format', [], 400);
            } elseif ($sanitized === 'en_US') {
                $result = ResponseService::error('Cannot delete default language (en_US)', [], 400);
            } else {
                $pathsByLocale = I18nManager::getInstance()->getInstalledLanguageFilePaths();
                if (!isset($pathsByLocale[$sanitized])) {
                    $result = ResponseService::error('Language not installed', [], 404);
                }
            }
        }
        return $result;
    }

    /**
     * Get PO/MO file paths for a locale. Uses paths from I18nManager's filesystem scan
     * (no path construction from user input - S2083 path injection fix).
     *
     * @return array{po: string|null, mo: string|null}
     */
    private function findLanguageFiles(string $locale): array
    {
        $pathsByLocale = I18nManager::getInstance()->getInstalledLanguageFilePaths();
        $files = $pathsByLocale[$locale] ?? null;
        return $files ?? ['po' => null, 'mo' => null];
    }

    /**
     * @param array{po: string|null, mo: string|null} $filesInfo Paths from I18nManager whitelist (not user-constructed)
     */
    private function removeLanguageFiles(array $filesInfo): bool
    {
        $deleted = false;
        if ($filesInfo['po'] && file_exists($filesInfo['po'])) {
            unlink($filesInfo['po']); // NOSONAR phpsecurity:S2083 - Paths from getInstalledLanguageFilePaths() whitelist; locale validated in validateLocaleForDeletion
            $deleted = true;
        }
        if ($filesInfo['mo'] && file_exists($filesInfo['mo'])) {
            unlink($filesInfo['mo']); // NOSONAR phpsecurity:S2083 - Paths from getInstalledLanguageFilePaths() whitelist; locale validated in validateLocaleForDeletion
            $deleted = true;
        }
        return $deleted;
    }

    public function getTranslationStrings(WP_REST_Request $request)
    {
        try {
            $locale = $request->get_param('locale');

            if (!$locale) {
                return ResponseService::error('Locale is required', [], 400);
            }

            // For now, return empty array - will be populated from PO files later
            $strings = \get_option("fleekdash_translation_strings_{$locale}", []);

            return ResponseService::success('Translation strings retrieved', ['strings' => $strings]);
        } catch (\Exception $e) {
            return ResponseService::error('Failed to get strings', ['error' => $e->getMessage()], 500);
        }
    }

    public function updateTranslationString()
    {
        try {
            // V2.2 INTEGRATED: Not used anymore (using TextOverridesController)
            return ResponseService::error(
                'Use text-overrides endpoint instead',
                ['endpoint' => '/fleekdash/v1/text-overrides/{locale}/strings/{string_id}'],
                501
            );
        } catch (\Exception $e) {
            return ResponseService::error('Failed to update string', ['error' => $e->getMessage()], 500);
        }
    }
}
