import { useAuth } from '@/hooks/use-auth';
import { authEvents } from '@/lib/api/client';
import React, { createContext, useCallback, useContext, useEffect, useState } from 'react';
import { LoginModal } from './login-modal';

export interface AuthContextType {
  requireAuth: (callback?: () => void) => boolean;
  showLoginModal: boolean;
  setShowLoginModal: (show: boolean) => void;
  pendingCallback: (() => void) | null;
}

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

export { AuthContext };

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const { isAuthenticated, isLoading } = useAuth();
  const [showLoginModal, setShowLoginModal] = useState(false);
  const [pendingCallback, setPendingCallback] = useState<(() => void) | null>(null);

  // 认证拦截函数
  const requireAuth = useCallback((callback?: () => void): boolean => {
    if (isLoading) {
      // 如果认证状态还在加载中，不执行任何操作
      return false;
    }

    if (!isAuthenticated) {
      // 未登录，保存回调并显示登录Modal
      setPendingCallback(() => callback || null);
      setShowLoginModal(true);
      return false;
    }

    // 已登录，执行回调
    if (callback) {
      callback();
    }
    return true;
  }, [isAuthenticated, isLoading]);

  // 监听登录状态变化
  useEffect(() => {
    if (isAuthenticated && showLoginModal) {
      // 登录成功，自动关闭Modal并执行回调
      if (pendingCallback) {
        pendingCallback();
        setPendingCallback(null);
      }
      setShowLoginModal(false);
    }
  }, [isAuthenticated, showLoginModal, pendingCallback]);

  // 监听 401 未授权事件
  useEffect(() => {
    const unsubscribe = authEvents.onUnauthorized(() => {
      if (!isLoading && !isAuthenticated) {
        setShowLoginModal(true);
      }
    });

    return unsubscribe;
  }, [isLoading, isAuthenticated]);

  const value = {
    requireAuth,
    showLoginModal,
    setShowLoginModal,
    pendingCallback,
  };

  return (
    <AuthContext.Provider value={value}>
      {children}
      <LoginModal
        visible={showLoginModal}
        onClose={() => {
          setShowLoginModal(false);
          setPendingCallback(null);
        }}
      />
    </AuthContext.Provider>
  );
}

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