/**
 * Authentication Context
 * Manages user login state and provides auth utilities
 */
"use client";

import React, { createContext, useContext, useState, useEffect, useCallback, ReactNode } from "react";

// User interface
export interface User {
  id: string;
  email: string;
  name: string | null;
  avatar_url: string | null;
}

// Auth context interface
interface AuthContextType {
  user: User | null;
  token: string | null;
  isLoading: boolean;
  isAuthenticated: boolean;
  login: () => void;
  logout: () => void;
  setAuthFromCallback: (token: string) => void;
}

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

// Token storage key
const TOKEN_KEY = "tradingagents_auth_token";

/**
 * Auth Provider Component
 */
export function AuthProvider({ children }: { children: ReactNode }) {
  const [user, setUser] = useState<User | null>(null);
  const [token, setToken] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [googleClientId, setGoogleClientId] = useState<string>("");

  // Fetch Google Client ID from API (runtime)
  useEffect(() => {
    fetch("/api/config")
      .then(res => res.json())
      .then(data => {
        setGoogleClientId(data.googleClientId || "");
      })
      .catch(err => {
        console.error("Failed to fetch config:", err);
      });
  }, []);

  // Parse JWT token to get user info
  const parseToken = useCallback((token: string): User | null => {
    try {
      const payload = JSON.parse(atob(token.split(".")[1]));
      return {
        id: payload.sub,
        email: payload.email,
        name: payload.name,
        avatar_url: payload.avatar_url,
      };
    } catch {
      return null;
    }
  }, []);

  // Check if token is expired
  const isTokenExpired = useCallback((token: string): boolean => {
    try {
      const payload = JSON.parse(atob(token.split(".")[1]));
      const exp = payload.exp * 1000; // Convert to milliseconds
      return Date.now() > exp;
    } catch {
      return true;
    }
  }, []);

  // Initialize auth state from localStorage
  useEffect(() => {
    const initAuth = () => {
      if (typeof window === "undefined") {
        setIsLoading(false);
        return;
      }

      const storedToken = localStorage.getItem(TOKEN_KEY);
      
      if (storedToken && !isTokenExpired(storedToken)) {
        const userData = parseToken(storedToken);
        if (userData) {
          setToken(storedToken);
          setUser(userData);
        } else {
          localStorage.removeItem(TOKEN_KEY);
        }
      } else if (storedToken) {
        // Token expired, remove it
        localStorage.removeItem(TOKEN_KEY);
      }
      
      setIsLoading(false);
    };

    initAuth();
  }, [parseToken, isTokenExpired]);

  // Login - redirect to Google OAuth
  const login = useCallback(() => {
    if (!googleClientId) {
      console.error("Google Client ID not configured");
      alert("Google 登入尚未設定。請聯繫管理員。");
      return;
    }

    // Build Google OAuth URL
    const redirectUri = `${window.location.origin}/api/auth/callback/google`;
    const scope = "openid email profile";
    
    const params = new URLSearchParams({
      client_id: googleClientId,
      redirect_uri: redirectUri,
      response_type: "code",
      scope: scope,
      access_type: "offline",
      prompt: "consent",
    });

    window.location.href = `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`;
  }, [googleClientId]);

  // Logout
  const logout = useCallback(() => {
    localStorage.removeItem(TOKEN_KEY);
    setToken(null);
    setUser(null);
  }, []);

  // Set auth from callback (after OAuth redirect)
  const setAuthFromCallback = useCallback((newToken: string) => {
    const userData = parseToken(newToken);
    if (userData) {
      localStorage.setItem(TOKEN_KEY, newToken);
      setToken(newToken);
      setUser(userData);
    }
  }, [parseToken]);

  const value: AuthContextType = {
    user,
    token,
    isLoading,
    isAuthenticated: !!user,
    login,
    logout,
    setAuthFromCallback,
  };

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

/**
 * Hook to use auth context
 */
export function useAuth(): AuthContextType {
  const context = useContext(AuthContext);
  if (context === undefined) {
    throw new Error("useAuth must be used within an AuthProvider");
  }
  return context;
}

/**
 * Get auth token for API requests
 */
export function getAuthToken(): string | null {
  if (typeof window === "undefined") return null;
  return localStorage.getItem(TOKEN_KEY);
}

/**
 * Get auth headers for API requests
 */
export function getAuthHeaders(): Record<string, string> {
  const token = getAuthToken();
  if (token) {
    return { Authorization: `Bearer ${token}` };
  }
  return {};
}
