import { createContext, useContext, useCallback, useState } from "react";
import type { ReactNode } from "react";
import { pb } from "@/lib/pocketbase";
import type { AuthRecord } from "pocketbase";
import { useNavigate } from "@tanstack/react-router";

/**
 * Represents the shape of the authenticated user object from PocketBase.
 */
/**
 * Context value for authentication state and actions.
 */
export interface AuthContextValue {
  user: AuthRecord | null;
  isLoading: boolean;
  login: (email: string, password: string) => Promise<void>;
  signup: (
    email: string,
    password: string,
    passwordConfirm: string,
  ) => Promise<void>;
  logout: () => Promise<void>;
}

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

/**
 * Provider for authentication context.
 */
export function AuthProvider({ children }: { children: ReactNode }) {
  const [isLoading, setIsLoading] = useState(false);
  const [user, setUser] = useState<AuthRecord | null>(pb.authStore.record);

  const navigate = useNavigate();

  function updateUser() {
    if (pb.authStore.isValid) {
      setUser(pb.authStore.record);
    }
    setIsLoading(false);
  }

  const login = useCallback(async (email: string, password: string) => {
    console.log("login");
    setIsLoading(true);
    await pb.collection("users").authWithPassword(email, password);
    updateUser();
    navigate({ to: "/campaigns" });
  }, []);

  const signup = useCallback(
    async (email: string, password: string, passwordConfirm: string) => {
      console.log("signup");
      setIsLoading(true);
      await pb.collection("users").create({ email, password, passwordConfirm });
      await pb.collection("users").authWithPassword(email, password);
      updateUser();
      navigate({ to: "/campaigns" });
    },
    [],
  );

  const logout = useCallback(async () => {
    console.log("logout");
    pb.authStore.clear();
    setUser(null);
    navigate({ to: "/" });
  }, []);

  return (
    <AuthContext.Provider
      value={{ user: user ?? null, isLoading, login, signup, logout }}
    >
      {children}
    </AuthContext.Provider>
  );
}

/**
 * Hook to access authentication context.
 * Throws if used outside of AuthProvider.
 */
export function useAuth(): AuthContextValue {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error("useAuth must be used within an AuthProvider");
  return ctx;
}
