/**
 * App-side push notifications.
 *
 * The native push plugin (FCM on Android / APNs on iOS) obtains the device
 * token and either caches it in the secure store under "push_token" or emits a
 * `ulti://push-token` event. After login we register it with the backend; on
 * logout we unregister it.
 *
 * Backend contract:
 *   POST /api/v1/devices/register   { platform, app, push_token, device_id? } -> { id }
 *   POST /api/v1/devices/unregister { push_token }
 */
import { apiClient } from "@/lib/api/client"
import { invoke, listen } from "@/lib/native/bridge"
import { isTauriRuntime, SUITE_APP } from "@/lib/platform"
import { readPushToken, writePushToken } from "@/lib/native/secure-store"

type PushRegistration = { platform: string; token: string | null }

function normalizePlatform(os: string): "ios" | "android" | null {
  if (os === "ios") return "ios"
  if (os === "android") return "android"
  return null
}

let started = false

async function registerToken(platform: "ios" | "android", token: string) {
  await writePushToken(token)
  await apiClient.post<{ id: string }>("/devices/register", {
    platform,
    app: SUITE_APP,
    push_token: token,
  })
}

/**
 * Call after a successful login. Idempotent. Asks the native layer for the push
 * token and registers it; also subscribes to late token deliveries.
 */
export async function registerPushAfterLogin(): Promise<void> {
  if (!isTauriRuntime()) return

  // Late token delivery (e.g. permission granted after first launch).
  if (!started) {
    started = true
    await listen("ulti://push-token", (payload) => {
      const token = typeof payload === "string" ? payload : null
      const platform = normalizePlatform(
        (navigator?.platform || "").toLowerCase().includes("android")
          ? "android"
          : "ios"
      )
      if (token && platform) void registerToken(platform, token)
    })
  }

  try {
    const reg = await invoke<PushRegistration>("plugin:ulti-core|push_register")
    if (!reg) return
    const platform = normalizePlatform(reg.platform)
    if (platform && reg.token) {
      await registerToken(platform, reg.token)
    }
  } catch {
    /* push optional — never block login */
  }
}

/** Call before clearing the session. */
export async function unregisterPushOnLogout(): Promise<void> {
  if (!isTauriRuntime()) return
  try {
    const token = await readPushToken()
    if (token) {
      await apiClient.post("/devices/unregister", { push_token: token })
    }
  } catch {
    /* best effort */
  }
}
