import { ApiResponse } from './common';
import { showQueueNotification } from '../components/QueueBox/QueueNotification2';
import { notification } from 'antd';

/** 队列状态枚举 */
export enum QueueStatus {
  WAIT = 'wait',     // 排队等待中
  READY = 'ready',   // 可以开始处理
  PROCESS = 'process' // 处理中
}

/** 队列响应数据接口 */
export interface QueueResponseData {
  status: QueueStatus;
  position?: number;
  queue_length?: number;
  waiting?: number;
  message?: string;
}

/** 队列响应接口 */
export interface QueueResponse extends ApiResponse<QueueResponseData> {
  code: number;
  message: string;
  data: QueueResponseData;
}

/**
 * 处理API轮询的配置选项
 */
interface PollConfig {
  /** 轮询间隔(ms), 默认10000ms */
  interval?: number;
  /** 最大轮询次数, 默认120次(20分钟) */
  maxAttempts?: number;
  /** 轮询成功后的回调 */
  onSuccess?: (data: any) => void;
  /** 轮询失败后的回调 */
  onError?: (error: Error) => void;
  /** 每次轮询时的回调 */
  onPolling?: (data: QueueResponseData) => void;
  /** 取消轮询时的回调 */
  onCancel?: () => void;
}

// 用于存储取消函数的映射
const cancelTokens = new Map<string, () => void>();

/**
 * 统一的队列API调用封装
 */
export async function withQueuePolling<T>(
  apiCall: (params: T) => Promise<QueueResponse>,
  params: T,
  config: PollConfig = {}
): Promise<QueueResponse> {
  const {
    interval = 10000,
    maxAttempts = 120,
    onSuccess,
    onError,
    onPolling,
    onCancel
  } = config;

  let attempts = 0;
  let lastNotificationPosition: number | undefined;
  let isCancelled = false;

  // 生成唯一的轮询ID
  const pollId = Math.random().toString(36).substring(7);

  // 创建取消函数
  const cancel = () => {
    isCancelled = true;
    notification.destroy(); // 关闭通知
    onCancel?.();
    cancelTokens.delete(pollId);
  };

  // 存储取消函数
  cancelTokens.set(pollId, cancel);

  const poll = async (): Promise<QueueResponse> => {
    try {
      if (isCancelled) {
        throw new Error('Operation canceled');
      }

      const response = await apiCall(params);
      
      // 处理队列状态
      if (response.code === 202 && 
         (response.data.status === QueueStatus.WAIT || response.data.status === QueueStatus.PROCESS)) {
        attempts++;
        
        // 获取队列位置和等待时间
        const { position, waiting, status } = response.data;
        
        // 如果位置发生变化，更新通知
        if ((position !== lastNotificationPosition || status === QueueStatus.PROCESS) && 
            position !== undefined && waiting !== undefined) {
          showQueueNotification(position, waiting, status, cancel);
          lastNotificationPosition = position;
        }

        // 调用轮询回调
        onPolling?.(response.data);

        // 检查是否达到最大尝试次数
        if (attempts >= maxAttempts) {
          notification.destroy(); // 关闭通知
          throw new Error('Exceeded the maximum polling limit');
        }

        // 继续轮询
        await new Promise(resolve => setTimeout(resolve, interval));
        return poll();
      }

      // 如果状态为ready，结束轮询
      if (response.code !== 202 && response.data) {
        notification.destroy(); // 关闭通知
        onSuccess?.(response.data);
        return response;
      }

      notification.destroy(); // 关闭通知
      return response;
    } catch (error) {
      notification.destroy(); // 关闭通知
      if (error instanceof Error) {
        onError?.(error);
      }
      throw error;
    } finally {
      cancelTokens.delete(pollId);
    }
  };

  return poll();
}

/**
 * 取消指定的轮询
 */
export function cancelPolling(pollId: string) {
  const cancel = cancelTokens.get(pollId);
  if (cancel) {
    cancel();
  }
}

/**
 * 取消所有轮询
 */
export function cancelAllPolling() {
  // 将 Map 转换为数组后再遍历
  Array.from(cancelTokens.values()).forEach(cancel => cancel());
  cancelTokens.clear();
}