
"use client";

import type { PropsWithChildren } from 'react';
import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
import { useRouter, usePathname } from 'next/navigation';
import { ADMIN_EMAILS, CONTRACTS_EMAILS, ALLOWED_USER_DOMAINS, DEV_MODE_SIMULATED_USER_EMAIL, type UserRole, type AuthUser, IS_DEV_MODE_OVERRIDE_ACTIVE } from '@/config/authConfig';
import { useToast } from '@/hooks/use-toast';

interface AuthContextType {
  user: AuthUser | null;
  isAuthenticated: boolean;
  isLoading: boolean;
  logout: () => Promise<void>;
  login: () => void;
}

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

export const AuthProvider = ({ children }: PropsWithChildren) => {
  const [user, setUser] = useState<AuthUser | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const router = useRouter();
  const pathname = usePathname();
  const { toast } = useToast();

  const determineRole = useCallback((email: string): UserRole => {
    const lowerEmail = email.toLowerCase();
    if (ADMIN_EMAILS.map(e => e.toLowerCase()).includes(lowerEmail)) return 'admin';
    if (CONTRACTS_EMAILS.map(e => e.toLowerCase()).includes(lowerEmail)) return 'contracts';
    if (ALLOWED_USER_DOMAINS.some(domain => lowerEmail.endsWith(domain.toLowerCase()))) return 'user';
    return 'unauthorized';
  }, []);

  const checkAuthStatus = useCallback(async () => {
    setIsLoading(true);
    if (DEV_MODE_SIMULATED_USER_EMAIL) {
      console.warn(`%cAUTH DEV MODE ACTIVE: Simulating user ${DEV_MODE_SIMULATED_USER_EMAIL}`, "color: orange; font-weight: bold;");
      const role = determineRole(DEV_MODE_SIMULATED_USER_EMAIL);
      if (role === 'unauthorized') {
        setUser(null);
        // Only redirect if not already on an auth outcome page
        if (pathname !== '/auth/denied' && pathname !== '/logged-out') {
            router.push('/auth/denied?reason=dev_override_unauthorized');
        }
      } else {
        setUser({ email: DEV_MODE_SIMULATED_USER_EMAIL, name: `Dev ${role.charAt(0).toUpperCase() + role.slice(1)}`, role, photo: undefined });
      }
      setIsLoading(false);
      return;
    }

    // Real Microsoft Auth Logic
    try {
      const response = await fetch('/api/auth/microsoft/me');
      if (response.ok) {
        const userData = await response.json(); // Expects { email, name, photo? }
        if (userData.email) {
          const role = determineRole(userData.email);
          if (role === 'unauthorized') {
            setUser(null);
            if (pathname !== '/auth/denied' && pathname !== '/logged-out' && !pathname.startsWith('/api/auth')) {
                 router.push('/auth/denied?reason=not_authorized_domain_or_user');
            }
          } else {
            setUser({ email: userData.email, name: userData.name, role, photo: userData.photo });
          }
        } else { // No email in response, treat as unauthenticated
          setUser(null); 
          // Do not redirect if on login, callback, denied or logged-out pages
          if (pathname !== '/api/auth/microsoft/login' && pathname !== '/api/auth/microsoft/callback' && pathname !== '/auth/denied' && pathname !== '/logged-out') {
            router.push('/api/auth/microsoft/login');
          }
        }
      } else { // Response not OK (e.g., 401, 500)
        setUser(null);
        // If 401, redirect to login unless on specific auth-related pages
        if (response.status === 401 && pathname !== '/api/auth/microsoft/login' && pathname !== '/api/auth/microsoft/callback' && pathname !== '/auth/denied' && pathname !== '/logged-out') {
          router.push('/api/auth/microsoft/login');
        } else if (response.status >= 400 && response.status < 500 && pathname !== '/auth/denied' && pathname !== '/logged-out' && !pathname.startsWith('/api/auth')) {
           const errorData = await response.json();
           if (errorData.error?.includes("not authorized") || response.status === 403) { // Or a more specific check for denied access
             router.push('/auth/denied?reason=not_authorized_domain_or_user');
           }
        }
      }
    } catch (error) {
      console.error("Error checking auth status:", error);
      setUser(null);
      // Do not redirect if on login, callback, denied or logged-out pages
      if (pathname !== '/api/auth/microsoft/login' && pathname !== '/api/auth/microsoft/callback' && pathname !== '/auth/denied' && pathname !== '/logged-out') {
         router.push('/api/auth/microsoft/login');
      }
    } finally {
      setIsLoading(false);
    }
  }, [router, determineRole, toast, pathname]);

  useEffect(() => {
    // This effect runs when the component mounts or when pathname/checkAuthStatus changes.
    // It decides whether to initiate an auth status check.
    // API routes handle their own logic and don't need this client-side check.
    if (!pathname.startsWith('/api/')) {
      checkAuthStatus();
    } else {
      setIsLoading(false); 
    }
  }, [checkAuthStatus, pathname]);


  const login = () => {
    if (DEV_MODE_SIMULATED_USER_EMAIL) {
      toast({ title: "Dev Mode Active", description: "Login is simulated." });
      checkAuthStatus(); // Re-check to apply dev mode if somehow it wasn't
      return;
    }
    router.push('/api/auth/microsoft/login');
  };

  const logout = async () => {
    setIsLoading(true);
     if (DEV_MODE_SIMULATED_USER_EMAIL) {
      console.warn("AUTH DEV MODE: Simulating logout.");
      setUser(null);
      setIsLoading(false);
      router.push('/logged-out');
      return;
    }
    try {
      await fetch('/api/auth/microsoft/logout', { method: 'POST' });
    } catch (error) {
      console.error("Logout failed:", error);
      toast({ title: "Logout Error", description: "Failed to logout properly.", variant: "destructive" });
    } finally {
      setUser(null);
      setIsLoading(false);
      router.push('/logged-out'); // Ensure redirect to logged-out page
    }
  };
  
  const isAuthenticated = !!user && user.role !== 'unauthorized' && user.role !== 'loading';

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

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