//
//  WatchConnectivityManager.swift
//  Reflect
//
//  Central coordinator for Watch Connectivity.
//  Used for immediate UI updates (Live Activity, widget refresh).
//  Data persistence is handled by CloudKit sync.
//

import Foundation
import WatchConnectivity
import WidgetKit
import os.log

/// Manages Watch Connectivity between iOS and watchOS
/// Used for immediate notifications, not data persistence (CloudKit handles that)
final class WatchConnectivityManager: NSObject, ObservableObject {

    static let shared = WatchConnectivityManager()

    private static let logger = Logger(subsystem: "com.88oakapps.reflect", category: "WatchConnectivity")

    private var session: WCSession?

    #if os(watchOS)
    /// Pending moods to send when session activates
    private var pendingMoods: [(mood: Int, date: Date)] = []
    #endif

    /// Whether the paired device is currently reachable for immediate messaging
    var isReachable: Bool {
        session?.isReachable ?? false
    }

    private override init() {
        super.init()

        if WCSession.isSupported() {
            session = WCSession.default
            session?.delegate = self
            session?.activate()
            Self.logger.info("WCSession activation requested")
        } else {
            Self.logger.warning("WCSession not supported on this device")
        }
    }

    // MARK: - iOS → Watch

    #if os(iOS)
    /// Notify watch to reload its complications
    func notifyWatchToReload() {
        guard let session = session,
              session.activationState == .activated,
              session.isWatchAppInstalled else {
            return
        }

        let message = ["action": "reloadWidgets"]
        session.transferUserInfo(message)
        Self.logger.info("Sent reload notification to watch")
    }
    #endif

    // MARK: - Watch → iOS

    #if os(watchOS)
    /// Send mood to iOS app for immediate side effects (Live Activity, etc.)
    /// Data persistence is handled by CloudKit - this is just for immediate UI updates
    func sendMoodToPhone(mood: Int, date: Date) -> Bool {
        guard let session = session else {
            Self.logger.warning("WCSession not ready - session is nil")
            return false
        }

        guard session.activationState == .activated else {
            pendingMoods.append((mood: mood, date: date))
            if session.activationState == .notActivated {
                session.activate()
            }
            Self.logger.warning("WCSession not activated, queued mood for later")
            return false
        }

        let message: [String: Any] = [
            "action": "logMood",
            "mood": mood,
            "date": date.timeIntervalSince1970
        ]

        // Try immediate message first if iPhone is reachable
        if session.isReachable {
            session.sendMessage(message, replyHandler: nil) { error in
                Self.logger.warning("sendMessage failed: \(error.localizedDescription), using transferUserInfo")
                session.transferUserInfo(message)
            }
            Self.logger.info("Sent mood \(mood) to iPhone via sendMessage")
        } else {
            session.transferUserInfo(message)
            Self.logger.info("Sent mood \(mood) to iPhone via transferUserInfo")
        }
        return true
    }
    #endif
}

// MARK: - WCSessionDelegate

extension WatchConnectivityManager: WCSessionDelegate {

    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        if let error = error {
            Self.logger.error("WCSession activation failed: \(error.localizedDescription)")
        } else {
            Self.logger.info("WCSession activation completed: \(activationState.rawValue)")

            #if os(watchOS)
            if activationState == .activated && !pendingMoods.isEmpty {
                Self.logger.info("Sending \(self.pendingMoods.count) pending mood(s)")
                for pending in pendingMoods {
                    _ = sendMoodToPhone(mood: pending.mood, date: pending.date)
                }
                pendingMoods.removeAll()
            }
            #endif
        }
    }

    #if os(iOS)
    func sessionDidBecomeInactive(_ session: WCSession) {
        Self.logger.info("WCSession became inactive")
    }

    func sessionDidDeactivate(_ session: WCSession) {
        Self.logger.info("WCSession deactivated, reactivating...")
        session.activate()
    }

    func session(_ session: WCSession, didReceiveUserInfo userInfo: [String: Any] = [:]) {
        Self.logger.info("Received userInfo from watch")
        handleReceivedMessage(userInfo)
    }

    func session(_ session: WCSession, didReceiveMessage message: [String: Any]) {
        Self.logger.info("Received message from watch")
        handleReceivedMessage(message)
    }

    func session(_ session: WCSession, didReceiveMessage message: [String: Any], replyHandler: @escaping ([String: Any]) -> Void) {
        Self.logger.info("Received message from watch (with reply)")
        handleReceivedMessage(message)
        replyHandler(["status": "received"])
    }

    private func handleReceivedMessage(_ message: [String: Any]) {
        Task { @MainActor in
            guard let action = message["action"] as? String else {
                Self.logger.error("No action in message")
                return
            }

            switch action {
            case "logMood":
                guard let moodRaw = message["mood"] as? Int,
                      let mood = Mood(rawValue: moodRaw),
                      let timestamp = message["date"] as? TimeInterval else {
                    Self.logger.error("Invalid mood message format")
                    return
                }

                let date = Date(timeIntervalSince1970: timestamp)
                Self.logger.info("Processing mood \(moodRaw) from watch for \(date)")
                MoodLogger.shared.logMood(mood, for: date, entryType: .watch)

            case "reloadWidgets":
                Self.logger.info("Received reloadWidgets from watch")
                WidgetCenter.shared.reloadAllTimelines()

            default:
                Self.logger.warning("Unknown action: \(action)")
            }
        }
    }
    #endif

    #if os(watchOS)
    func session(_ session: WCSession, didReceiveUserInfo userInfo: [String: Any] = [:]) {
        if userInfo["action"] as? String == "reloadWidgets" {
            Self.logger.info("Received reload notification from iPhone")
            Task { @MainActor in
                WidgetCenter.shared.reloadAllTimelines()
            }
        }
    }

    func session(_ session: WCSession, didReceiveMessage message: [String: Any]) {
        if message["action"] as? String == "reloadWidgets" {
            Task { @MainActor in
                WidgetCenter.shared.reloadAllTimelines()
            }
        }
    }
    #endif
}
