import Foundation
import WatchConnectivity

/// Manages WatchConnectivity session and receives card data from iPhone
@MainActor
final class WatchConnectivityService: NSObject {
    static let shared = WatchConnectivityService()
    
    /// Callback when cards are received from iPhone
    var onCardsReceived: (([WatchCard]) -> Void)?
    
    private var session: WCSession?
    
    private override init() {
        super.init()
        if WCSession.isSupported() {
            session = WCSession.default
            session?.delegate = self
            session?.activate()
            WatchDesign.debugLog("WatchConnectivity: Session activating...")
        } else {
            WatchDesign.debugLog("WatchConnectivity: Not supported")
        }
    }
    
    /// Check for any existing application context on launch
    func checkForExistingContext() {
        guard let session = session else { return }
        
        let context = session.receivedApplicationContext
        if !context.isEmpty {
            WatchDesign.debugLog("WatchConnectivity: Found existing context on launch")
            processReceivedContext(context)
        } else {
            WatchDesign.debugLog("WatchConnectivity: No existing context found")
        }
    }
    
    private func processReceivedContext(_ context: [String: Any]) {
        guard let cardsData = context["cards"] as? Data else {
            WatchDesign.debugLog("WatchConnectivity: No cards data in context")
            return
        }
        
        WatchDesign.debugLog("WatchConnectivity: Received \(cardsData.count) bytes")
        
        do {
            let syncableCards = try JSONDecoder().decode([SyncableCard].self, from: cardsData)
            let watchCards = syncableCards.map { syncable in
                WatchCard(
                    id: syncable.id,
                    fullName: syncable.fullName,
                    role: syncable.role,
                    company: syncable.company,
                    email: syncable.email,
                    phone: syncable.phone,
                    website: syncable.website,
                    location: syncable.location,
                    isDefault: syncable.isDefault,
                    qrCodeImageData: syncable.qrCodeImageData
                )
            }
            WatchDesign.debugLog("WatchConnectivity: Decoded \(watchCards.count) cards")
            onCardsReceived?(watchCards)
        } catch {
            WatchDesign.debugLog("WatchConnectivity: ERROR - Failed to decode: \(error)")
        }
    }
}

// MARK: - WCSessionDelegate

extension WatchConnectivityService: WCSessionDelegate {
    nonisolated func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        Task { @MainActor in
            if let error = error {
                WatchDesign.debugLog("WatchConnectivity: Activation failed: \(error)")
            } else {
                WatchDesign.debugLog("WatchConnectivity: Activated with state: \(activationState.rawValue)")
                // Check for existing context after activation
                checkForExistingContext()
            }
        }
    }
    
    nonisolated func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String: Any]) {
        Task { @MainActor in
            WatchDesign.debugLog("WatchConnectivity: Received application context update")
            processReceivedContext(applicationContext)
        }
    }
    
    nonisolated func session(_ session: WCSession, didReceiveUserInfo userInfo: [String: Any] = [:]) {
        Task { @MainActor in
            WatchDesign.debugLog("WatchConnectivity: Received userInfo transfer")
            processReceivedContext(userInfo)
        }
    }
    
    nonisolated func session(_ session: WCSession, didReceiveMessage message: [String: Any]) {
        Task { @MainActor in
            WatchDesign.debugLog("WatchConnectivity: Received message")
            processReceivedContext(message)
        }
    }
}

/// Syncable card structure matching iOS side (for decoding)
private struct SyncableCard: Codable, Identifiable {
    let id: UUID
    var fullName: String
    var role: String
    var company: String
    var email: String
    var phone: String
    var website: String
    var location: String
    var isDefault: Bool
    var pronouns: String
    var bio: String
    var linkedIn: String
    var twitter: String
    var instagram: String
    var qrCodeImageData: Data?
}
