"use client";

import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from "react";
import {
  fetchCurrentCustomer,
  loginWithEmail,
  logout as sdkLogout,
  registerWithEmail,
  updateCustomerProfile,
  type AuthCustomer,
} from "@/lib/auth";

type AuthContextValue = {
  customer: AuthCustomer | null;
  loading: boolean;
  refresh: () => Promise<void>;
  login: (email: string, password: string) => Promise<void>;
  register: (input: {
    email: string;
    password: string;
    firstName: string;
    lastName: string;
  }) => Promise<void>;
  updateProfile: (input: {
    firstName: string;
    lastName: string;
  }) => Promise<void>;
  logout: () => Promise<void>;
};

const AuthContext = createContext<AuthContextValue | null>(null);

export function AuthProvider({ children }: { children: ReactNode }) {
  const [customer, setCustomer] = useState<AuthCustomer | null>(null);
  const [loading, setLoading] = useState(true);

  const refresh = useCallback(async () => {
    const c = await fetchCurrentCustomer();
    setCustomer(c);
  }, []);

  useEffect(() => {
    refresh().finally(() => setLoading(false));
  }, [refresh]);

  const value = useMemo<AuthContextValue>(
    () => ({
      customer,
      loading,
      refresh,
      login: async (email, password) => {
        const c = await loginWithEmail(email, password);
        setCustomer(c as AuthCustomer);
      },
      register: async (input) => {
        const c = await registerWithEmail(input);
        setCustomer(c as AuthCustomer);
      },
      updateProfile: async (input) => {
        const c = await updateCustomerProfile(input);
        setCustomer(c);
      },
      logout: async () => {
        try {
          await sdkLogout();
        } finally {
          setCustomer(null);
        }
      },
    }),
    [customer, loading, refresh]
  );

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

export function useAuth() {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error("useAuth must be used within AuthProvider");
  return ctx;
}
