import { useState, useCallback, useEffect, useRef } from 'react';
import { useToast } from '@/components/ui/use-toast';
import { getDeployEnvironments } from '../service';
import type { DeployTeam } from '../types';

interface UseDeploymentDataOptions {
  onInitialLoadComplete?: () => void;
}

/**
 * 部署数据管理 Hook
 * 优化点:
 * 1. 智能轮询 - 根据部署状态动态调整轮询频率
 * 2. 页面可见性检测 - 页面隐藏时暂停轮询
 * 3. 状态持久化 - 刷新时保持选中的团队和环境
 */
export function useDeploymentData(options: UseDeploymentDataOptions = {}) {
  const { toast } = useToast();
  const [loading, setLoading] = useState(true);
  const [teams, setTeams] = useState<DeployTeam[]>([]);
  const [currentTeamId, setCurrentTeamId] = useState<number | null>(null);
  const [currentEnvId, setCurrentEnvId] = useState<number | null>(null);
  const [deploying, setDeploying] = useState<Set<number>>(new Set());
  const [isInitialLoad, setIsInitialLoad] = useState(true);
  const [recentlyCompleted, setRecentlyCompleted] = useState(false); // 刚完成部署，保持较短轮询间隔
  
  const intervalRef = useRef<NodeJS.Timeout | null>(null);
  const recentlyCompletedTimerRef = useRef<NodeJS.Timeout | null>(null);
  const optionsRef = useRef(options);
  const toastRef = useRef(toast);
  
  // 同步 options 和 toast 到 ref
  useEffect(() => {
    optionsRef.current = options;
    toastRef.current = toast;
  }, [options, toast]);

  // 使用 ref 存储当前选中的团队和环境，避免 loadData 依赖变化
  const currentSelectionRef = useRef({ teamId: currentTeamId, envId: currentEnvId });
  
  useEffect(() => {
    currentSelectionRef.current = { teamId: currentTeamId, envId: currentEnvId };
  }, [currentTeamId, currentEnvId]);

  // 加载部署环境数据 - 移除状态依赖，使用 ref
  const loadData = useCallback(async (showLoading = false) => {
    try {
      if (showLoading) {
        setLoading(true);
      }
      
      const response = await getDeployEnvironments();
      
      if (response && response.length > 0) {
        const prevTeamId = currentSelectionRef.current.teamId;
        const prevEnvId = currentSelectionRef.current.envId;
        
        setTeams(response);
        
        setIsInitialLoad(prev => {
          if (prev) {
            // 首次加载：默认选中第一个团队和第一个环境
            if (response.length > 0) {
              setCurrentTeamId(response[0].teamId);
              
              if (response[0].environments.length > 0) {
                setCurrentEnvId(response[0].environments[0].environmentId);
              }
            }
            optionsRef.current.onInitialLoadComplete?.();
            return false;
          } else {
            // 后续刷新：保持当前选中的团队和环境
            if (prevTeamId !== null) {
              const teamExists = response.some(t => t.teamId === prevTeamId);
              if (teamExists) {
                setCurrentTeamId(prevTeamId);
                
                if (prevEnvId !== null) {
                  const team = response.find(t => t.teamId === prevTeamId);
                  const envExists = team?.environments.some(e => e.environmentId === prevEnvId);
                  if (envExists) {
                    setCurrentEnvId(prevEnvId);
                  } else if (team && team.environments.length > 0) {
                    setCurrentEnvId(team.environments[0].environmentId);
                  }
                }
              } else if (response.length > 0) {
                setCurrentTeamId(response[0].teamId);
                if (response[0].environments.length > 0) {
                  setCurrentEnvId(response[0].environments[0].environmentId);
                }
              }
            }
            
            // 检查部署状态，如果应用不再是 RUNNING 状态，从 deploying 状态中移除
            setDeploying((prevDeploying) => {
              const newDeploying = new Set(prevDeploying);
              let hasChanges = false;
              
              response.forEach(team => {
                team.environments.forEach(env => {
                  env.applications.forEach(app => {
                    if (newDeploying.has(app.teamApplicationId)) {
                      const latestStatus = app.deployStatistics?.latestStatus;
                      if (latestStatus && latestStatus !== 'RUNNING') {
                        newDeploying.delete(app.teamApplicationId);
                        hasChanges = true;
                      }
                    }
                  });
                });
              });
              
              // 部署完成后：立即刷新 + 保持较短轮询间隔一段时间
              if (hasChanges && newDeploying.size === 0) {
                // 立即刷新一次
                setTimeout(() => {
                  loadData(false);
                }, 1000);
                
                // 设置"刚完成部署"状态，保持10秒轮询间隔，30秒后恢复正常
                setRecentlyCompleted(true);
                if (recentlyCompletedTimerRef.current) {
                  clearTimeout(recentlyCompletedTimerRef.current);
                }
                recentlyCompletedTimerRef.current = setTimeout(() => {
                  setRecentlyCompleted(false);
                }, 30000);
              }
              
              return hasChanges ? newDeploying : prevDeploying;
            });
          }
          return prev;
        });
      }
    } catch (error) {
      console.error('加载数据失败:', error);
      setIsInitialLoad(prev => {
        if (prev) {
          toastRef.current({
            variant: 'destructive',
            title: '加载失败',
            description: '无法加载部署环境数据，请稍后重试',
          });
        }
        return prev;
      });
    } finally {
      if (showLoading) {
        setLoading(false);
      }
    }
  }, []);

  // 首次加载数据
  useEffect(() => {
    const initData = async () => {
      await loadData(false);
      setLoading(false);
    };
    
    initData();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // 计算轮询间隔：部署中5秒，刚完成10秒，空闲30秒
  const getPollingInterval = useCallback(() => {
    if (deploying.size > 0) return 5000;
    if (recentlyCompleted) return 10000;
    return 30000;
  }, [deploying.size, recentlyCompleted]);

  // 定时刷新数据（智能轮询）
  useEffect(() => {
    // 初始加载时不启动轮询
    if (isInitialLoad) return;

    // 清除旧的定时器
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
    }

    // 页面可见性检测
    const handleVisibilityChange = () => {
      if (document.hidden) {
        // 页面隐藏时停止轮询
        if (intervalRef.current) {
          clearInterval(intervalRef.current);
          intervalRef.current = null;
        }
      } else {
        // 页面显示时恢复轮询
        if (intervalRef.current) {
          clearInterval(intervalRef.current);
        }
        const interval = getPollingInterval();
        intervalRef.current = setInterval(() => {
          loadData(false);
        }, interval);
      }
    };

    // 启动轮询 - 智能间隔
    const interval = getPollingInterval();
    intervalRef.current = setInterval(() => {
      loadData(false);
    }, interval);

    // 监听页面可见性变化
    document.addEventListener('visibilitychange', handleVisibilityChange);

    return () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
      }
      document.removeEventListener('visibilitychange', handleVisibilityChange);
    };
  }, [isInitialLoad, deploying.size, recentlyCompleted, loadData, getPollingInterval]);

  // 清理 recentlyCompletedTimer
  useEffect(() => {
    return () => {
      if (recentlyCompletedTimerRef.current) {
        clearTimeout(recentlyCompletedTimerRef.current);
      }
    };
  }, []);

  // 切换团队
  const handleTeamChange = useCallback((teamId: string) => {
    const newTeamId = Number(teamId);
    setCurrentTeamId(newTeamId);
    
    const team = teams.find(t => t.teamId === newTeamId);
    if (team && team.environments.length > 0) {
      setCurrentEnvId(team.environments[0].environmentId);
    } else {
      setCurrentEnvId(null);
    }
  }, [teams]);

  // 处理部署成功
  const handleDeploySuccess = useCallback(async () => {
    await loadData(false);
  }, [loadData]);

  // 获取当前团队和环境
  const currentTeam = teams.find(t => t.teamId === currentTeamId);
  const currentEnv = currentTeam?.environments.find(e => e.environmentId === currentEnvId);

  return {
    loading,
    teams,
    currentTeamId,
    currentEnvId,
    deploying,
    currentTeam,
    currentEnv,
    setCurrentEnvId,
    handleTeamChange,
    handleDeploySuccess,
    refreshData: () => loadData(false)
  };
}
