import React, {
  createContext,
  useContext,
  useReducer,
  useEffect,
  ReactNode,
  useMemo,
} from "react";
// Removed @huggingface/hub dependency - using direct OAuth redirect instead
import {
  AuthState,
  AuthContextType,
  OAuthResult,
  UserInfo,
} from "@/types/auth";
import { useModal } from "./ModalContext";

type AuthAction =
  | { type: "AUTH_START" }
  | { type: "AUTH_SUCCESS"; payload: OAuthResult }
  | { type: "AUTH_ERROR"; payload: string }
  | { type: "AUTH_LOGOUT" }
  | { type: "SET_LOADING"; payload: boolean };

const initialState: AuthState = {
  isAuthenticated: false,
  user: null,
  accessToken: null,
  accessTokenExpiresAt: null,
  scope: null,
  isLoading: true,
  error: null,
};

function authReducer(state: AuthState, action: AuthAction): AuthState {
  switch (action.type) {
    case "AUTH_START":
      return {
        ...state,
        isLoading: true,
        error: null,
      };
    case "AUTH_SUCCESS":
      return {
        ...state,
        isAuthenticated: true,
        user: action.payload.userInfo,
        accessToken: action.payload.accessToken,
        accessTokenExpiresAt:
          action.payload.accessTokenExpiresAt instanceof Date
            ? action.payload.accessTokenExpiresAt.toISOString()
            : action.payload.accessTokenExpiresAt,
        scope: action.payload.scope,
        isLoading: false,
        error: null,
      };
    case "AUTH_ERROR":
      return {
        ...state,
        isAuthenticated: false,
        user: null,
        accessToken: null,
        accessTokenExpiresAt: null,
        scope: null,
        isLoading: false,
        error: action.payload,
      };
    case "AUTH_LOGOUT":
      return {
        ...initialState,
        isLoading: false,
      };
    case "SET_LOADING":
      return {
        ...state,
        isLoading: action.payload,
      };
    default:
      return state;
  }
}

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

const STORAGE_KEY = "agentgraph_oauth";

// OAuth result handling is now done directly in checkAuthStatus

export function AuthProvider({ children }: { children: ReactNode }) {
  const [authState, dispatch] = useReducer(authReducer, initialState);
  const { openModal } = useModal();

  // Check for existing auth on mount
  useEffect(() => {
    checkAuthStatus();
  }, []);

  const checkAuthStatus = async () => {
    try {
      dispatch({ type: "SET_LOADING", payload: true });

      // First check backend session for existing authentication
      try {
        const response = await fetch("/auth/status", {
          credentials: "include", // Include session cookies
        });

        if (response.ok) {
          const statusData = await response.json();
          if (statusData.authenticated && statusData.user) {
            console.log("🔓 Found existing backend session authentication");

            // Convert backend user format to our OAuth format
            const oauthResult: OAuthResult = {
              userInfo: {
                id: statusData.user.id,
                name: statusData.user.name || statusData.user.username,
                fullname: statusData.user.name || statusData.user.username,
                email: statusData.user.email,
                emailVerified: false,
                avatarUrl: statusData.user.avatar_url,
                orgs: [],
                isPro: false,
              },
              accessToken: statusData.user.access_token || "session_token",
              accessTokenExpiresAt: new Date(
                Date.now() + 24 * 60 * 60 * 1000
              ).toISOString(), // 24 hours
              scope: "openid profile read-repos", // Backend authenticated users have these scopes
            };

            dispatch({ type: "AUTH_SUCCESS", payload: oauthResult });
            // Also save to localStorage for consistency
            localStorage.setItem(STORAGE_KEY, JSON.stringify(oauthResult));
            return;
          }
        }
      } catch (error) {
        console.log("🔍 No backend session found, checking localStorage");
      }

      // Second, check localStorage for existing oauth data
      const stored = localStorage.getItem(STORAGE_KEY);
      if (stored) {
        try {
          const oauthResult = JSON.parse(stored) as OAuthResult;
          // Check if token is still valid
          const expiresAt = new Date(oauthResult.accessTokenExpiresAt);
          if (expiresAt > new Date()) {
            dispatch({ type: "AUTH_SUCCESS", payload: oauthResult });
            return;
          } else {
            // Token expired, remove from storage
            localStorage.removeItem(STORAGE_KEY);
          }
        } catch (error) {
          localStorage.removeItem(STORAGE_KEY);
        }
      }

      // Check for OAuth redirect (standard OAuth code parameter)
      const urlParams = new URLSearchParams(window.location.search);
      const code = urlParams.get("code");
      const state = urlParams.get("state");
      const storedState = localStorage.getItem("oauth_state");

      if (code && state) {
        console.log(
          "🔐 OAuth callback detected - backend should have handled this"
        );

        // Clear OAuth state from localStorage
        localStorage.removeItem("oauth_state");

        // Clean up URL parameters since backend handled the OAuth
        window.history.replaceState(
          {},
          document.title,
          window.location.pathname
        );

        // Recheck auth status to pick up the backend session
        setTimeout(() => {
          checkAuthStatus();
        }, 100);
        return;
      } else {
        // No OAuth redirect found, check if we need to show auth modal

        // Enhanced HF Spaces detection with debugging
        const isHFSpaces =
          // Method 1: Check for window.huggingface
          (window.huggingface && window.huggingface.variables) ||
          // Method 2: Check for HF-specific URL patterns
          window.location.hostname.includes("hf.space") ||
          window.location.hostname.includes("huggingface.co") ||
          // Method 3: Check for HF-specific environment indicators
          document.querySelector('meta[name="hf:space"]') !== null;

        // Debug logging (remove in production)
        console.log("🔍 HF Spaces Environment Check:", {
          hostname: window.location.hostname,
          hasHuggingface: !!window.huggingface,
          hasVariables: !!(window.huggingface && window.huggingface.variables),
          hasHfMeta: !!document.querySelector('meta[name="hf:space"]'),
          isHFSpaces,
          href: window.location.href,
          huggingfaceObject: window.huggingface,
          variables: window.huggingface?.variables,
          oauthScopes: window.huggingface?.variables?.OAUTH_SCOPES,
        });

        if (isHFSpaces) {
          // In HF Spaces, we require authentication - show the modal
          console.log("🔐 HF Spaces detected - showing auth modal");
          dispatch({ type: "SET_LOADING", payload: false });
          openModal("auth-login", "Sign in to AgentGraph");
        } else {
          // In local development, no auth required
          console.log("🏠 Local development detected - no auth required");
          dispatch({ type: "SET_LOADING", payload: false });
        }
      }
    } catch (error) {
      console.error("Auth check failed:", error);
      dispatch({
        type: "AUTH_ERROR",
        payload: "Failed to check authentication status",
      });
    }
  };

  const login = async () => {
    console.log("🚀 login() function called");
    try {
      dispatch({ type: "AUTH_START" });
      console.log("📤 Dispatched AUTH_START");

      // Check if we're in HF Spaces environment
      const isHFSpaces =
        (window.huggingface && window.huggingface.variables) ||
        window.location.hostname.includes("hf.space") ||
        window.location.hostname.includes("huggingface.co") ||
        document.querySelector('meta[name="hf:space"]') !== null;

      console.log("🔍 HF Spaces detection in login():", {
        isHFSpaces,
        hostname: window.location.hostname,
        hasHuggingface: !!window.huggingface,
      });

      if (isHFSpaces) {
        // In HF Spaces, get OAuth config from backend API
        console.log("🔐 Getting OAuth config from backend");

        try {
          console.log("📡 Fetching /auth/oauth-config...");
          const response = await fetch("/auth/oauth-config");
          console.log("📡 Fetch response status:", response.status);
          const oauthConfig = await response.json();
          console.log("📡 OAuth config response:", oauthConfig);

          if (!oauthConfig.oauth_enabled) {
            throw new Error("OAuth not enabled or configured on backend");
          }

          console.log("✅ OAuth config received:", {
            client_id: oauthConfig.client_id?.substring(0, 8) + "...",
            scopes: oauthConfig.scopes,
            provider_url: oauthConfig.provider_url,
          });

          // Direct OAuth URL construction with backend-provided client_id
          const baseUrl = window.location.origin;
          const redirectUri = `${baseUrl}/auth/oauth-callback`;

          // Create state for CSRF protection
          const state = Math.random().toString(36).substring(2, 15);
          localStorage.setItem("oauth_state", state);

          // Use HF OAuth endpoint with proper client_id from backend
          const oauthUrl =
            `${oauthConfig.provider_url}/oauth/authorize?` +
            `response_type=code&` +
            `client_id=${encodeURIComponent(oauthConfig.client_id)}&` +
            `redirect_uri=${encodeURIComponent(redirectUri)}&` +
            `scope=${encodeURIComponent(oauthConfig.scopes)}&` +
            `state=${state}&` +
            `prompt=consent`;

          console.log("🔄 Redirecting to HF OAuth:", oauthUrl.substring(0, 100) + "...");
          window.location.href = oauthUrl;
        } catch (configError) {
          console.error(
            "❌ Failed to get OAuth config from backend:",
            configError
          );
          throw new Error("OAuth configuration not available from backend");
        }
      } else {
        // For local development, show a message or redirect to HF
        console.log("⚠️ Not in HF Spaces, dispatching AUTH_ERROR");
        dispatch({
          type: "AUTH_ERROR",
          payload:
            "Authentication is only available when deployed to Hugging Face Spaces",
        });
      }
    } catch (error) {
      console.error("❌ Login failed:", error);
      dispatch({
        type: "AUTH_ERROR",
        payload: "Failed to initiate login",
      });
    }
  };

  const logout = () => {
    localStorage.removeItem(STORAGE_KEY);
    dispatch({ type: "AUTH_LOGOUT" });
    // Optionally redirect to clear URL params
    const url = new URL(window.location.href);
    url.search = "";
    window.history.replaceState({}, "", url.toString());
  };

  const requireAuth = () => {
    if (!authState.isAuthenticated) {
      openModal("auth-login", "Sign in to AgentGraph");
    }
  };

  const contextValue = useMemo(
    () => ({
      authState,
      login,
      logout,
      requireAuth,
      checkAuthStatus,
    }),
    [authState]
  );

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

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