import Foundation
import Combine
import SwiftUI
#if canImport(Translation)
import Translation
#endif

class LanguageManager: ObservableObject {
    static let shared = LanguageManager()
    
    @Published var supportedLanguages: [LanguageStatus] = []

    init() {
        // Initialize with candidates assuming internet required (fail-safe)
        self.supportedLanguages = candidateLocales.compactMap { id in
            let locale = Locale(identifier: id)
            return LanguageStatus(id: id, locale: locale, isOnlineRequired: true)
        }.sorted { $0.name < $1.name }
    }
    
    struct LanguageStatus: Identifiable, Equatable {
        let id: String // Locale identifier
        let locale: Locale
        let isOnlineRequired: Bool
        
        // English names for all supported languages
        private static let englishNames: [String: String] = [
            "ar-SA": "Arabic",
            "zh-CN": "Chinese (Simplified)",
            "zh-TW": "Chinese (Traditional)",
            "nl-NL": "Dutch",
            "en-US": "English (United States)",
            "en-UK": "English (United Kingdom)",
            "fr-FR": "French (France)",
            "de-DE": "German",
            "id-ID": "Indonesian",
            "it-IT": "Italian",
            "ja-JP": "Japanese",
            "ko-KR": "Korean",
            "pl-PL": "Polish",
            "pt-BR": "Portuguese (Brazil)",
            "ru-RU": "Russian",
            "es-ES": "Spanish (Spain)",
            "es-MX": "Spanish (Mexico)",
            "th-TH": "Thai",
            "tr-TR": "Turkish",
            "uk-UA": "Ukrainian",
            "vi-VN": "Vietnamese"
        ]
        
        var name: String {
            Self.englishNames[id] ?? locale.identifier
        }
        
        var flag: String {
            locale.flagEmoji ?? "🏳️"
        }
        
        var requiresInternet: Bool {
            isOnlineRequired
        }
        
        /// Languages that don't have downloadable packs (use built-in/internet)
        var isDownloadAvailable: Bool {
            // Only en-UK and es-MX don't have download available
            return id != "en-UK" && id != "es-MX"
        }
    }
    
    // A curated list of languages supported by Apple Translate
    private let candidateLocales: [String] = [
        "ar-SA", "zh-CN", "zh-TW", "nl-NL", "en-UK", "fr-FR", 
        "de-DE", "id-ID", "it-IT", "ja-JP", "ko-KR", "pl-PL", "pt-BR", 
        "ru-RU", "es-ES", "es-MX", "th-TH", "tr-TR", "uk-UA", "vi-VN"
    ]
    
    private let startSpeakingTranslations: [String: String] = [
        "ar-SA": "تحدث الآن...",
        "zh-CN": "开始说话...",
        "zh-TW": "開始說話...",
        "nl-NL": "Begin met spreken...",
        "en-US": "Start speaking...",
        "en-UK": "Start speaking...",
        "fr-FR": "Commencez à parler...",
        "de-DE": "Jetzt sprechen...",
        "id-ID": "Mulai berbicara...",
        "it-IT": "Inizia a parlare...",
        "ja-JP": "話し始めてください...",
        "ko-KR": "말씀해 주세요...",
        "pl-PL": "Zacznij mówić...",
        "pt-BR": "Comece a falar...",
        "ru-RU": "Начните говорить...",
        "es-ES": "Empieza a hablar...",
        "es-MX": "Empieza a hablar...",
        "th-TH": "เริ่มพูด...",
        "tr-TR": "Konuşmaya başla...",
        "uk-UA": "Почніть говорити...",
        "vi-VN": "Bắt đầu nói..."
    ]
    
    func getStartSpeakingText(for identifier: String) -> String {
        return startSpeakingTranslations[identifier] ?? "Start speaking..."
    }
    
    func checkAvailability() async {
        guard #available(iOS 18.0, *) else { return }
        
        #if canImport(Translation)
        var results: [LanguageStatus] = []
        let availability = LanguageAvailability()
        let source = Locale.Language(identifier: "en-US")
        
        for identifier in candidateLocales {
            let target = Locale.Language(identifier: identifier)
            let status = await availability.status(from: source, to: target)
            
            // Should we limit to only supported/installed?
            // If we initialized with all candidates, maybe we should keep all candidates
            // but update their online status?
            // For now, let's just stick to the discovered ones to be accurate about "Translation" support.
            // Actually, if we want the menu to work, we need items.
            // If 'status' is unsupported, we should probably remove it?
            // But 'candidateLocales' are presumably supported by the backend.
            
            if status == .supported || status == .installed {
                let locale = Locale(identifier: identifier)
                let isOnline = (status == .supported)
                results.append(LanguageStatus(id: identifier, locale: locale, isOnlineRequired: isOnline))
            }
        }
        
        await MainActor.run {
            // Update the list with verified verification status
            if !results.isEmpty {
                self.supportedLanguages = results.sorted { $0.name < $1.name }
            }
        }
        #endif
    }
    
    /// Check if a language identifier is internet-only (no download available)
    func isInternetOnlyLanguage(_ identifier: String) -> Bool {
        return identifier == "en-UK" || identifier == "es-MX"
    }
}

extension Locale {
    var flagEmoji: String? {
        // Simple heuristic for region code
        guard let region = self.region?.identifier else {
            // Try to parse from identifier if region is missing
            let parts = identifier.split(separator: "-")
            if parts.count > 1 {
                return String(parts.last!).flagEmoji
            }
            return nil
        }
        return region.flagEmoji
    }
}

extension String {
    var flagEmoji: String {
        let base: UInt32 = 127397
        var s = ""
        for v in self.unicodeScalars {
            s.unicodeScalars.append(UnicodeScalar(base + v.value)!)
        }
        return s
    }
}
