import { useEffect, useState } from 'react';
import { apiFetch } from '../lib/api';

export type Plan = 'free' | 'pro' | 'legend';

/**
 * Single source of truth für den eingeloggten User. /api/auth/me joint
 * `auth.users` mit `rebreak.profiles` server-side — wir bekommen alles in
 * einem Request: plan, avatar, nickname, streak.
 *
 * Live-Update-Pattern (siehe RECOVERY_LOG): nach Profile-Edit (PATCH /api/auth/me)
 * MUSS `invalidateMe()` aufgerufen werden — alle useMe-Konsumenten (AppHeader,
 * PostCard, ComposeCard, etc.) re-fetchen automatisch via Listener-Subscribe.
 *
 * WICHTIG: nicht aus `supabase.auth.getUser().user_metadata` lesen — das
 * sind nur die JWT-Claims vom Signup-Zeitpunkt, NICHT der aktuelle Profile-
 * Stand (Avatar/Nickname/Plan werden via Profile-Edit-API geupdated, landen
 * in der DB, NICHT zurück ins JWT-Claim).
 */
export type OnboardingStep =
  | 'welcome'
  | 'account'
  | 'plan'
  | 'pre_protection'
  | 'done'
  // legacy (alte Builds könnten das im Profile haben — wird im neuen Flow nicht gesetzt)
  | 'nickname'
  | 'block';

export type Me = {
  id: string;
  email: string;
  username: string;
  nickname: string | null;
  avatar: string | null;
  plan: Plan;
  streak: number;
  lyraVoiceId: string | null;
  onboardingStep: OnboardingStep;
  created_at?: string;
  presenceVisible?: boolean;
};

let cachedMe: Me | null = null;
const listeners = new Set<() => void>();

/**
 * Lädt /api/auth/me neu und benachrichtigt ALLE useMe-Konsumenten in der App.
 * Nach jedem PATCH /api/auth/me aufrufen — sonst sehen Konsumenten alten Cache.
 */
export function invalidateMe(): void {
  cachedMe = null;
  for (const cb of listeners) cb();
}

export function useMe(): { me: Me | null; loading: boolean; reload: () => void } {
  const [me, setMe] = useState<Me | null>(cachedMe);
  const [loading, setLoading] = useState(cachedMe === null);
  const [version, setVersion] = useState(0);

  // Auf globale Invalidierung lauschen (Avatar-/Nickname-Update aus Profile-Edit)
  useEffect(() => {
    const cb = () => setVersion((v) => v + 1);
    listeners.add(cb);
    return () => {
      listeners.delete(cb);
    };
  }, []);

  useEffect(() => {
    let cancelled = false;
    (async () => {
      // Falls cache schon frisch ist (von anderem Konsumenten gerade geladen): nutzen
      if (cachedMe !== null) {
        setMe(cachedMe);
        setLoading(false);
        return;
      }
      try {
        const res = await apiFetch<Me>('/api/auth/me');
        if (cancelled) return;
        cachedMe = res;
        setMe(res);
      } catch (e) {
        console.warn('[useMe] fetch failed:', e);
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [version]);

  return {
    me,
    loading,
    reload: () => {
      invalidateMe();
    },
  };
}
