import Foundation

/// Key bundle for one device, used in X3DH
struct DeviceBundle {
    let deviceId: String
    let identityKey: Data      // Ed25519 public key (32 bytes)
    let spk: Data              // X25519 public key (32 bytes)
    let spkSignature: Data     // Ed25519 signature (64 bytes)
    let spkId: String
    let opk: Data?             // X25519 public key (32 bytes), optional
    let opkId: String?

    /// Parse from server response dictionary
    /// Server uses: signed_prekey, signed_prekey_id, one_time_prekey, one_time_prekey_id (base64)
    static func fromDict(_ dict: [String: Any], identityKey: Data? = nil) throws -> DeviceBundle {
        guard let deviceId = dict["device_id"] as? String else {
            throw ChatError.invalidData("Missing device_id")
        }

        // Identity key can be passed in (from parent) or in dict
        let ik: Data
        if let passedIk = identityKey {
            ik = passedIk
        } else if let ikB64 = dict["identity_key"] as? String,
                  let ikData = Data(base64Encoded: ikB64) {
            ik = ikData
        } else {
            throw ChatError.invalidData("Missing identity_key")
        }

        // SPK - try both naming conventions, base64 encoded
        let spkB64 = dict["signed_prekey"] as? String ?? dict["spk"] as? String
        guard let spkB64 = spkB64,
              let spk = Data(base64Encoded: spkB64) else {
            throw ChatError.invalidData("Missing signed_prekey")
        }

        // SPK signature - base64 encoded
        guard let spkSigB64 = dict["spk_signature"] as? String,
              let spkSig = Data(base64Encoded: spkSigB64) else {
            throw ChatError.invalidData("Missing spk_signature")
        }

        // SPK ID - try both naming conventions
        let spkId = dict["signed_prekey_id"] as? String ?? dict["spk_id"] as? String
        guard let spkId = spkId else {
            throw ChatError.invalidData("Missing signed_prekey_id")
        }

        // OPK - optional, base64 encoded
        var opk: Data?
        var opkId: String?
        let opkB64 = dict["one_time_prekey"] as? String ?? dict["opk"] as? String
        if let opkB64 = opkB64, let opkData = Data(base64Encoded: opkB64) {
            opk = opkData
            opkId = dict["one_time_prekey_id"] as? String ?? dict["opk_id"] as? String
        }

        return DeviceBundle(
            deviceId: deviceId,
            identityKey: ik,
            spk: spk,
            spkSignature: spkSig,
            spkId: spkId,
            opk: opk,
            opkId: opkId
        )
    }
}
