import React, { createContext, useContext, useState, useEffect } from 'react';
import type { User } from '../../../types';
import { apiClient } from '../../../lib/api-client';

interface AuthContextType {
  user: User | null;
  loading: boolean;
  mfaPendingEmail: string | null;
  login: (email: string) => Promise<User>;
  register: (
    email: string,
    profile?: { companyName: string; website: string; sector: string; companySize: string }
  ) => Promise<User>;
  verifyMfa: (code: string) => Promise<User>;
  logout: () => void;
  updateUserLocal: (updatedUser: User) => void;
}

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

export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState<boolean>(true);
  const [mfaPendingEmail, setMfaPendingEmail] = useState<string | null>(null);

  // Check active session on boot
  useEffect(() => {
    const fetchSession = async () => {
      const activeSessionEmail = sessionStorage.getItem('t4b_session_email');
      if (activeSessionEmail) {
        try {
          const response = await apiClient.get<User>('/auth/session');
          if (response.data.mfaVerified) {
            setUser(response.data);
          } else {
            // Need MFA
            setMfaPendingEmail(activeSessionEmail);
          }
        } catch (error) {
          sessionStorage.removeItem('t4b_session_email');
        }
      }
      setLoading(false);
    };

    fetchSession();
  }, []);

  const login = async (email: string): Promise<User> => {
    setLoading(true);
    try {
      const response = await apiClient.post<User>('/auth/login', { email, password: 'password' });
      setMfaPendingEmail(email);
      setLoading(false);
      return response.data;
    } catch (error: any) {
      setLoading(false);
      throw error;
    }
  };

  const register = async (
    email: string,
    profile?: { companyName: string; website: string; sector: string; companySize: string }
  ): Promise<User> => {
    setLoading(true);
    try {
      const response = await apiClient.post<User>('/auth/register', {
        email,
        password: 'password',
        ...profile
      });
      setMfaPendingEmail(email);
      setLoading(false);
      return response.data;
    } catch (error: any) {
      setLoading(false);
      throw error;
    }
  };

  const verifyMfa = async (code: string): Promise<User> => {
    if (!mfaPendingEmail) {
      throw new Error('No MFA challenge active');
    }

    setLoading(true);
    try {
      const response = await apiClient.post<User>('/auth/mfa-verify', {
        email: mfaPendingEmail,
        code
      });
      setUser(response.data);
      setMfaPendingEmail(null);
      setLoading(false);
      return response.data;
    } catch (error: any) {
      setLoading(false);
      throw error;
    }
  };

  const logout = () => {
    sessionStorage.removeItem('t4b_session_email');
    setUser(null);
    setMfaPendingEmail(null);
  };

  const updateUserLocal = (updatedUser: User) => {
    setUser(updatedUser);
  };

  return (
    <AuthContext.Provider value={{
      user,
      loading,
      mfaPendingEmail,
      login,
      register,
      verifyMfa,
      logout,
      updateUserLocal
    }}>
      {children}
    </AuthContext.Provider>
  );
};

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