import Foundation
import Security

enum ServerListStore {
    static var appSupportURL: URL {
        let url = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
        return url.appendingPathComponent("VoiceCat", isDirectory: true)
    }

    static var serversURL: URL {
        appSupportURL.appendingPathComponent("servers.json")
    }

    static var tofuStorePath: String {
        appSupportURL.appendingPathComponent("tofu_pins.txt").path
    }

    static func load() -> [SavedServer] {
        try? FileManager.default.createDirectory(at: appSupportURL, withIntermediateDirectories: true)
        guard let data = try? Data(contentsOf: serversURL),
              let list = try? JSONDecoder().decode([SavedServer].self, from: data) else { return [] }
        return list
    }

    static func save(_ servers: [SavedServer]) {
        try? FileManager.default.createDirectory(at: appSupportURL, withIntermediateDirectories: true)
        if let data = try? JSONEncoder().encode(servers) {
            try? data.write(to: serversURL, options: .atomic)
        }
    }

    // MARK: - Keychain

    static func savePassword(_ password: String, tag: String) {
        guard let data = password.data(using: .utf8) else { return }
        deletePassword(tag: tag)
        let query: [CFString: Any] = [
            kSecClass: kSecClassGenericPassword,
            kSecAttrService: "cat.voice.VoiceCatMac",
            kSecAttrAccount: tag,
            kSecValueData: data,
        ]
        SecItemAdd(query as CFDictionary, nil)
    }

    static func loadPassword(tag: String) -> String? {
        let query: [CFString: Any] = [
            kSecClass: kSecClassGenericPassword,
            kSecAttrService: "cat.voice.VoiceCatMac",
            kSecAttrAccount: tag,
            kSecReturnData: true,
            kSecMatchLimit: kSecMatchLimitOne,
        ]
        var result: AnyObject?
        guard SecItemCopyMatching(query as CFDictionary, &result) == errSecSuccess,
              let data = result as? Data,
              let password = String(data: data, encoding: .utf8) else { return nil }
        return password
    }

    static func deletePassword(tag: String) {
        let query: [CFString: Any] = [
            kSecClass: kSecClassGenericPassword,
            kSecAttrService: "cat.voice.VoiceCatMac",
            kSecAttrAccount: tag,
        ]
        SecItemDelete(query as CFDictionary)
    }
}
