/**
 * Entitlement context — single source of truth for ad-gating + lock UI.
 *
 * Logic (per product brief, May 2026):
 *   • GUEST (not logged-in) → free forever; ads governed by admin
 *     `ads_enabled_for_guests` toggle (defaults ON when ads_enabled).
 *   • LOGGED-IN with days_remaining > 0 → premium subscriber. Ads
 *     governed by admin `ads_enabled_for_users` toggle (defaults OFF).
 *   • LOGGED-IN with days_remaining = 0 / expired → ads ON via the
 *     `ads_enabled_for_users` toggle, redirected to /trial-expired.
 *   • ADMIN → ads OFF, never gated.
 *
 * Per-user override (`user.ads_enabled` boolean) still takes priority
 * over the global toggles — admins can force a specific account ON or
 * OFF from the Subscriber edit card.
 *
 * BUG-2 FIX (2026-05): the previous policy auto-disabled ads for ANY
 * "premium" user, which meant admins could not enable ads for the
 * Users segment as a whole — only per-user. The new
 * `ads_enabled_for_users` / `ads_enabled_for_guests` flags fix that
 * by giving admins a global Users-vs-Guests switch.
 */

import { createContext, useContext, useMemo, type ReactNode } from "react";
import { useAuth } from "@/hooks/useAuth";
import { useTrialStatus, type TrialStatus } from "@/hooks/useTrialStatus";
import { useAdsPolicy } from "@/hooks/useAdsPolicy";
import { isSmartTV } from "@/lib/platform";

type EntitlementState = {
  trial: TrialStatus | null;
  trialLoading: boolean;
  trialError: string | null;
  /** Logged-in user has an ACTIVE paid subscription (days_remaining > 0). */
  userIsPremium: boolean;
  /** Logged-in user but their paid subscription has hit 0 days. */
  userExpired: boolean;
  /** Premium = active paid OR admin OR device-flagged premium. */
  isPremium: boolean;
  /** Days remaining on the current paid subscription, or null for guests. */
  daysRemaining: number | null;
  /** ISO date when the subscription expires, or null. */
  expiryAt: string | null;
  /** True ONLY for logged-in users whose subscription has expired (renewal prompt). */
  showRenewalPrompt: boolean;
  /**
   * TV-only guest lockout. True when ALL of:
   *   - Running on Samsung Tizen or LG webOS
   *   - Visitor is NOT logged in (guest mode)
   *   - Device-level 15-day trial has expired AND device is not premium
   * Admins, logged-in premium users, Android phones and web visitors
   * never trigger this flag.
   */
  tvGuestLocked: boolean;
  /** Whether AdMob banners + interstitials should be served right now. */
  adsEnabled: boolean;
  refreshTrial: () => Promise<void>;
};

const Ctx = createContext<EntitlementState | undefined>(undefined);

export function EntitlementProvider({ children }: { children: ReactNode }) {
  const { user, isGuest } = useAuth();
  const { trial, loading: trialLoading, error: trialError, refresh: refreshTrial } =
    useTrialStatus();
  // BUG-2 FIX (2026-05) — pull the admin-controlled Users-vs-Guests
  // toggles from /api/public/ad-config. These default to the legacy
  // behaviour (guests=on, users=off) when the backend hasn't been
  // upgraded yet, so existing deployments keep working unchanged.
  const adsPolicy = useAdsPolicy();

  const value = useMemo<EntitlementState>(() => {
    const isAdmin = user?.role === "admin";
    const isLoggedIn = !!user;
    const daysRemaining = user?.days_remaining ?? null;
    const expiryAt = user?.expiry_at ?? null;
    const userIsPremium =
      isLoggedIn && !isAdmin && daysRemaining !== null && daysRemaining > 0;
    const userExpired =
      isLoggedIn && !isAdmin && daysRemaining !== null && daysRemaining <= 0;

    const devicePremium = !!trial?.is_premium;
    const isPremium = isAdmin || userIsPremium || devicePremium;

    // BUG-5 FEATURE (2026-05): honour the rewarded-ads "watch N ads
    // → unlock M hours ad-free" window. We trust EITHER the
    // server-issued `user.ad_free_until` (logged-in) OR the local
    // `nadi_ad_free_until` from localStorage (guests). Whichever is
    // further in the future wins, so logging in mid-window doesn't
    // shorten the unlock.
    let adFreeUntilMs = 0;
    if (user?.ad_free_until) {
      const t = Date.parse(user.ad_free_until);
      if (Number.isFinite(t)) adFreeUntilMs = Math.max(adFreeUntilMs, t);
    }
    try {
      const ls = typeof window !== "undefined"
        ? window.localStorage.getItem("nadi_ad_free_until")
        : null;
      if (ls) {
        const t = Date.parse(ls);
        if (Number.isFinite(t)) adFreeUntilMs = Math.max(adFreeUntilMs, t);
      }
    } catch { /* SSR / private mode */ }
    const adFreeActive = adFreeUntilMs > Date.now();

    // ── Ads policy (priority order) ──
    //   1. Admin user → NEVER show ads.
    //   2. Per-user override (`user.ads_enabled` boolean) set explicitly
    //      by the admin on the Subscriber edit card:
    //        true  → force ADS ON (regardless of global flags)
    //        false → force ADS OFF (e.g. comp / VIP accounts)
    //   3. GLOBAL master toggle (`adsPolicy.globalEnabled`) → if false,
    //      no one sees ads.
    //   4. Logged-in user → governed by `ads_enabled_for_users` flag.
    //      BUG-2 FIX: previously this branch auto-disabled ads for
    //      premium users; now an admin can switch them on via the
    //      Users-vs-Guests toggle.
    //   5. Guest → governed by `ads_enabled_for_guests` flag.
    let adsEnabled: boolean;
    if (isAdmin) {
      adsEnabled = false;
    } else if (adFreeActive) {
      // BUG-5 FEATURE (2026-05): user is inside the rewarded-unlock
      // window — suppress ALL ads regardless of any other flag.
      adsEnabled = false;
    } else if (isLoggedIn && typeof user?.ads_enabled === "boolean") {
      adsEnabled = user.ads_enabled;
    } else if (!adsPolicy.globalEnabled) {
      adsEnabled = false;
    } else if (isLoggedIn) {
      adsEnabled = adsPolicy.enabledForUsers;
    } else {
      adsEnabled = adsPolicy.enabledForGuests;
    }

    return {
      trial,
      trialLoading,
      trialError,
      userIsPremium,
      userExpired,
      isPremium,
      daysRemaining,
      expiryAt,
      // Only logged-in users see the renewal prompt; guests are never gated.
      showRenewalPrompt: userExpired,
      // TV-only guest lockout. The lock screen overlay (TVGuestLockOverlay)
      // checks this flag and renders ABOVE every page. Premium / admin /
      // mobile / web are never gated here.
      tvGuestLocked:
        isSmartTV() &&
        !isAdmin &&
        (isGuest || !isLoggedIn) &&
        !devicePremium &&
        !!trial?.trial_expired,
      adsEnabled,
      refreshTrial,
    };
  }, [user, isGuest, trial, trialLoading, trialError, refreshTrial, adsPolicy]);

  return <Ctx.Provider value={value}>{children}</Ctx.Provider>;
}

export function useEntitlement(): EntitlementState {
  const v = useContext(Ctx);
  if (!v) throw new Error("useEntitlement must be used inside <EntitlementProvider>");
  return v;
}
