/**
 * Taro 存储接口
 */
interface StorageInterface {
  setStorage: (options: { key: string; data: any }) => Promise<any>;
  getStorage: (options: { key: string }) => Promise<{ data: any }>;
}

/**
 * 任务状态枚举
 */
export enum TaskStatus {
  PENDING = 'pending',    // 待开始
  RUNNING = 'running',    // 执行中  
  SUCCESS = 'success',    // 成功
  FAILED = 'failed',      // 失败
  TIMEOUT = 'timeout',    // 超时
  CANCELLED = 'cancelled' // 已取消
}

/**
 * 任务配置接口
 */
export interface TaskConfig {
  taskId: string;           // 任务ID
  pollingInterval: number;  // 轮询间隔(毫秒)
  maxRetries: number;       // 最大重试次数
  timeout: number;          // 超时时间(毫秒)
  onProgress?: (status: TaskStatus, data?: any) => void;
  onSuccess?: (result: any) => void;
  onError?: (error: Error) => void;
  onTimeout?: () => void;
}

/**
 * 任务数据结构
 */
export interface TaskData {
  id: string;
  status: TaskStatus;
  startTime: number;
  retryCount: number;
  lastPollTime: number;
  result?: any;
  error?: string;
  config: TaskConfig;
}

/**
 * 状态检查函数类型
 */
type StatusChecker = (taskId: string) => Promise<TaskStatus>;

/**
 * 异步任务管理器
 * 专为 Taro 环境设计的异步任务管理工具
 */
export class AsyncTaskManager {
  private activeTasks: Map<string, TaskData> = new Map();
  private pollingTimers: Map<string, number> = new Map();
  private statusChecker?: StatusChecker;
  private isPaused: boolean = false;
  private storage?: StorageInterface;

  /**
   * 构造函数
   * @param storage 存储接口实现（测试时可注入mock）
   */
  constructor(storage?: StorageInterface) {
    this.storage = storage;
    
    // 如果没有注入存储，尝试使用真实的 Taro
    if (!this.storage && typeof window !== 'undefined') {
      try {
        const Taro = require('@tarojs/taro');
        this.storage = {
          setStorage: Taro.setStorage,
          getStorage: Taro.getStorage
        };
      } catch (error) {
        console.warn('无法加载 Taro，存储功能将不可用');
      }
    }
  }

  /**
   * 设置状态检查函数（用于测试和自定义状态检查）
   */
  setStatusChecker(checker: StatusChecker) {
    this.statusChecker = checker;
  }

  /**
   * 启动新任务
   */
  async startTask(config: TaskConfig): Promise<void> {
    const taskData: TaskData = {
      id: config.taskId,
      status: TaskStatus.RUNNING,
      startTime: Date.now(),
      retryCount: 0,
      lastPollTime: Date.now(),
      config
    };

    this.activeTasks.set(config.taskId, taskData);
    await this.saveTaskToStorage(taskData);
    
    if (!this.isPaused) {
      this.startPolling(config.taskId);
    }
  }

  /**
   * 检查任务是否存在
   */
  hasTask(taskId: string): boolean {
    return this.activeTasks.has(taskId);
  }

  /**
   * 获取任务状态
   */
  getTaskStatus(taskId: string): TaskStatus | null {
    const task = this.activeTasks.get(taskId);
    return task ? task.status : null;
  }

  /**
   * 取消任务
   */
  async cancelTask(taskId: string): Promise<void> {
    const task = this.activeTasks.get(taskId);
    if (task) {
      task.status = TaskStatus.CANCELLED;
      this.stopPolling(taskId);
      await this.saveTaskToStorage(task);
    }
  }

  /**
   * 开始轮询任务状态
   */
  private startPolling(taskId: string): void {
    const task = this.activeTasks.get(taskId);
    if (!task || this.isPaused) return;

    // 先清除现有的定时器
    this.stopPolling(taskId);

    const timer = setTimeout(async () => {
      await this.pollTaskStatus(taskId);
    }, task.config.pollingInterval);

    this.pollingTimers.set(taskId, timer as any);
  }

  /**
   * 停止轮询
   */
  private stopPolling(taskId: string): void {
    const timer = this.pollingTimers.get(taskId);
    if (timer) {
      clearTimeout(timer);
      this.pollingTimers.delete(taskId);
    }
  }

  /**
   * 轮询任务状态
   */
  private async pollTaskStatus(taskId: string): Promise<void> {
    const task = this.activeTasks.get(taskId);
    if (!task || task.status !== TaskStatus.RUNNING) {
      return;
    }

    // 检查超时
    if (Date.now() - task.startTime > task.config.timeout) {
      task.status = TaskStatus.TIMEOUT;
      this.stopPolling(taskId);
      task.config.onTimeout?.();
      await this.saveTaskToStorage(task);
      return;
    }

    try {
      let status: TaskStatus;
      
      if (this.statusChecker) {
        status = await this.statusChecker(taskId);
      } else {
        status = TaskStatus.RUNNING; // 默认状态
      }

      task.status = status;
      task.lastPollTime = Date.now();
      task.retryCount = 0; // 重置重试计数

      // 触发进度回调
      task.config.onProgress?.(status);

      if (status === TaskStatus.SUCCESS) {
        task.config.onSuccess?.(task.result);
        await this.saveTaskToStorage(task);
        return;
      }

      if (status === TaskStatus.FAILED) {
        task.config.onError?.(new Error('Task failed'));
        await this.saveTaskToStorage(task);
        return;
      }

      // 如果仍在运行，继续轮询
      if (status === TaskStatus.RUNNING && !this.isPaused) {
        this.startPolling(taskId);
      }

      await this.saveTaskToStorage(task);

    } catch (error) {
      task.retryCount++;

      if (task.retryCount >= task.config.maxRetries) {
        task.status = TaskStatus.FAILED;
        task.error = error instanceof Error ? error.message : String(error);
        task.config.onError?.(error instanceof Error ? error : new Error(String(error)));
        await this.saveTaskToStorage(task);
      } else {
        // 重试
        if (!this.isPaused) {
          this.startPolling(taskId);
        }
      }
    }
  }

  /**
   * 暂停所有任务的轮询
   */
  pausePolling(): void {
    this.isPaused = true;
    for (const taskId of this.pollingTimers.keys()) {
      this.stopPolling(taskId);
    }
  }

  /**
   * 激活所有任务的轮询
   */
  activatePolling(): void {
    this.isPaused = false;
    for (const [taskId, task] of this.activeTasks) {
      if (task.status === TaskStatus.RUNNING) {
        this.startPolling(taskId);
      }
    }
  }

  /**
   * 恢复任务（从存储中加载）
   */
  async resumeTasks(): Promise<void> {
    try {
      const storedTasks = await this.loadTasksFromStorage();
      
      for (const taskData of storedTasks) {
        this.activeTasks.set(taskData.id, taskData);
        
        // 只恢复运行中的任务
        if (taskData.status === TaskStatus.RUNNING && !this.isPaused) {
          this.startPolling(taskData.id);
        }
      }
    } catch (error) {
      console.error('恢复任务失败:', error);
    }
  }

  /**
   * 保存任务到本地存储
   */
  private async saveTaskToStorage(task: TaskData): Promise<void> {
    if (!this.storage) {
      console.warn('存储接口不可用，跳过保存');
      return;
    }

    try {
      const existingTasks = await this.loadTasksFromStorage();
      const tasksMap = existingTasks.reduce((map, t) => {
        map[t.id] = t;
        return map;
      }, {} as Record<string, TaskData>);

      tasksMap[task.id] = {
        ...task,
        lastSaveTime: Date.now()
      } as any;

      await this.storage.setStorage({
        key: 'async_tasks',
        data: tasksMap
      });
    } catch (error) {
      console.error('保存任务失败:', error);
    }
  }

  /**
   * 从本地存储加载任务
   */
  private async loadTasksFromStorage(): Promise<TaskData[]> {
    if (!this.storage) {
      return [];
    }

    try {
      const result = await this.storage.getStorage({ key: 'async_tasks' });
      if (result.data && typeof result.data === 'object') {
        return Object.values(result.data) as TaskData[];
      }
      return [];
    } catch (error) {
      return [];
    }
  }
}