import { useQuery } from '@tanstack/react-query';
import { parseMhCookieRaw } from '@/lib/mh-cookie';
import { captureCaught } from '@/lib/observability';
import { getCsrfToken } from '@/lib/csrf';
import { qk } from '@/lib/query/keys';
import { fetchWithRefresh } from '@/lib/api/refresh-on-401';

export interface MhPageData {
  wishlist?: string[];
  favoriteVendors?: string[];
  cart: { count: number; subtotal: number };
  recs?: unknown[];
  recentlyViewed?: string[];
  savedFilters?: unknown[];
  /** Email-verification banner payload for unverified logged-in users (null otherwise). */
  ev?: { email: string; emailVerifiedAt: string | null } | null;
  /** Onboarding-sheet payload when user hasn't completed onboarding on an eligible route. */
  onboarding?: { required: boolean; emailVerifiedFlag: boolean } | null;
}

const SESSION_TTL_MS = 300_000;
const SESSION_KEY_PREFIX = 'mh-page:';

interface SessionSeed {
  data: MhPageData;
  ts: number;
}

/** Read mhv from the `mh` cookie so cached entries invalidate on auth mutations. */
function readMhv(): string {
  if (typeof document === 'undefined') return '';
  const rawMhCookie = document.cookie.match(/(?:^|;\s*)mh=([^;]+)/)?.[1] ?? '';
  if (!rawMhCookie) return '';
  const payload = parseMhCookieRaw(rawMhCookie);
  // mhVersion counter (.c field) — invalidates sessionStorage seeds on auth mutations.
  return typeof payload?.c === 'number' ? String(payload.c) : '';
}

function readSessionSeed(route: string): SessionSeed | undefined {
  if (typeof sessionStorage === 'undefined') return undefined;
  try {
    const raw = sessionStorage.getItem(`${SESSION_KEY_PREFIX}${readMhv()}:${route}`);
    if (!raw) return undefined;
    const parsed = JSON.parse(raw) as SessionSeed;
    if (Date.now() - parsed.ts > SESSION_TTL_MS) return undefined;
    return parsed;
  } catch (err) {
    captureCaught(err, {
      scope: 'lib.hooks.usePersonalization.readSessionSeed',
      severity: 'info',
    });
    return undefined;
  }
}

function writeSessionSeed(route: string, data: MhPageData): void {
  if (typeof sessionStorage === 'undefined') return;
  try {
    sessionStorage.setItem(
      `${SESSION_KEY_PREFIX}${readMhv()}:${route}`,
      JSON.stringify({ ts: Date.now(), data } satisfies SessionSeed),
    );
  } catch (err) {
    // QuotaExceeded or storage disabled — non-fatal, hook still works without seed.
    captureCaught(err, {
      scope: 'lib.hooks.usePersonalization.writeSessionSeed',
      severity: 'info',
    });
  }
}

export function usePersonalization(route: string) {
  const enabled =
    typeof document !== 'undefined' && document.documentElement.dataset.auth === 'user';

  return useQuery<MhPageData>({
    queryKey: qk.mhPage(route),
    enabled,
    staleTime: SESSION_TTL_MS,
    initialData: () => readSessionSeed(route)?.data,
    initialDataUpdatedAt: () => readSessionSeed(route)?.ts,
    queryFn: async () => {
      const res = await fetchWithRefresh('/api/me/page-data', {
        method: 'POST',
        body: JSON.stringify({ route }),
        credentials: 'include',
        headers: {
          'Content-Type': 'application/json',
          'x-csrf-token': getCsrfToken(),
        },
      });
      if (!res.ok) throw new Error(`/api/me/page-data ${res.status}`);
      const data = (await res.json()) as MhPageData;
      writeSessionSeed(route, data);
      return data;
    },
  });
}
