import SwiftUI

// Cross-target notification posted by every deep-link handoff path so
// `RootView` can react in one place. The three SwiftUI / delegate
// hooks (`.onContinueUserActivity`, `.onOpenURL`,
// `WatchAppDelegate.handle(_ userActivity:)`) all post this — Apple's
// docs are ambiguous about which fires for watchOS widgetURL taps,
// so we wire all three and let whichever runs land us on Feed.
extension Notification.Name {
    static let halflightOpenFeed = Notification.Name("ht.halflig.app.openFeed")
}

@main
struct HalflightWatchApp: App {
    @StateObject private var auth = AuthState()
    // The delegate adaptor receives `WKApplicationRefreshBackgroundTask`
    // wakeups for the complication's 20-min refresh chain. SwiftUI's
    // App protocol has no equivalent hook on its own — the delegate is
    // the only path to `handle(_:)` on watchOS.
    @WKApplicationDelegateAdaptor(WatchAppDelegate.self) private var appDelegate

    var body: some Scene {
        WindowGroup {
            RootView()
                .environmentObject(auth)
                .onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { activity in
                    // `widgetURL(_:)` on the complication delivers
                    // the URL as a web-browsing NSUserActivity. The
                    // `webpageURL` carries the original
                    // `halflight://watch/feed` value.
                    if let url = activity.webpageURL {
                        DeepLink.route(url)
                    }
                }
                .onOpenURL { url in
                    // Belt-and-suspenders — multiple Apple Developer
                    // Forum reports say `.onOpenURL` doesn't fire on
                    // watchOS for widget taps, but if a future OS
                    // revision starts honoring it we catch the URL
                    // here too. Idempotent against the activity path
                    // — both routes funnel into the same notification.
                    DeepLink.route(url)
                }
                .task {
                    // Wire the WCSession delegate once, with a live
                    // ref to the AuthState so inbound application-
                    // context payloads + revoke messages can mutate
                    // it on the main actor. Idempotent — repeat
                    // .task firings (every RootView appearance) are
                    // no-ops after the first activation.
                    WatchSession.shared.activate(auth: auth)
                    // Kick the background-refresh chain. If a previously
                    // scheduled task was dropped during a long suspension,
                    // this re-arms it; if one is already pending, the
                    // OS coalesces and this is a no-op.
                    BackgroundRefresh.scheduleNext()
                }
        }
    }
}

// Single funnel for deep-link URLs delivered by any of the three
// handoff hooks. Today the only recognized path is
// `halflight://watch/feed` (the Latest Media complication's
// `widgetURL`); future widgets can extend this enum without touching
// the three call sites.
enum DeepLink {
    static func route(_ url: URL) {
        guard url.scheme == "halflight" else { return }
        // `host` for `halflight://watch/feed` is "watch"; the path
        // is "/feed". Match on both so a stray `halflight://feed`
        // (no `watch` host) still lands the user on Feed rather
        // than being silently ignored.
        let host = url.host ?? ""
        let path = url.path
        if host == "watch" && path.hasPrefix("/feed") {
            NotificationCenter.default.post(name: .halflightOpenFeed, object: url)
            return
        }
        if host == "feed" || path.hasPrefix("/feed") {
            NotificationCenter.default.post(name: .halflightOpenFeed, object: url)
        }
    }
}
