import apiClient from "@/services/api";
import { signal, Signal } from "@preact/signals";
import { createContext, JSX } from "preact";
import { useContext, useEffect } from "preact/hooks";

interface UserData {
  id: number;
  username: string;
  email: string;
}

interface AuthStatusResponse {
  isAuthenticated: boolean;
  user?: UserData;
}

interface AppContextValue {
  isLoggedIn: Signal<boolean>;
  isCheckingAuth: Signal<boolean>;
  currentUser: Signal<UserData | null>;
  checkAuth: () => Promise<void>;
}

const initialLoggedIn = localStorage.getItem("loggedIn") === "true";

const AppContext = createContext<AppContextValue | null>(null);

const AppProvider = ({ children }: { children: JSX.Element }) => {
  const isLoggedIn = signal(initialLoggedIn);
  const isCheckingAuth = signal(true);
  const currentUser = signal<UserData | null>(null);

  const checkAuth = async () => {
    console.log("Checking auth status...");
    isCheckingAuth.value = true;
    try {
      const response = await apiClient<AuthStatusResponse>("/api/auth/status/", {
        method: "GET",
        needsCsrf: false,
      });

      if (response.isAuthenticated && response.user) {
        console.log("User is authenticated:", response.user.username);
        isLoggedIn.value = true;
        currentUser.value = response.user;
        localStorage.setItem("loggedIn", "true");
      } else {
        console.log("User is not authenticated.");
        isLoggedIn.value = false;
        currentUser.value = null;
        localStorage.removeItem("loggedIn");
      }
    } catch (error: any) {
      console.error("Auth check failed:", error.message);
      isLoggedIn.value = false;
      currentUser.value = null;
      localStorage.removeItem("loggedIn");
    } finally {
      isCheckingAuth.value = false;
      console.log("Auth check finished. isLoggedIn:", isLoggedIn.value);
    }
  };

  useEffect(() => {
    checkAuth();
  }, []);

  const value: AppContextValue = {
    isLoggedIn,
    isCheckingAuth,
    currentUser,
    checkAuth,
  };

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

const useAppContext = () => {
  const context = useContext(AppContext);
  if (!context) {
    throw new Error("useAppContext must be used within AppProvider");
  }
  return context;
};

export { AppProvider, useAppContext };
export type { UserData };
