import Foundation

/// Encrypted local message cache.
/// Matches Python: chat_core.py message cache (message_cache/{conv_id}.json)
enum MessageCache {

    /// Save messages for a conversation (encrypted with local storage key)
    static func save(email: String, convId: String, messages: [[String: Any]], cacheKey: Data?) throws {
        let dir = try KeyStorage.getKeyDir(email: email).appendingPathComponent("message_cache")
        try FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true)

        let jsonData = try JSONSerialization.data(withJSONObject: messages)

        let dataToWrite: Data
        if let cacheKey = cacheKey {
            dataToWrite = try CryptoUtils.encryptLocal(jsonData, key: cacheKey)
        } else {
            dataToWrite = jsonData
        }

        try dataToWrite.write(to: dir.appendingPathComponent("\(convId).json"), options: .completeFileProtection)
    }

    /// Load messages for a conversation
    static func load(email: String, convId: String, cacheKey: Data?) -> [[String: Any]]? {
        guard let dir = try? KeyStorage.getKeyDir(email: email) else { return nil }
        let path = dir.appendingPathComponent("message_cache").appendingPathComponent("\(convId).json")
        guard let raw = try? Data(contentsOf: path) else { return nil }

        let jsonData: Data
        if let cacheKey = cacheKey {
            if let decrypted = try? CryptoUtils.decryptLocal(raw, key: cacheKey) {
                jsonData = decrypted
            } else {
                // Plaintext fallback (migration)
                jsonData = raw
            }
        } else {
            jsonData = raw
        }

        return try? JSONSerialization.jsonObject(with: jsonData) as? [[String: Any]]
    }

    /// Search messages in a conversation
    static func search(email: String, convId: String, query: String, cacheKey: Data?) -> [[String: Any]] {
        guard let messages = load(email: email, convId: convId, cacheKey: cacheKey) else {
            return []
        }
        let lowerQuery = query.lowercased()
        return messages.filter { msg in
            if let text = msg["text"] as? String, text.lowercased().contains(lowerQuery) {
                return true
            }
            return false
        }
    }

    /// Delete cache for a conversation
    static func delete(email: String, convId: String) {
        guard let dir = try? KeyStorage.getKeyDir(email: email) else { return }
        let path = dir.appendingPathComponent("message_cache").appendingPathComponent("\(convId).json")
        try? FileManager.default.removeItem(at: path)
    }
}
