@preconcurrency import Foundation

enum LogLevel: String, Codable {
    case debug
    case info
    case warning
    case error
    
    func shouldLog(_ level: LogLevel) -> Bool {
        let levels: [LogLevel] = [.debug, .info, .warning, .error]
        guard let currentIndex = levels.firstIndex(of: self),
              let targetIndex = levels.firstIndex(of: level) else {
            return false
        }
        return targetIndex >= currentIndex
    }
}

struct LogConfig: Codable {
    let level: LogLevel
    
    init(level: LogLevel = .info) {
        self.level = level
    }
}

struct KeyMapping: Codable {
    let from: Int64
    let to: Int64
}

struct MappingConfig: Codable {
    private let mappings: [String: KeyMapping]
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        mappings = try container.decode([String: KeyMapping].self)
    }
    
    init(mappings: [String: KeyMapping] = [:]) {
        self.mappings = mappings
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encode(mappings)
    }
    
    func getAllMappings() -> [(Int64, Int64)] {
        return mappings.values.map { ($0.from, $0.to) }
    }
}

struct Config: Codable {
    let log: LogConfig
    let mapping: MappingConfig
    
    init(log: LogConfig = LogConfig(), mapping: MappingConfig = MappingConfig()) {
        self.log = log
        self.mapping = mapping
    }
    
    static func load(from path: String) throws -> Config {
        let url = URL(fileURLWithPath: path)
        let data = try Data(contentsOf: url)
        let decoder = JSONDecoder()
        return try decoder.decode(Config.self, from: data)
    }
    
    static func createDefault(at path: String) throws {
        let defaultConfig = Config(
            log: LogConfig(level: .info),
            mapping: MappingConfig(mappings: [
                "backslash2backspace": KeyMapping(from: 42, to: 51),
                "backspace2backslash": KeyMapping(from: 51, to: 42)
            ])
        )
        
        let encoder = JSONEncoder()
        encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
        let data = try encoder.encode(defaultConfig)
        try data.write(to: URL(fileURLWithPath: path))
    }
    
    static func getConfigPath() -> String {
        let homeDir = FileManager.default.homeDirectoryForCurrentUser
        let configDir = homeDir.appendingPathComponent(".config/uskey")
        
        try? FileManager.default.createDirectory(at: configDir, withIntermediateDirectories: true)
        
        return configDir.appendingPathComponent("config.json").path
    }
}
