//
//  LanguagesUtils.swift
//  LegendTeam
//
//  Created by dong on 2022/5/18.
//

import Foundation
//import Lottie
import UIKit
import RswiftResources

enum Languages: String, Codable {
    case id
    case en
    case vi
    case fil
    case ms
    case th
}

/// api manager.. etc.
class LanguagesUtils {
    /// default languages order
    // static var supportLanguages:[Languages] = [.en, .id, .ms, .vi, .fil, .th]
    
    static func initailLanguageSetting() {
//        #warning("test to do")
//        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
//            Languages.preferedLans = LanguagesUtils.getSupportSortedLanguages()
//            LanguagesUtils.showAppLanugagesPickVc()
//        }
//        return

        if let lan = AppCache.fetchCache(key: CacheKey.userAppLanguage.rawValue, type: Languages.self) {
            Languages.preferedLans = [lan]
        } else {
            if UserCore.shared.isLogin() { // 针对老用户（版本更新前已经注册的老用户）
                AppCache.cache(key: CacheKey.userAppLanguage.rawValue, value: Languages.id)
                Languages.preferedLans = [Languages.id]
            } else {
                // 先按系统语言显示
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.7) {
                    Languages.preferedLans = LanguagesUtils.getSupportSortedLanguages()
                    LanguagesUtils.showAppLanugagesPickVc()
                }
            }
        }
    }
    
    static func isInitialLanuageAlreadySetting()-> Bool{
        if (AppCache.fetchCache(key: CacheKey.userAppLanguage.rawValue, type: Languages.self) != nil || UserCore.shared.isLogin()) {
            return true
        }else{
            return false
        }
    }

    static func showAppLanugagesPickVc() {
//        let vc = LanguagesPrimarySetupController()
//        guard let rootVc = UIWindow.applicationKey?.rootViewController else {
//            assert(false)
//            return
//        }
//
//        rootVc.addChild(vc)
//        rootVc.view.addSubview(vc.view)
//
//        vc.view.snp.makeConstraints { make in
//            make.edges.equalToSuperview()
//        }
    }

    /// 语言选择sheep vc, 语言顺序按固定默认顺序了
//    @discardableResult
//    static func showAppLanugagesPicker() -> SheetPopListSelectView {
//        
//    }

    // MARK: - helper

    /// 系统的语言顺序
    static func getSystemLanguagesList() -> [String] {
        let lanugages = Locale.preferredLanguages.compactMap { $0.components(separatedBy: "-").first }
        return lanugages
    }

    /// 默认顺序, 用在系统设置中，去设置
    static func languagesDict() -> [Languages] {
        return [.en, .id, .ms, .vi, .fil, .th]
    }

    /// 排序过后的（系统语言中有的，放到前面去），用在用户首次设置
    static func getSupportSortedLanguages() -> [Languages] {
        // default顺序
        let defaultOrderLanguages: [Languages] = LanguagesUtils.languagesDict()
        let systemLanguages = LanguagesUtils.getSystemLanguagesList() // ["en", "zh", "id"]
        var matchedArray: [Languages] = []
        let matched = systemLanguages.filter { // "en", "id"
            for per in defaultOrderLanguages {
                if $0 == per.rawValue {
                    matchedArray.append(per)
                    return true
                }
            }
            return false
        }

        let otherLanguages = defaultOrderLanguages.filter {
            !matched.contains($0.rawValue)
        }

        return matchedArray + otherLanguages
    }

    static func deviceSavePreferLanuage(lan: Languages) {
        Languages.preferedLans = [lan]
        AppCache.cache(key: CacheKey.userAppLanguage.rawValue, value: lan)
        //  加载App其他相关信息
        // ...
        
    }

    static func restartWindow() {
        if let appdelegate = UIApplication.shared.delegate as? AppDelegate {
            //appdelegate.setupWindowRootController()
        } else {
            assert(false)
        }
        NotificationCenter.post(name: .appLanugageChanged)
    }
}

extension Languages {
    /// 初始时尝试从配置中拉取
    public static var preferedLans: [Languages] = [Languages.en]

    // 🔥 RSwift Library会调用
    public static func preferLanguages() -> [String] {
        let preferLansCode = preferedLans.map { $0.rawValue }
        return preferLansCode + [Languages.en.rawValue] //
    }

    public static func localizedAppLanguage() -> String {
        let lan = preferedLans.first ?? .en

        return Languages.localizedLang(lan: lan)
    }

    // MARK: - helper

    public static func localizedLang(lan: Languages) -> String {
        return "en"
    }

    public static func selfLanDesc(lan: Languages) -> String {
        return "English"
    }

    static func regionCode(lan: Languages) -> String {
        return "en"
    }

    static func localRegionCode() -> String {
        let lan = preferedLans.first ?? .en
        return Languages.regionCode(lan: lan)
    }
}

@objcMembers class OCLanuagesUtils: NSObject {
    @objc static func localized(key: String, tableName: String, arguments: [String]?) -> String {
        guard let (locale, bundle) = StringResource.localeBundle(tableName: tableName, preferredLanguages: Languages.preferLanguages()) else {
            return key
        }
        let format = NSLocalizedString(key, tableName: tableName, bundle: bundle, comment: "")
        return String(format: format, locale: locale, arguments: arguments ?? [])
    }
}

extension StringResource {
    fileprivate static let applicationLocale = hostingBundle.preferredLocalizations.first.flatMap { Locale(identifier: $0) } ?? Locale.current
    fileprivate static let hostingBundle = Bundle.main

    public func localized(_ values: [String] = [""]) -> String {
        // 替换规则说明：  R.string.localizable.home.localized()    ->     R.string.localizable.home.localized.localized()
        guard let (locale, bundle) = StringResource.localeBundle(tableName: tableName, preferredLanguages: Languages.preferLanguages()) else {
            return key.description
        }

        let format = NSLocalizedString(key.description, tableName: tableName, bundle: bundle, comment: "")
        return String(format: format, locale: locale, arguments: values) // String(format: format, locale: locale, values)
    }

    /// Find first language and bundle for which the table exists
    fileprivate static func localeBundle(tableName: String, preferredLanguages: [String]) -> (Foundation.Locale, Foundation.Bundle)? {
        // Filter preferredLanguages to localizations, use first locale
        var languages = preferredLanguages
            .map { Locale(identifier: $0) }
            .prefix(1)
            .flatMap { locale -> [String] in
                if hostingBundle.localizations.contains(locale.identifier) {
                    if let language = locale.languageCode, hostingBundle.localizations.contains(language) {
                        return [locale.identifier, language]
                    } else {
                        return [locale.identifier]
                    }
                } else if let language = locale.languageCode, hostingBundle.localizations.contains(language) {
                    return [language]
                } else {
                    return []
                }
            }

        // If there's no languages, use development language as backstop
        if languages.isEmpty {
            if let developmentLocalization = hostingBundle.developmentLocalization {
                languages = [developmentLocalization]
            }
        } else {
            // Insert Base as second item (between locale identifier and languageCode)
            languages.insert("Base", at: 1)

            // Add development language as backstop
            if let developmentLocalization = hostingBundle.developmentLocalization {
                languages.append(developmentLocalization)
            }
        }

        // Find first language for which table exists
        // Note: key might not exist in chosen language (in that case, key will be shown)
        for language in languages {
            if let lproj = hostingBundle.url(forResource: language, withExtension: "lproj"),
               let lbundle = Bundle(url: lproj) {
                let strings = lbundle.url(forResource: tableName, withExtension: "strings")
                let stringsdict = lbundle.url(forResource: tableName, withExtension: "stringsdict")

                if strings != nil || stringsdict != nil {
                    return (Locale(identifier: language), lbundle)
                }
            }
        }

        // If table is available in main bundle, don't look for localized resources
        let strings = hostingBundle.url(forResource: tableName, withExtension: "strings", subdirectory: nil, localization: nil)
        let stringsdict = hostingBundle.url(forResource: tableName, withExtension: "stringsdict", subdirectory: nil, localization: nil)

        if strings != nil || stringsdict != nil {
            return (applicationLocale, hostingBundle)
        }

        // If table is not found for requested languages, key will be shown
        return nil
    }
}
