/**
 * useExitInterstitial — counts native-player exits and shows an AdMob
 * interstitial every Nth time the user comes back to the main menu.
 *
 * Wired up exactly once at app root (see `App.tsx`). It does NOT render
 * anything; it just attaches a listener to the `NativePlayer` plugin
 * for the `playerExited` event (fired from
 * {@code PlayerActivity.teardownPlayback}) and reacts.
 *
 * Counter persistence:
 *   • Stored in localStorage under `nadi_player_exit_count` so it
 *     survives full process kills. Bumped to a fresh value on every
 *     exit event, including those for premium users (so the cadence
 *     stays predictable if the user later loses premium).
 *
 * Suppression rules (all checked in this order):
 *   1. Non-native runtime (web / desktop preview) — no AdMob at all.
 *   2. User has an active ad-free entitlement (premium or rewarded
 *      unlock) — `useEntitlement().adsEnabled === false`.
 *   3. Counter % `everyN` !== 0 — not yet the Nth exit.
 *
 * When all three pass we call `showInterstitialNow()`. The function
 * returns a boolean we ignore here — the in-app fallback overlay
 * (already wired in `lib/admob.ts`) handles "ad failed to load".
 *
 * Iter-6 feature (2026-01).
 */
import { useEffect, useRef } from "react";
import { Capacitor } from "@capacitor/core";
import { NativePlayer } from "@/native/nativePlayer";
import { useEntitlement } from "@/hooks/useEntitlement";
import { showInterstitialNow, prepareInterstitial } from "@/lib/admob";

const LS_KEY = "nadi_player_exit_count";

interface Options {
  /** Fire an interstitial every {@code everyN}th exit (default 3). */
  everyN?: number;
}

function readCount(): number {
  try {
    const v = parseInt(localStorage.getItem(LS_KEY) ?? "0", 10);
    return Number.isFinite(v) && v >= 0 ? v : 0;
  } catch {
    return 0;
  }
}

function writeCount(n: number): void {
  try { localStorage.setItem(LS_KEY, String(n)); } catch { /* SSR / quota */ }
}

export function useExitInterstitial({ everyN = 3 }: Options = {}): void {
  const { adsEnabled } = useEntitlement();
  // Latest entitlement value, read inside the listener closure.
  // Using a ref avoids re-attaching the native listener on every
  // entitlement refresh (which would briefly lose events).
  const adsEnabledRef = useRef(adsEnabled);
  useEffect(() => { adsEnabledRef.current = adsEnabled; }, [adsEnabled]);

  useEffect(() => {
    if (!Capacitor.isNativePlatform()) return;

    let cancelled = false;
    let handle: { remove?: () => void } | null = null;

    (async () => {
      // Warm up the interstitial slot so the Nth exit feels instant.
      // The plugin caches the prepared ad — we only need to nudge it
      // once on mount; future fires happen via the showInterstitialNow
      // ⇒ prepareInterstitial chain inside admob.ts.
      try { await prepareInterstitial(); } catch { /* config not loaded yet — fine */ }

      try {
        const h = await NativePlayer.addListener("playerExited", () => {
          // (1) Bump the persistent counter on EVERY exit (so the
          //     cadence stays predictable across premium loss/gain).
          const next = readCount() + 1;
          writeCount(next);

          // (2) Premium / rewarded ad-free users: nothing else to do.
          if (!adsEnabledRef.current) return;

          // (3) Only the Nth exit fires an interstitial.
          if (next % everyN !== 0) {
            // Pre-warm the next ad slot so the upcoming Nth tap is
            // ready. Best-effort, no await.
            void prepareInterstitial();
            return;
          }

          // (4) Fire-and-forget. Failure is handled inside admob.ts.
          console.log(
            `[useExitInterstitial] exit #${next} — firing interstitial`,
          );
          void showInterstitialNow();
        });
        if (cancelled) {
          h.remove?.();
        } else {
          handle = h;
        }
      } catch (e) {
        console.warn("[useExitInterstitial] addListener failed:", e);
      }
    })();

    return () => {
      cancelled = true;
      try { handle?.remove?.(); } catch { /* ignore */ }
    };
  }, [everyN]);
}
