import { createContext, useContext, useState, useEffect, useCallback } from 'react';
import api from '../services/api';

const AuthContext = createContext(null);

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const token = localStorage.getItem('token');
    if (token) {
      api.get('/auth/me')
        .then(res => setUser(res.data.user))
        .catch(() => {
          localStorage.removeItem('token');
        })
        .finally(() => setLoading(false));
    } else {
      setLoading(false);
    }
  }, []);

  const login = useCallback(async (email, password) => {
    const res = await api.post('/auth/login', { email, password });
    if (res.data.requires2FA) {
      return { requires2FA: true, tempToken: res.data.tempToken };
    }
    localStorage.setItem('token', res.data.token);
    setUser(res.data.user);
    return res.data.user;
  }, []);

  const verify2FA = useCallback(async (tempToken, code) => {
    const res = await api.post('/auth/login/2fa', { tempToken, code });
    localStorage.setItem('token', res.data.token);
    setUser(res.data.user);
    return res.data.user;
  }, []);

  const register = useCallback(async (username, displayName, email, password, inviteToken) => {
    const payload = { username, display_name: displayName, email, password };
    if (inviteToken) payload.invite_token = inviteToken;
    const res = await api.post('/auth/register', payload);
    if (res.data.needsVerification) {
      return { needsVerification: true };
    }
    localStorage.setItem('token', res.data.token);
    setUser(res.data.user);
    return res.data.user;
  }, []);

  const logout = useCallback(async () => {
    let keycloakLogoutUrl = null;
    try {
      const res = await api.post('/auth/logout');
      keycloakLogoutUrl = res.data?.keycloakLogoutUrl || null;
    } catch {
      // ignore — token is removed locally regardless
    }
    localStorage.removeItem('token');
    if (keycloakLogoutUrl) {
      // Redirect to Keycloak BEFORE clearing React state to avoid
      // flash-rendering the login page while the redirect is pending.
      window.location.href = keycloakLogoutUrl;
      return;
    }
    setUser(null);
  }, []);

  const loginWithOAuth = useCallback(async (token) => {
    localStorage.setItem('token', token);
    try {
      const res = await api.get('/auth/me');
      setUser(res.data.user);
      return res.data.user;
    } catch (err) {
      localStorage.removeItem('token');
      throw err;
    }
  }, []);

  const updateUser = useCallback((updatedUser) => {
    setUser(updatedUser);
  }, []);

  return (
    <AuthContext.Provider value={{ user, loading, login, verify2FA, register, logout, loginWithOAuth, updateUser }}>
      {children}
    </AuthContext.Provider>
  );
}

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