import { createContext, useContext, useEffect, useState, type ReactNode } from 'react';
import type { Session } from '@supabase/supabase-js';
import type { Perfil } from '@gustito/shared';
import { recibirSesionDeUrl } from '@gustito/shared';
import { supabase } from './supabase';

interface AuthState {
  session: Session | null;
  perfil: Perfil | null;
  cargando: boolean;
  recuperando: boolean;
  terminarRecuperacion: () => void;
  refrescar: () => Promise<void>;
  salir: () => Promise<void>;
}

const Ctx = createContext<AuthState>({
  session: null,
  perfil: null,
  cargando: true,
  recuperando: false,
  terminarRecuperacion: () => {},
  refrescar: async () => {},
  salir: async () => {},
});

export function AuthProvider({ children }: { children: ReactNode }) {
  const [session, setSession] = useState<Session | null>(null);
  const [perfil, setPerfil] = useState<Perfil | null>(null);
  const [cargando, setCargando] = useState(true);
  const [recuperando, setRecuperando] = useState(false);

  async function cargarPerfil(userId: string) {
    const { data } = await supabase.from('perfiles').select('*').eq('id', userId).maybeSingle();
    setPerfil((data as unknown as Perfil) ?? null);
  }

  async function refrescar() {
    const { data } = await supabase.auth.getSession();
    if (data.session) await cargarPerfil(data.session.user.id);
  }

  useEffect(() => {
    (async () => {
      // Si llegamos desde la app unica con la sesion en la URL, cargarla primero.
      await recibirSesionDeUrl(supabase);
      const { data } = await supabase.auth.getSession();
      setSession(data.session);
      if (data.session) await cargarPerfil(data.session.user.id);
      setCargando(false);
    })();
    const { data: sub } = supabase.auth.onAuthStateChange(async (event, s) => {
      if (event === 'PASSWORD_RECOVERY') setRecuperando(true);
      setSession(s);
      if (s) await cargarPerfil(s.user.id);
      else setPerfil(null);
    });
    return () => sub.subscription.unsubscribe();
  }, []);

  async function salir() {
    await supabase.auth.signOut();
    setPerfil(null);
  }

  function terminarRecuperacion() {
    setRecuperando(false);
  }

  return (
    <Ctx.Provider value={{ session, perfil, cargando, recuperando, terminarRecuperacion, refrescar, salir }}>
      {children}
    </Ctx.Provider>
  );
}

export function useAuth() {
  return useContext(Ctx);
}
