import Foundation
import WatchConnectivity
import Flutter

class WatchSessionManager: NSObject, WCSessionDelegate {
    static let shared = WatchSessionManager()

    private var flutterChannel: FlutterMethodChannel?
    private var isFlutterWatchSyncReady = false
    private var pendingAuthPayloads: [[String: Any]] = []
    private var pendingICloudRecoveryNotification = false
    private let pendingAuthQueue = DispatchQueue(label: "app.firka.pendingAuthQueue")

    override private init() {
        super.init()
    }

    private func mergeApplicationContext(_ newEntries: [String: Any]) {
        let session = WCSession.default
        guard session.activationState == .activated else { return }

        var merged = session.applicationContext
        for (key, value) in newEntries {
            merged[key] = value
        }
        if !newEntries.keys.contains("force_logout") {
            merged.removeValue(forKey: "force_logout")
        }
        do {
            try session.updateApplicationContext(merged)
        } catch {
            print("[WatchSessionManager] Failed to merge applicationContext: \(error)")
        }
    }

    func setup(with messenger: FlutterBinaryMessenger) {
        flutterChannel = FlutterMethodChannel(
            name: "app.firka/watch_sync",
            binaryMessenger: messenger
        )

        flutterChannel?.setMethodCallHandler { [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) in
            switch call.method {
            case "sendTokenToWatch":
                self?.handleSendTokenToWatch(arguments: call.arguments, result: result)
            case "sendWidgetDataToWatch":
                self?.handleSendWidgetDataToWatch(arguments: call.arguments, result: result)
            case "sendLanguageToWatch":
                self?.handleSendLanguageToWatch(arguments: call.arguments, result: result)
            case "notifyReauthRequired":
                self?.handleNotifyReauthRequired(result: result)
            case "requestTokenFromWatch":
                self?.handleRequestTokenFromWatch(result: result)
            case "checkiCloudToken":
                self?.handleCheckiCloudToken(result: result)
            case "saveTokeToniCloud":
                self?.handleSaveTokenToiCloud(arguments: call.arguments, result: result)
            case "isWatchAppInstalled":
                self?.handleIsWatchAppInstalled(result: result)
            case "isWatchReachable":
                self?.handleIsWatchReachable(result: result)
            case "clearICloudToken":
                self?.handleClearICloudToken(result: result)
            case "sendLogoutToWatch":
                self?.handleSendLogoutToWatch(result: result)
            case "watchSyncReady":
                self?.handleWatchSyncReady(result: result)
            case "waitForPeerRefreshLease":
                self?.handleWaitForPeerRefreshLease(arguments: call.arguments, result: result)
            case "acquireRefreshLease":
                self?.handleAcquireRefreshLease(arguments: call.arguments, result: result)
            case "releaseRefreshLease":
                self?.handleReleaseRefreshLease(arguments: call.arguments, result: result)
            case "clearRefreshLeaseForAccount":
                self?.handleClearRefreshLeaseForAccount(arguments: call.arguments, result: result)
            case "clearAllRefreshLeases":
                self?.handleClearAllRefreshLeases(result: result)
            case "clearSharedLanguageState":
                self?.handleClearSharedLanguageState(result: result)
            case "sendMessageToWatch":
                self?.handleSendMessageToWatch(arguments: call.arguments, result: result)
            default:
                result(FlutterMethodNotImplemented)
            }
        }

        if WCSession.isSupported() {
            WCSession.default.delegate = self
            WCSession.default.activate()
            print("[WatchSessionManager] WCSession activated")
        } else {
            print("[WatchSessionManager] WCSession not supported on this device")
        }

        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleTokenRecoveredFromiCloud),
            name: Notification.Name("TokenRecoveredFromiCloud"),
            object: nil
        )
    }

    @objc private func handleTokenRecoveredFromiCloud() {
        print("[WatchSessionManager] Token recovered from iCloud, notifying Flutter to clear reauth flag")
        DispatchQueue.main.async {
            self.notifyTokenRecoveredToFlutter()
        }
    }

    private func parseInt64(_ value: Any?) -> Int64? {
        if let value = value as? Int64 {
            return value
        }
        if let value = value as? Int {
            return Int64(value)
        }
        if let value = value as? Double {
            return Int64(value)
        }
        if let value = value as? String, let parsed = Int64(value) {
            return parsed
        }
        return nil
    }

    private func parseLeaseOwner(_ value: Any?) -> RefreshLeaseOwner? {
        guard let raw = value as? String else {
            return nil
        }
        return RefreshLeaseOwner(rawValue: raw)
    }

    private func tokenPayload(from token: WatchToken) -> [String: Any] {
        var tokenData: [String: Any] = [
            "studentId": token.studentId,
            "studentIdNorm": token.studentIdNorm,
            "iss": token.iss,
            "idToken": token.idToken,
            "accessToken": token.accessToken,
            "refreshToken": token.refreshToken,
            "expiryDate": Int64(token.expiryDate.timeIntervalSince1970 * 1000)
        ]
        if let tokenVersion = token.effectiveTokenVersion {
            tokenData["tokenVersion"] = tokenVersion
        }
        if let updatedAtMs = token.effectiveUpdatedAtMs {
            tokenData["updatedAtMs"] = updatedAtMs
        }
        return tokenData
    }

    private func isTokenUsable(_ token: WatchToken, skewSeconds: TimeInterval = 60) -> Bool {
        token.expiryDate > Date().addingTimeInterval(skewSeconds)
    }

    private func fallbackTokenFromSharedKeychain() -> [String: Any]? {
        guard let token = SharedKeychainManager.shared.loadToken() else {
            return nil
        }
        guard isTokenUsable(token, skewSeconds: 0) else {
            print("[WatchSessionManager] Shared Keychain fallback token is expired, skipping fallback")
            return nil
        }
        return tokenPayload(from: token)
    }

    private func sameTokenPayload(_ lhs: [String: Any], _ rhs: [String: Any]) -> Bool {
        return parseInt64(lhs["studentIdNorm"]) == parseInt64(rhs["studentIdNorm"]) &&
               parseInt64(lhs["expiryDate"]) == parseInt64(rhs["expiryDate"]) &&
               parseInt64(lhs["tokenVersion"]) == parseInt64(rhs["tokenVersion"]) &&
               parseInt64(lhs["updatedAtMs"]) == parseInt64(rhs["updatedAtMs"]) &&
               (lhs["refreshToken"] as? String) == (rhs["refreshToken"] as? String)
    }

    private func tokenPayloadIsUsable(_ tokenData: [String: Any], skewMs: Int64 = 0) -> Bool {
        guard let expiryMs = parseInt64(tokenData["expiryDate"]) else {
            return false
        }
        let nowMs = Int64(Date().timeIntervalSince1970 * 1000)
        return expiryMs > (nowMs + skewMs)
    }

    private func enqueuePendingAuth(_ authData: [String: Any]) {
        pendingAuthQueue.sync {
            if pendingAuthPayloads.contains(where: { sameTokenPayload($0, authData) }) {
                return
            }
            pendingAuthPayloads.append(authData)
            print("[WatchSessionManager] Queued pending token from Watch until Flutter sync is ready")
        }
    }

    private func forwardTokenToFlutter(_ authData: [String: Any]) {
        guard isFlutterWatchSyncReady else {
            enqueuePendingAuth(authData)
            return
        }
        flutterChannel?.invokeMethod("onTokenFromWatch", arguments: authData)
    }

    private func notifyTokenRecoveredToFlutter() {
        guard isFlutterWatchSyncReady else {
            pendingICloudRecoveryNotification = true
            print("[WatchSessionManager] Queued iCloud recovery notification until Flutter sync is ready")
            return
        }
        flutterChannel?.invokeMethod("onTokenRecoveredFromiCloud", arguments: nil)
    }

    private func flushPendingEvents() {
        guard isFlutterWatchSyncReady else {
            return
        }

        let payloadsToFlush: [[String: Any]] = pendingAuthQueue.sync {
            let copy = pendingAuthPayloads
            pendingAuthPayloads.removeAll()
            return copy
        }

        if !payloadsToFlush.isEmpty {
            print("[WatchSessionManager] Flushing \(payloadsToFlush.count) queued token event(s) to Flutter")
        }
        for authData in payloadsToFlush {
            flutterChannel?.invokeMethod("onTokenFromWatch", arguments: authData)
        }

        if pendingICloudRecoveryNotification {
            pendingICloudRecoveryNotification = false
            flutterChannel?.invokeMethod("onTokenRecoveredFromiCloud", arguments: nil)
        }
    }

    private func handleWatchSyncReady(result: @escaping FlutterResult) {
        isFlutterWatchSyncReady = true
        print("[WatchSessionManager] Flutter WatchSync marked as ready")
        flushPendingEvents()
        result(nil)
    }

    private func handleSendTokenToWatch(arguments: Any?, result: @escaping FlutterResult) {
        guard let authData = arguments as? [String: Any] else {
            result(FlutterError(code: "INVALID_ARGS", message: "Arguments must be a dictionary", details: nil))
            return
        }

        guard WCSession.default.isWatchAppInstalled else {
            print("[WatchSessionManager] No paired Watch app, skipping token send")
            result(nil)
            return
        }

        guard WCSession.default.activationState == .activated else {
            result(FlutterError(code: "SESSION_NOT_ACTIVE", message: "WCSession is not activated", details: nil))
            return
        }

        let session = WCSession.default

        mergeApplicationContext(["auth": authData])

        session.transferUserInfo([
            "id": "token_update",
            "auth": authData
        ])

        if session.isReachable {
            session.sendMessage(
                [
                    "id": "token_update",
                    "auth": authData
                ],
                replyHandler: { _ in
                    print("[WatchSessionManager] Token delivered to Watch via sendMessage")
                },
                errorHandler: { error in
                    print("[WatchSessionManager] Failed immediate token send via sendMessage: \(error.localizedDescription)")
                }
            )
        }

        result(nil)
        print("[WatchSessionManager] Token sent to Watch")
    }

    private func handleSendWidgetDataToWatch(arguments: Any?, result: @escaping FlutterResult) {
        guard let jsonString = arguments as? String else {
            result(FlutterError(code: "INVALID_ARGS", message: "Arguments must be a JSON string", details: nil))
            return
        }

        guard WCSession.default.activationState == .activated else {
            result(FlutterError(code: "SESSION_NOT_ACTIVE", message: "WCSession is not activated", details: nil))
            return
        }

        mergeApplicationContext(["widget_data": jsonString])
        result(nil)
        print("[WatchSessionManager] Widget data sent to Watch")
    }

    private func handleSendLanguageToWatch(arguments: Any?, result: @escaping FlutterResult) {
        guard let languageCode = arguments as? String else {
            result(FlutterError(code: "INVALID_ARGS", message: "Language code must be a string", details: nil))
            return
        }

        guard WCSession.default.isWatchAppInstalled else {
            print("[WatchSessionManager] No paired Watch app, skipping language publish")
            result(nil)
            return
        }

        let sharedState = SharedLanguageStateManager.shared.publishState(languageCode: languageCode)

        if WCSession.default.activationState == .activated {
            mergeApplicationContext([
                "language": languageCode,
                "language_state_version": sharedState.stateVersion
            ])
            print("[WatchSessionManager] Language '\(languageCode)' sent to Watch via applicationContext")

            WCSession.default.transferUserInfo([
                "id": "language_update",
                "language": languageCode,
                "language_state_version": sharedState.stateVersion
            ])
        } else {
            print("[WatchSessionManager] WCSession not active, language shared-state published only")
        }
        result(nil)
        print("[WatchSessionManager] Language '\(languageCode)' sent to Watch")
    }

    private func handleNotifyReauthRequired(result: @escaping FlutterResult) {
        guard WCSession.default.activationState == .activated else {
            result(FlutterError(code: "SESSION_NOT_ACTIVE", message: "WCSession is not activated", details: nil))
            return
        }

        WCSession.default.transferUserInfo([
            "id": "reauth_required"
        ])
        result(nil)
        print("[WatchSessionManager] Reauth notification sent to Watch")
    }

    private func handleRequestTokenFromWatch(result: @escaping FlutterResult) {
        guard WCSession.default.activationState == .activated else {
            result(["error": "session_not_active"])
            return
        }

        guard WCSession.default.isReachable else {
            result(["error": "watch_not_reachable"])
            return
        }

        print("[WatchSessionManager] Requesting token from Watch...")

        WCSession.default.sendMessage(
            ["action": "getToken"],
            replyHandler: { response in
                if let tokenData = response["token"] as? [String: Any] {
                    print("[WatchSessionManager] Received token from Watch")
                    result(tokenData)
                } else if let error = response["error"] as? String {
                    print("[WatchSessionManager] Watch returned error: \(error)")
                    result(["error": error])
                } else {
                    result(["error": "no_token"])
                }
            },
            errorHandler: { error in
                print("[WatchSessionManager] Failed to request token from Watch: \(error)")
                result(["error": error.localizedDescription])
            }
        )
    }

    private func handleCheckiCloudToken(result: @escaping FlutterResult) {
        print("[WatchSessionManager] Checking shared Keychain for token...")

        guard let token = SharedKeychainManager.shared.loadToken() else {
            print("[WatchSessionManager] No token in shared Keychain")
            result(["error": "no_token"])
            return
        }

        let formatter = DateFormatter()
        formatter.dateFormat = "HH:mm:ss"
        print("[WatchSessionManager] Found shared Keychain token, expiry: \(formatter.string(from: token.expiryDate))")

        result(tokenPayload(from: token))
    }

    private func handleSaveTokenToiCloud(arguments: Any?, result: @escaping FlutterResult) {
        guard let tokenData = arguments as? [String: Any] else {
            result(FlutterError(code: "INVALID_ARGS", message: "Arguments must be a dictionary", details: nil))
            return
        }

        guard WCSession.default.isWatchAppInstalled else {
            print("[WatchSessionManager] No paired Watch app, skipping token save to shared Keychain")
            result(nil)
            return
        }

        guard let accessToken = tokenData["accessToken"] as? String,
              let refreshToken = tokenData["refreshToken"] as? String,
              let idToken = tokenData["idToken"] as? String,
              let iss = tokenData["iss"] as? String,
              let studentId = tokenData["studentId"] as? String,
              let expiryMs = parseInt64(tokenData["expiryDate"]) else {
            result(FlutterError(code: "INVALID_ARGS", message: "Missing required token fields", details: nil))
            return
        }

        let studentIdNorm = parseInt64(tokenData["studentIdNorm"]) ?? 0
        let expiryDate = Date(timeIntervalSince1970: Double(expiryMs) / 1000.0)
        let tokenVersion = parseInt64(tokenData["tokenVersion"]) ?? WatchToken.extractIatMillis(from: idToken)
        let updatedAtMs = parseInt64(tokenData["updatedAtMs"]) ?? Int64(Date().timeIntervalSince1970 * 1000)

        let token = WatchToken(
            accessToken: accessToken,
            refreshToken: refreshToken,
            idToken: idToken,
            iss: iss,
            studentId: studentId,
            studentIdNorm: studentIdNorm,
            expiryDate: expiryDate,
            tokenVersion: tokenVersion,
            updatedAtMs: updatedAtMs
        )

        let forceAccountSwitch = (tokenData["forceAccountSwitch"] as? Bool) == true
        let didSave = SharedKeychainManager.shared.saveToken(
            token,
            forceAccountSwitch: forceAccountSwitch
        )
        if WCSession.default.isWatchAppInstalled {
            if didSave {
                _ = SharedSessionStateManager.shared.publishState(
                    hasAnyAccount: true,
                    activeStudentIdNorm: studentIdNorm
                )
            } else if SharedKeychainManager.shared.loadToken()?.studentIdNorm == studentIdNorm {
                _ = SharedSessionStateManager.shared.publishState(
                    hasAnyAccount: true,
                    activeStudentIdNorm: studentIdNorm
                )
            } else {
                print("[WatchSessionManager] Token save skipped (stale/cross-account); skipping session-state publish for \(studentIdNorm)")
            }
        }

        let formatter = DateFormatter()
        formatter.dateFormat = "HH:mm:ss"
        print("[WatchSessionManager] Token saved to shared Keychain, expiry: \(formatter.string(from: expiryDate))")

        result(nil)
    }

    private func handleIsWatchAppInstalled(result: @escaping FlutterResult) {
        guard WCSession.isSupported() else {
            result(false)
            return
        }

        let session = WCSession.default
        let installed = session.isPaired && session.isWatchAppInstalled
        result(installed)
    }

    private func handleIsWatchReachable(result: @escaping FlutterResult) {
        guard WCSession.isSupported() else {
            result(false)
            return
        }

        let session = WCSession.default
        let reachable =
            session.isPaired &&
            session.isWatchAppInstalled &&
            session.activationState == .activated &&
            session.isReachable
        result(reachable)
    }

    private func handleClearICloudToken(result: @escaping FlutterResult) {
        SharedKeychainManager.shared.deleteToken()

        SharedKeychainManager.shared.clearKVStore()
        RefreshLeaseManager.shared.clearAllLeases()
        SharedLanguageStateManager.shared.clearState()
        if WCSession.default.isWatchAppInstalled {
            _ = SharedSessionStateManager.shared.publishState(
                hasAnyAccount: false,
                activeStudentIdNorm: nil
            )
        } else {
            SharedSessionStateManager.shared.clearState()
        }
        result(nil)
    }

    private func handleWaitForPeerRefreshLease(arguments: Any?, result: @escaping FlutterResult) {
        guard let args = arguments as? [String: Any],
              let owner = parseLeaseOwner(args["owner"]),
              let studentIdNorm = parseInt64(args["studentIdNorm"]) else {
            result(FlutterError(code: "INVALID_ARGS", message: "Invalid wait lease arguments", details: nil))
            return
        }

        let maxWaitMs = parseInt64(args["maxWaitMs"]) ?? 150_000
        let pollMs = parseInt64(args["pollIntervalMs"]) ?? 250

        if owner == .iphone && !WCSession.default.isWatchAppInstalled {
            result([
                "ready": true,
                "status": "no_watch",
                "waitedMs": 0,
                "leaseChanged": false
            ])
            return
        }

        Task {
            let waitResult = await RefreshLeaseManager.shared.waitForPeerLeaseRelease(
                owner: owner,
                studentIdNorm: studentIdNorm,
                maxWaitMs: maxWaitMs,
                pollIntervalMs: pollMs
            )
            DispatchQueue.main.async {
                result(waitResult.asDictionary())
            }
        }
    }

    private func handleAcquireRefreshLease(arguments: Any?, result: @escaping FlutterResult) {
        guard let args = arguments as? [String: Any],
              let owner = parseLeaseOwner(args["owner"]),
              let studentIdNorm = parseInt64(args["studentIdNorm"]) else {
            result(FlutterError(code: "INVALID_ARGS", message: "Invalid acquire lease arguments", details: nil))
            return
        }

        if owner == .iphone && !WCSession.default.isWatchAppInstalled {
            result([
                "skipped": true,
                "status": "no_watch"
            ])
            return
        }

        let ttlMs = parseInt64(args["ttlMs"]) ?? 120_000
        let operationId = (args["operationId"] as? String) ?? UUID().uuidString
        let lease = RefreshLeaseManager.shared.acquireLease(
            owner: owner,
            studentIdNorm: studentIdNorm,
            ttlMs: ttlMs,
            operationId: operationId
        )
        result([
            "operationId": lease.operationId,
            "startedAtMs": lease.startedAtMs,
            "expiresAtMs": lease.expiresAtMs
        ])
    }

    private func handleReleaseRefreshLease(arguments: Any?, result: @escaping FlutterResult) {
        guard let args = arguments as? [String: Any],
              let owner = parseLeaseOwner(args["owner"]),
              let studentIdNorm = parseInt64(args["studentIdNorm"]) else {
            result(FlutterError(code: "INVALID_ARGS", message: "Invalid release lease arguments", details: nil))
            return
        }
        let operationId = args["operationId"] as? String
        RefreshLeaseManager.shared.releaseLease(
            owner: owner,
            studentIdNorm: studentIdNorm,
            operationId: operationId
        )
        result(nil)
    }

    private func handleClearRefreshLeaseForAccount(arguments: Any?, result: @escaping FlutterResult) {
        guard let args = arguments as? [String: Any],
              let studentIdNorm = parseInt64(args["studentIdNorm"]) else {
            result(FlutterError(code: "INVALID_ARGS", message: "Missing studentIdNorm", details: nil))
            return
        }
        RefreshLeaseManager.shared.clearLeases(studentIdNorm: studentIdNorm)
        result(nil)
    }

    private func handleClearAllRefreshLeases(result: @escaping FlutterResult) {
        RefreshLeaseManager.shared.clearAllLeases()
        result(nil)
    }

    private func handleClearSharedLanguageState(result: @escaping FlutterResult) {
        SharedLanguageStateManager.shared.clearState()
        result(nil)
    }

    private func handleSendLogoutToWatch(result: @escaping FlutterResult) {
        guard WCSession.default.activationState == .activated else {
            result(nil)
            return
        }

        guard WCSession.default.isWatchAppInstalled else {
            result(nil)
            return
        }

        mergeApplicationContext(["force_logout": true])

        WCSession.default.transferUserInfo([
            "id": "force_logout"
        ])
        print("[WatchSessionManager] Force logout sent to Watch")
        result(nil)
    }

    private func handleSendMessageToWatch(arguments: Any?, result: @escaping FlutterResult) {
        guard let message = arguments as? [String: Any] else {
            result(FlutterError(code: "INVALID_ARGS", message: "Arguments must be a dictionary", details: nil))
            return
        }

        guard WCSession.default.activationState == .activated else {
            result(FlutterError(code: "SESSION_NOT_ACTIVE", message: "WCSession is not activated", details: nil))
            return
        }

        guard WCSession.default.isReachable else {
            result(FlutterError(code: "NOT_REACHABLE", message: "Watch is not reachable", details: nil))
            return
        }

        WCSession.default.sendMessage(message, replyHandler: nil, errorHandler: { error in
            print("[WatchSessionManager] Failed to send message to Watch: \(error.localizedDescription)")
        })
        result(nil)
    }

    func session(
        _ session: WCSession,
        activationDidCompleteWith activationState: WCSessionActivationState,
        error: Error?
    ) {
        DispatchQueue.main.async {
            if let error = error {
                print("[WatchSessionManager] Activation error: \(error.localizedDescription)")
            } else {
                print("[WatchSessionManager] Session activated with state: \(activationState.rawValue)")

                if activationState == .activated {
                    let context = session.receivedApplicationContext
                    if let authData = context["auth"] as? [String: Any] {
                        print("[WatchSessionManager] Found pending auth in applicationContext")
                        self.forwardTokenToFlutter(authData)
                    }
                }
            }
        }
    }

    func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String: Any]) {
        print("[WatchSessionManager] Received applicationContext from Watch")
        DispatchQueue.main.async {
            if let authData = applicationContext["auth"] as? [String: Any] {
                print("[WatchSessionManager] Processing auth from applicationContext")
                self.forwardTokenToFlutter(authData)
            }
        }
    }

    func session(
        _ session: WCSession,
        didReceiveMessage message: [String: Any],
        replyHandler: @escaping ([String: Any]) -> Void
    ) {
        DispatchQueue.main.async { [self] in
            self._handleMessageWithReply(message: message, replyHandler: replyHandler)
        }
    }

    private func _handleMessageWithReply(message: [String: Any], replyHandler: @escaping ([String: Any]) -> Void) {
        print("[WatchSessionManager] Received message from Watch: \(message)")

        guard let action = message["action"] as? String else {
            replyHandler(["error": "No action specified"])
            return
        }

        switch action {
        case "requestToken":
            if !self.isFlutterWatchSyncReady {
                if let tokenData = self.fallbackTokenFromSharedKeychain() {
                    print("[WatchSessionManager] Flutter not ready, returning iCloud token to Watch")
                    replyHandler(["auth": tokenData])
                } else {
                    print("[WatchSessionManager] Flutter not ready and no iCloud token available")
                    replyHandler(["error": "no_token"])
                }
                return
            }
            self.flutterChannel?.invokeMethod("getTokenForWatch", arguments: nil) { result in
                    if let tokenData = result as? [String: Any] {
                        if let error = tokenData["error"] as? String {
                            if error == "needsReauth" {
                                print("[WatchSessionManager] Flutter reported needsReauth, not using iCloud fallback")
                                replyHandler(["error": error])
                            } else if let fallbackToken = self.fallbackTokenFromSharedKeychain() {
                                print("[WatchSessionManager] Flutter returned error (\(error)), falling back to iCloud token")
                                replyHandler(["auth": fallbackToken])
                            } else {
                                print("[WatchSessionManager] Flutter returned error: \(error)")
                                replyHandler(["error": error])
                            }
                        } else {
                            guard self.tokenPayloadIsUsable(tokenData) else {
                                print("[WatchSessionManager] Flutter token is expired, refusing to send to Watch")
                                replyHandler(["error": "needsReauth"])
                                return
                            }
                            print("[WatchSessionManager] Sending token to Watch")
                            replyHandler(["auth": tokenData])
                        }
                    } else {
                        if let fallbackToken = self.fallbackTokenFromSharedKeychain() {
                            print("[WatchSessionManager] No Flutter token available, falling back to iCloud token")
                            replyHandler(["auth": fallbackToken])
                        } else {
                            print("[WatchSessionManager] No token available from Flutter")
                            replyHandler(["error": "no_token"])
                        }
                    }
                }

        case "requestLanguage":
            if !self.isFlutterWatchSyncReady {
                if let sharedState = SharedLanguageStateManager.shared.loadState() {
                    print("[WatchSessionManager] Flutter not ready for language request, serving shared language: \(sharedState.languageCode)")
                    replyHandler([
                        "language": sharedState.languageCode,
                        "language_state_version": sharedState.stateVersion
                    ])
                } else {
                    print("[WatchSessionManager] Flutter not ready for language request and no shared language is available")
                    replyHandler(["error": "language_not_ready"])
                }
                return
            }

            guard let flutterChannel = self.flutterChannel else {
                if let sharedState = SharedLanguageStateManager.shared.loadState() {
                    print("[WatchSessionManager] Flutter channel missing for language request, serving shared language: \(sharedState.languageCode)")
                    replyHandler([
                        "language": sharedState.languageCode,
                        "language_state_version": sharedState.stateVersion
                    ])
                } else {
                    print("[WatchSessionManager] Flutter channel missing for language request and no shared language is available")
                    replyHandler(["error": "language_not_ready"])
                }
                return
            }

            var hasReplied = false
            let timeoutWorkItem = DispatchWorkItem {
                guard !hasReplied else { return }
                hasReplied = true
                if let sharedState = SharedLanguageStateManager.shared.loadState() {
                    print("[WatchSessionManager] Flutter timeout, serving shared language: \(sharedState.languageCode)")
                    replyHandler([
                        "language": sharedState.languageCode,
                        "language_state_version": sharedState.stateVersion
                    ])
                } else {
                    print("[WatchSessionManager] Flutter timeout and no shared language available")
                    replyHandler(["error": "timeout"])
                }
            }
            DispatchQueue.main.asyncAfter(deadline: .now() + 5.0, execute: timeoutWorkItem)

            flutterChannel.invokeMethod("getLanguageForWatch", arguments: nil) { result in
                timeoutWorkItem.cancel()
                guard !hasReplied else { return }
                hasReplied = true

                if let languageCode = result as? String, !languageCode.isEmpty {
                    if let existingState = SharedLanguageStateManager.shared.loadState(),
                       existingState.languageCode == languageCode {
                        print("[WatchSessionManager] Sending language to Watch from shared cache: \(languageCode)")
                        replyHandler([
                            "language": languageCode,
                            "language_state_version": existingState.stateVersion
                        ])
                        return
                    }

                    let sharedState = SharedLanguageStateManager.shared.publishState(
                        languageCode: languageCode
                    )
                    print("[WatchSessionManager] Sending language to Watch: \(languageCode)")
                    replyHandler([
                        "language": languageCode,
                        "language_state_version": sharedState.stateVersion
                    ])
                } else if let sharedState = SharedLanguageStateManager.shared.loadState() {
                    print("[WatchSessionManager] No language from Flutter, serving last shared language: \(sharedState.languageCode)")
                    replyHandler([
                        "language": sharedState.languageCode,
                        "language_state_version": sharedState.stateVersion
                    ])
                } else {
                    print("[WatchSessionManager] No language available from Flutter or shared state")
                    replyHandler(["error": "language_not_ready"])
                }
            }

        case "receiveTokenFromWatch":
            guard let tokenData = message["token"] as? [String: Any] else {
                replyHandler(["error": "no_token_data"])
                return
            }

            if !self.isFlutterWatchSyncReady {
                print("[WatchSessionManager] Flutter not ready, queueing token from Watch")
                self.enqueuePendingAuth(tokenData)
                replyHandler(["success": true])
                return
            }

            print("[WatchSessionManager] Receiving token from Watch")
            self.flutterChannel?.invokeMethod("onTokenFromWatch", arguments: tokenData) { result in
                if let success = result as? Bool, success {
                    print("[WatchSessionManager] Flutter accepted Watch token")
                    replyHandler(["success": true])
                } else if let resultDict = result as? [String: Any],
                          let success = resultDict["success"] as? Bool, success {
                    print("[WatchSessionManager] Flutter accepted Watch token")
                    replyHandler(["success": true])
                } else {
                    print("[WatchSessionManager] Flutter rejected Watch token")
                    replyHandler(["error": "rejected"])
                }
            }

        default:
            replyHandler(["error": "Unknown action: \(action)"])
        }
    }

    func session(_ session: WCSession, didReceiveMessage message: [String: Any]) {
        print("[WatchSessionManager] Received fire-and-forget message from Watch: \(message)")
        DispatchQueue.main.async {
            self.flutterChannel?.invokeMethod("onWatchMessage", arguments: message)
        }
    }

    func sessionDidBecomeInactive(_ session: WCSession) {
        print("[WatchSessionManager] Session did become inactive")
    }

    func sessionDidDeactivate(_ session: WCSession) {
        print("[WatchSessionManager] Session did deactivate, reactivating...")
        if WCSession.isSupported() {
            WCSession.default.activate()
        }
    }

    func session(
        _ session: WCSession,
        didReceiveUserInfo userInfo: [String : Any] = [:]
    ) {
        DispatchQueue.main.async {
            guard let messageId = userInfo["id"] as? String else {
                return
            }

            if messageId == "token_update_from_watch" {
                if let authData = userInfo["auth"] as? [String: Any] {
                    self.forwardTokenToFlutter(authData)
                    print("[WatchSessionManager] Token received from Watch")
                }
            }
        }
    }

    func sessionWatchStateDidChange(_ session: WCSession) {
        DispatchQueue.main.async {
            if session.isWatchAppInstalled {
                self.flutterChannel?.invokeMethod("watchAppInstalled", arguments: nil)
                print("[WatchSessionManager] Watch app installed detected")
            } else {
                print("[WatchSessionManager] Watch app not installed")
            }
        }
    }
}
