"use client";

import { createContext, useContext, useState, useEffect } from "react";
import type { Session } from "next-auth";
import { updateSession, getFreshUserData } from "./GuardProviderSS";

// --- TYPES ---
type AuthState = {
  session: Session | null;
  isAuthenticated: boolean;
  isLoading: boolean;
  hasTriggeredGlobalLoad: boolean; // Track if we've triggered global data loading
  hasManualUpdate: boolean; // Track if we've manually updated the session
};

type AuthContextType = {
  session: Session | null;
  isAuthenticated: boolean;
  isLoading: boolean;
  hasTriggeredGlobalLoad: boolean;
  refreshSession: () => Promise<void>;
  clearSession: () => void;
  triggerGlobalDataLoad: () => void;
  updateSessionData: (updates: Partial<Session["user"]>) => void;
};

// --- CONTEXT ---
const AuthContext = createContext<AuthContextType>({
  session: null,
  isAuthenticated: false,
  isLoading: false,
  hasTriggeredGlobalLoad: false,
  refreshSession: async () => {},
  clearSession: () => {},
  triggerGlobalDataLoad: () => {},
  updateSessionData: () => {},
});

export const useAuth = () => useContext(AuthContext);

// --- PROVIDER ---
export const AuthProvider = ({
  children,
  initialSession,
}: {
  children: React.ReactNode;
  initialSession: Session | null;
}) => {
  const [authState, setAuthState] = useState<AuthState>({
    session: initialSession,
    isAuthenticated: !!initialSession?.user?.id,
    isLoading: false,
    hasTriggeredGlobalLoad: false,
    hasManualUpdate: false,
  });

  // Only refresh session when explicitly called - no automatic polling
  const refreshSession = async () => {
    try {
      setAuthState((prev) => ({ ...prev, isLoading: true }));
      const updated = await updateSession();
      setAuthState((prev) => ({
        ...prev,
        session: updated,
        isAuthenticated: !!updated?.user?.id,
        isLoading: false,
      }));
      console.log(
        `[AuthProvider] Session refreshed: ${updated?.user?.email || "none"}`
      );
    } catch (error) {
      console.error("[AuthProvider] Failed to refresh session:", error);
      setAuthState({
        session: null,
        isAuthenticated: false,
        isLoading: false,
        hasTriggeredGlobalLoad: false,
        hasManualUpdate: false,
      });
    }
  };

  const clearSession = () => {
    // Clear application state
    setAuthState({
      session: null,
      isAuthenticated: false,
      isLoading: false,
      hasTriggeredGlobalLoad: false,
      hasManualUpdate: false,
    });

    // Clear NextAuth.js localStorage data
    if (typeof window !== "undefined") {
      // Clear NextAuth.js session data
      const nextAuthKeys = [
        "next-auth.session-token",
        "next-auth.csrf-token",
        "next-auth.callback-url",
        "next-auth.state",
        "__Secure-next-auth.session-token", // Secure version
        "__Host-next-auth.csrf-token", // Host version
      ];

      nextAuthKeys.forEach((key) => {
        localStorage.removeItem(key);
        sessionStorage.removeItem(key);
      });

      // Clear any NextAuth.js cookies (best effort - some may be HTTP-only)
      const cookiesToClear = [
        "next-auth.session-token",
        "next-auth.csrf-token",
        "__Secure-next-auth.session-token",
        "__Host-next-auth.csrf-token",
      ];

      cookiesToClear.forEach((cookieName) => {
        document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
        document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${window.location.hostname};`;
      });

      console.log("[AuthProvider] Session and browser data cleared");
    } else {
      console.log("[AuthProvider] Session cleared (server-side)");
    }
  };

  const triggerGlobalDataLoad = () => {
    setAuthState((prev) => ({ ...prev, hasTriggeredGlobalLoad: true }));
    console.log("[AuthProvider] Global data loading triggered");

    // Notify dashboard to start loading data
    window.dispatchEvent(new CustomEvent("trigger-dashboard-load"));
  };

  const updateSessionData = (updates: Partial<Session["user"]>) => {
    const newSession = authState.session
      ? {
          ...authState.session,
          user: {
            ...authState.session.user,
            ...updates,
          },
        }
      : authState.session;

    setAuthState((prev) => ({
      ...prev,
      session: newSession,
      hasManualUpdate: true,
    }));

    console.log("[AuthProvider] Session data updated directly");
  };

  // Global pre-loading: Check session and validate user exists, then trigger data loading
  useEffect(() => {
    const initializeGlobalData = async () => {
      if (!authState.isAuthenticated || authState.hasTriggeredGlobalLoad) {
        return; // Skip if not authenticated or already triggered
      }

      console.log(
        "[AuthProvider] Authenticated user detected, validating and triggering data load..."
      );

      try {
        // Validate user still exists in database
        const userId = authState.session?.user?.id;
        if (userId) {
          await getFreshUserData(userId);
          console.log(
            "[AuthProvider] User validation successful, triggering global data load"
          );
          triggerGlobalDataLoad();
        }
      } catch (error) {
        console.error("[AuthProvider] User validation failed:", error);
        clearSession(); // Clear invalid session
      }
    };

    initializeGlobalData();
  }, [
    authState.isAuthenticated,
    authState.hasTriggeredGlobalLoad,
    authState.session?.user?.id,
  ]);

  // Simple session sync without loops - respect manual updates
  useEffect(() => {
    if (initialSession !== authState.session && !authState.hasManualUpdate) {
      setAuthState((prev) => ({
        ...prev,
        session: initialSession,
        isAuthenticated: !!initialSession?.user?.id,
      }));
    }
  }, [initialSession, authState.session, authState.hasManualUpdate]);

  return (
    <AuthContext.Provider
      value={{
        session: authState.session,
        isAuthenticated: authState.isAuthenticated,
        isLoading: authState.isLoading,
        hasTriggeredGlobalLoad: authState.hasTriggeredGlobalLoad,
        refreshSession,
        clearSession,
        triggerGlobalDataLoad,
        updateSessionData,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
};
