import { useEffect } from 'react'
import { Platform } from 'react-native'
import { watchEvents } from 'react-native-watch-connectivity'
import { devlog } from 'src/lib/devnet/log'
import { AccountStore } from 'src/state/accountStore'
import { enableWatchHandoff, pushActiveHandoff } from './handoff'

// Renderless effect-only bridge. Wires the WCSession listeners once and
// pushes the active account's handoff payload to the watch on the
// events that should rotate the watch's view of "current account":
//
//   - Boot — unconditional re-push; the persisted MMKV signature only
//     proves the previous process _attempted_ a push, not that the
//     watch currently holds the payload. A watch reinstall or app-group
//     wipe between processes silently starves the complication unless
//     this fires regardless of signature match — `'boot'` is in
//     `BYPASS_DEDUPE_REASONS` in handoff.ts.
//
//   - AccountStore mutation (login complete, switch, sign-out fallback,
//     soft-delete revival, profile-blob update, …) — every signal that
//     mutates `(activeAccountId, AccountSummary, accessToken)` is
//     funnelled through `AccountStore.subscribe` already; piggy-backing
//     on it gives us all of "login → push", "switch → push", "remove
//     active → push fallback" without per-call wiring.
//
//   - watchEvents `installed` flipping true — the user just installed the
//     Halflight Watch app from the iPhone Watch app, and we want it to
//     pick up the active handoff immediately rather than waiting for the
//     next account-store mutation.
//
//   - watchEvents `reachability` flipping true — a previously unreachable
//     updateApplicationContext should already be queued by WC, but a
//     fresh push refreshes `issuedAt` so the watch's "Updated Nm ago"
//     stays correct after the watch comes back into range.
//
// AppState 'active' (foreground) was previously a fifth trigger but
// fires on every trivial transition (incoming call, control centre,
// notification shade) — pure noise once the AccountStore subscription
// covers token rotation and reachability covers wake-from-asleep.
// Token-refresh and sign-out have explicit hooks at their call sites
// (`pushHandoffForAccount`, `revokeOnWatch`, `revokeAllOnWatch`)
// because the AccountStore subscription can't see "the keychain
// rotated but no registry field changed" or "this revoke must reach
// the watch even though the account is already gone from the
// registry". Mount once at the top of the tree alongside the other
// service bridges; renders nothing.

export default function WatchHandoffBridge() {
  useEffect(() => {
    if (Platform.OS !== 'ios') return
    enableWatchHandoff()
    devlog.wc('bridge mount')
    // Initial push — `'boot'` is in BYPASS_DEDUPE_REASONS so this
    // always fires a real bridge round-trip on cold launch, even when
    // the persisted MMKV signature matches the current credentials.
    // The persisted signature only proves a prior process attempted a
    // push; it can't see a watch reinstall or app-group wipe between
    // processes.
    pushActiveHandoff('boot')

    const unsubAccount = AccountStore.subscribe(() => {
      pushActiveHandoff('account-store-change')
    })

    const unsubInstalled = watchEvents.addListener('installed', (installed) => {
      devlog.wc(`watch-installed=${installed}`)
      if (installed) pushActiveHandoff('watch-installed')
    })
    const unsubReach = watchEvents.addListener('reachability', (reachable) => {
      devlog.wc(`watch-reachable=${reachable}`)
      if (reachable) pushActiveHandoff('watch-reachable')
    })

    return () => {
      unsubAccount()
      unsubInstalled()
      unsubReach()
    }
  }, [])

  return null
}
