//
//  CLUI.swift

//
//  Created by Leon on 2025/7/11.
//

import Foundation

let EPConfigShadowPrefix = "@SHA:"
let EPConfigGradientPrefix = "@GRA:"

class CLBaseTokens {
    static var shared = CLBaseTokens()
    // MARK: - Properties
    
    var globalTokens: [String: Any]?
    var sysDarkTokens: [String: Any]?
    var sysLightTokens: [String: Any]?
    
    var globalKeys: [String]?
    var sysDarkKeys: [String]?
    var sysLightKeys: [String]?
    
    // MARK: - Singleton
    // static let shared = CLBaseTokens()
    
    init() {
        initialTokens()
    }
    
    // MARK: - Initial
    private func initialTokens() {
        // 加载 global tokens
        if let json1Path = Bundle.main.path(forResource: "token_global", ofType: "json"),
           let json1Data = try? Data(contentsOf: URL(fileURLWithPath: json1Path)),
           let dict1 = try? JSONSerialization.jsonObject(with: json1Data, options: []) as? [String: Any] {
            globalTokens = dict1
            globalKeys = dict1.keys.sorted()
            //assert(dict1 != nil, "json should be valid")
        }
        
        // 加载 sysDark tokens
        if let json2Path = Bundle.main.path(forResource: "token_sys_normal", ofType: "json"),
           let json2Data = try? Data(contentsOf: URL(fileURLWithPath: json2Path)),
           let dict2 = try? JSONSerialization.jsonObject(with: json2Data, options: []) as? [String: Any] {
            sysDarkTokens = dict2
            sysDarkKeys = dict2.keys.sorted()
        }
        
        assert(sysDarkTokens != nil)
    }
    
    // MARK: - Public Methods
    
    /// ⚠️ 只针对单 token 的情况，保留此方法，不推荐使用
    func getTokenByKey(_ key: String) -> String {
        var value: String?
        
        if let sysDarkKeys = sysDarkKeys, sysDarkKeys.contains(key) {
            value = sysDarkTokens?[key] as? String
        }
        
        if value == nil, let globalKeys = globalKeys, globalKeys.contains(key) {
            value = globalTokens?[key] as? String
        }
        
        guard let finalValue = value else {
            print("\(key) UI Token Key may doesn't exist")
            return ""
        }
        
        if finalValue.contains("$") {
            let keyNew = finalValue.replacingOccurrences(of: "$", with: "")
            return getTokenByKey(keyNew)
        }
        
        return finalValue
    }
    
    func getTokensByKey(_ key: String) -> [String] {
        var value: String?
        

        if let sysKeys = sysDarkKeys {
            if sysKeys.contains(key){
                value = sysDarkTokens?[key] as? String
            }
        }
        
        if value == nil, let globalKeys = globalKeys, globalKeys.contains(key) {
            value = globalTokens?[key] as? String
        }
        
        guard let finalValue = value else {
            print("❌\(key)❌ UI Token Key doesn't exist ❌❌")
            return []
        }
        
        let params = finalValue.components(separatedBy: ",")
        var arrayM: [String] = []
        
        for per in params {
            let dealPer = per.trimmingCharacters(in: .whitespacesAndNewlines)
            if dealPer.contains("$") {
                var keyNew = dealPer
                keyNew = keyNew.replacingOccurrences(of: EPConfigShadowPrefix, with: "")
                keyNew = keyNew.replacingOccurrences(of: EPConfigGradientPrefix, with: "")
                
                if keyNew.contains("&") {
                    let keys = keyNew.components(separatedBy: "&")
                    var multi: [String] = []
                    
                    for perKey in keys {
                        let keyNew2 = perKey.replacingOccurrences(of: "$", with: "")
                        let value = getTokenByKey(keyNew2)
                        multi.append(value)
                    }
                    
                    let covertValues = multi.joined(separator: "&")
                    arrayM.append(covertValues)
                } else {
                    var values: [String] = []
                    var tempKey = keyNew
                    while tempKey.contains("$") {
                        tempKey = tempKey.replacingOccurrences(of: "$", with: "")
                        values = getTokensByKey(tempKey)
                        arrayM.append(contentsOf: values)
                    }
                }
            } else {
                arrayM.append(dealPer)
            }
        }
        
        return arrayM
    }
    
    // MARK: - Always Dark
    
    /// ⚠️ 只针对单 token 的情况，保留此方法，不推荐使用
    func getDarkToken(_ key: String) -> String {
        var value: String?
        
        if let sysDarkKeys = sysDarkKeys, sysDarkKeys.contains(key) {
            value = sysDarkTokens?[key] as? String
        }
        
        if value == nil, let globalKeys = globalKeys, globalKeys.contains(key) {
            value = globalTokens?[key] as? String
        }
        
        guard let finalValue = value else {
            print("❌\(key)❌ UI Token Key doesn't exist ❌❌")
            return ""
        }
        
        if finalValue.contains("$") {
            let keyNew = finalValue.replacingOccurrences(of: "$", with: "")
            return getTokenByKey(keyNew)
        }
        
        return finalValue
    }
    
    func getDarkTokens(_ key: String) -> [String] {
        var value: String?
        
        if let sysDarkKeys = sysDarkKeys, sysDarkKeys.contains(key) {
            value = sysDarkTokens?[key] as? String
        }
        
        if value == nil, let globalKeys = globalKeys, globalKeys.contains(key) {
            value = globalTokens?[key] as? String
        }
        
        guard let finalValue = value else {
            print("❌\(key)❌ UI Token Key doesn't exist ❌❌")
            return []
        }
        
        let params = finalValue.components(separatedBy: ",")
        var arrayM: [String] = []
        
        for per in params {
            let dealPer = per.trimmingCharacters(in: .whitespacesAndNewlines)
            if dealPer.contains("$") {
                var keyNew = dealPer
                keyNew = keyNew.replacingOccurrences(of: EPConfigShadowPrefix, with: "")
                keyNew = keyNew.replacingOccurrences(of: EPConfigGradientPrefix, with: "")
                
                var values: [String] = []
                while keyNew.contains("$") {
                    keyNew = keyNew.replacingOccurrences(of: "$", with: "")
                    values = getTokensByKey(keyNew)
                    arrayM.append(contentsOf: values)
                }
            } else {
                arrayM.append(dealPer)
            }
        }
        
        return arrayM
    }
}




