import {
  createContext,
  useContext,
  useEffect,
  useState,
  useCallback,
} from 'react';
import {
  getAuthToken,
  saveAuthTokens,
  isTokenExpired,
} from '../../api/utils/token';
import { UsersApi } from '../../api/users';
import { AuthApi } from '../../api/auth';
import { CircularProgress } from '@mui/material';

const AuthContext = createContext(null);

export const AuthProvider = ({ children }) => {
  const [loading, setLoading] = useState(true);
  const [user, setUser] = useState(null);
  const [isAuthenticated, setIsAuthenticated] = useState(() => {
    const token = getAuthToken();
    return !!token && !isTokenExpired();
  });

  const loadUser = useCallback(async () => {
    if (!isAuthenticated) {
      setUser(null);
      return;
    }

    try {
      const userData = await UsersApi.me();
      setUser(userData);
    } catch (error) {
      console.error('Ошибка загрузки пользователя:', error);
      if (error.response?.status === 401) {
        setIsAuthenticated(false);
        setUser(null);
      } else {
        setUser(null);
      }
    }
  }, [isAuthenticated]);

  const login = async (username, password) => {
    setLoading(true);
    try {
      const data = await AuthApi.login(username, password);
      saveAuthTokens(data);
      setIsAuthenticated(true);

      try {
        const userData = await UsersApi.me();
        setUser(userData);
      } catch (userError) {
        console.error('Ошибка загрузки пользователя:', userError);
        setUser(null);
      }
    } catch (error) {
      setIsAuthenticated(false);
      setUser(null);
      console.error('Ошибка авторизации:', error);

      throw new Error(
        error?.response?.data?.detail || 'Неверный логин или пароль',
        { cause: error },
      );
    } finally {
      setLoading(false);
    }
  };

  const logout = async () => {
    try {
      AuthApi.logout();
      setIsAuthenticated(false);
      setUser(null);
    } catch (error) {
      console.error('Ошибка выхода:', error);
    }
  };

  useEffect(() => {
    setLoading(false);
  }, []);

  useEffect(() => {
    loadUser();
  }, [loadUser]);

  useEffect(() => {
    const handleAuthChange = (_event) => {
      const token = getAuthToken();
      const newIsAuthenticated = !!token && !isTokenExpired();
      setIsAuthenticated(newIsAuthenticated);
    };

    const handleAuthExpired = () => {
      setIsAuthenticated(false);
      setUser(null);
    };

    window.addEventListener('auth:changed', handleAuthChange);
    window.addEventListener('auth:expired', handleAuthExpired);

    return () => {
      window.removeEventListener('auth:changed', handleAuthChange);
      window.removeEventListener('auth:expired', handleAuthExpired);
    };
  }, []);

  return (
    <AuthContext.Provider
      value={{ isAuthenticated, user, login, logout, loadUser }}
    >
      {loading ? (
        <div className="flex items-center justify-center min-h-screen">
          <CircularProgress />
        </div>
      ) : (
        children
      )}
    </AuthContext.Provider>
  );
};

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