import { createContext, useContext, useEffect, useState, type ReactNode } from "react";
import { supabase } from "@/integrations/supabase/client";
import type { Session } from "@supabase/supabase-js";

type Profile = {
  id: string;
  display_name: string | null;
  recovery_email: string | null;
  recovery_phone: string | null;
  master_pin_hash: string | null;
  encryption_salt: string | null;
  webauthn_credentials: unknown;
};

type VaultContextValue = {
  session: Session | null;
  loading: boolean;
  profile: Profile | null;
  vaultKey: CryptoKey | null;
  refreshProfile: () => Promise<void>;
  setVaultKey: (key: CryptoKey | null) => void;
  signOut: () => Promise<void>;
};

const Ctx = createContext<VaultContextValue | null>(null);

export function VaultProvider({ children }: { children: ReactNode }) {
  const [session, setSession] = useState<Session | null>(null);
  const [loading, setLoading] = useState(true);
  const [profile, setProfile] = useState<Profile | null>(null);
  const [vaultKey, setVaultKey] = useState<CryptoKey | null>(null);

  useEffect(() => {
    const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, s) => {
      setSession(s);
      if (!s) {
        setProfile(null);
        setVaultKey(null);
      }
    });
    supabase.auth.getSession().then(({ data }) => {
      setSession(data.session);
      setLoading(false);
    });
    return () => subscription.unsubscribe();
  }, []);

  const refreshProfile = async () => {
    if (!session?.user) {
      setProfile(null);
      return;
    }
    const { data } = await supabase.from("profiles").select("*").eq("id", session.user.id).maybeSingle();
    setProfile(data as Profile | null);
  };

  useEffect(() => {
    if (session?.user) refreshProfile();
    else setProfile(null);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [session?.user?.id]);

  const signOut = async () => {
    setVaultKey(null);
    await supabase.auth.signOut();
  };

  return (
    <Ctx.Provider value={{ session, loading, profile, vaultKey, refreshProfile, setVaultKey, signOut }}>
      {children}
    </Ctx.Provider>
  );
}

export function useVault() {
  const v = useContext(Ctx);
  if (!v) throw new Error("useVault must be used inside VaultProvider");
  return v;
}
