import { DataSource } from 'typeorm';
import * as cron from 'node-cron';
import { PrintTaskService } from './print-task.service';
import { FeieApiConfig, CancelReason, PrintStatus } from '../types/feie.types';
import { OrderMt } from '@d8d/orders-module-mt';

export class DelaySchedulerService {
  private printTaskService: PrintTaskService;
  private isRunning: boolean = false;
  private cronJob: cron.ScheduledTask | null = null;
  private defaultDelaySeconds: number = 120; // 默认2分钟延迟
  private tenantId: number | null = null; // 租户ID，null表示处理所有租户

  private dataSource: DataSource;
  private orderRepository: any | null;

  constructor(dataSource: DataSource, feieConfig: FeieApiConfig, tenantId?: number) {
    this.dataSource = dataSource;
    this.printTaskService = new PrintTaskService(dataSource, feieConfig);
    this.tenantId = tenantId || null;

    // 尝试获取订单仓库，如果不可用则设置为null
    try {
      this.orderRepository = dataSource.getRepository(OrderMt);
    } catch (error) {
      console.warn('无法获取订单仓库，订单退款检查功能将不可用:', error);
      this.orderRepository = null;
    }
  }

  /**
   * 启动调度器
   */
  async start(): Promise<void> {
    if (this.isRunning) {
      throw new Error('调度器已经在运行中');
    }

    console.log('启动防退款延迟打印调度器...');

    // 每30秒检查一次待处理的延迟打印任务
    this.cronJob = cron.schedule('*/30 * * * * *', async () => {
      await this.processDelayedTasks();
    });

    this.isRunning = true;
    console.log('防退款延迟打印调度器已启动');
  }

  /**
   * 停止调度器
   */
  async stop(): Promise<void> {
    if (!this.isRunning) {
      throw new Error('调度器未在运行中');
    }

    console.log('停止防退款延迟打印调度器...');

    if (this.cronJob) {
      this.cronJob.stop();
      this.cronJob = null;
    }

    this.isRunning = false;
    console.log('防退款延迟打印调度器已停止');
  }

  /**
   * 处理延迟打印任务
   */
  private async processDelayedTasks(): Promise<void> {
    try {
      console.log('开始检查延迟打印任务...');

      if (this.tenantId !== null) {
        // 只处理指定租户的延迟任务
        console.log(`处理租户 ${this.tenantId} 的延迟任务`);
        await this.processTenantDelayedTasks(this.tenantId);
      } else {
        // 处理所有租户的延迟任务（向后兼容）
        const tenantIds = await this.getTenantsWithDelayedTasks();

        if (tenantIds.length === 0) {
          console.log('没有找到有延迟任务的租户');
          return;
        }

        console.log(`找到 ${tenantIds.length} 个有延迟任务的租户`);

        // 处理每个租户的延迟任务
        for (const tenantId of tenantIds) {
          await this.processTenantDelayedTasks(tenantId);
        }
      }

      console.log('延迟任务检查完成');
    } catch (error) {
      console.error('处理延迟打印任务失败:', error);
    }
  }


  /**
   * 处理指定租户的延迟打印任务
   */
  private async processTenantDelayedTasks(tenantId: number): Promise<void> {
    try {
      // 获取待处理的延迟打印任务
      const pendingTasks = await this.printTaskService.getPendingDelayedTasks(tenantId);

      if (pendingTasks.length === 0) {
        return;
      }

      console.log(`租户 ${tenantId} 有 ${pendingTasks.length} 个待处理的延迟打印任务`);

      // 处理每个任务
      for (const task of pendingTasks) {
        await this.processSingleDelayedTask(tenantId, task);
      }
    } catch (error) {
      console.error(`处理租户 ${tenantId} 的延迟打印任务失败:`, error);
    }
  }

  /**
   * 处理单个延迟打印任务
   */
  private async processSingleDelayedTask(tenantId: number, task: any): Promise<void> {
    try {
      console.log(`处理延迟打印任务: ${task.taskId}, 订单ID: ${task.orderId}`);

      // 0. 检查任务状态，避免重复处理
      // 如果任务已经是最终状态（SUCCESS, FAILED, CANCELLED），跳过处理
      if ([PrintStatus.SUCCESS, PrintStatus.FAILED, PrintStatus.CANCELLED].includes(task.printStatus as PrintStatus)) {
        console.log(`任务 ${task.taskId} 状态为 ${task.printStatus}，跳过处理`);
        return;
      }

      // 1. 检查订单状态（验证是否已退款）
      if (task.orderId) {
        const shouldCancel = await this.shouldCancelDueToRefund(tenantId, task.orderId);
        if (shouldCancel) {
          console.log(`订单 ${task.orderId} 已退款，取消打印任务 ${task.taskId}`);
          await this.printTaskService.cancelPrintTask(tenantId, task.taskId, CancelReason.REFUND);
          return;
        }
      }

      // 2. 执行打印任务
      console.log(`执行延迟打印任务: ${task.taskId}`);
      await this.printTaskService.executePrintTask(tenantId, task.taskId);
      console.log(`延迟打印任务完成: ${task.taskId}`);

    } catch (error) {
      console.error(`处理延迟打印任务失败 ${task.taskId}:`, error);

      // 如果是任务已完成或已取消的错误，记录但不取消（因为任务已经处于最终状态）
      const errorMessage = error instanceof Error ? error.message : String(error);
      if (errorMessage.includes('打印任务已完成') || errorMessage.includes('打印任务已取消')) {
        console.log(`任务 ${task.taskId} 已完成或已取消，跳过错误处理`);
        return;
      }

      // 如果是订单状态检查失败，可能是订单不存在或其他问题
      // 在这种情况下，我们取消任务以避免无限重试
      if (errorMessage.includes('订单') || errorMessage.includes('Order')) {
        console.log(`因订单检查失败取消任务 ${task.taskId}`);
        await this.printTaskService.cancelPrintTask(tenantId, task.taskId, CancelReason.TIMEOUT);
      }
    }
  }

  /**
   * 检查订单是否应该因退款而取消打印
   */
  private async shouldCancelDueToRefund(tenantId: number, orderId: number): Promise<boolean> {
    try {
      // 如果订单仓库不可用，跳过检查
      if (!this.orderRepository) {
        console.debug('订单仓库不可用，跳过退款检查');
        return false;
      }

      // 查询订单状态
      const order = await this.orderRepository.findOne({
        where: { id: orderId, tenantId }
      });

      if (!order) {
        console.warn(`订单 ${orderId} 不存在，租户 ${tenantId}`);
        return true; // 订单不存在，取消打印
      }

      // 检查支付状态：3 = 已退款
      if (order.payState === 3) {
        console.log(`订单 ${orderId} 支付状态为已退款 (${order.payState})`);
        return true;
      }

      // 检查订单状态：5 = 订单关闭（可能包含退款）
      if (order.state === 5) {
        console.log(`订单 ${orderId} 状态为已关闭 (${order.state})`);
        return true;
      }

      return false;
    } catch (error) {
      console.error(`检查订单退款状态失败，订单ID: ${orderId}, 租户: ${tenantId}:`, error);
      // 如果检查失败，保守起见不取消任务，让下次调度再试
      return false;
    }
  }

  /**
   * 设置默认延迟时间
   */
  setDefaultDelaySeconds(seconds: number): void {
    if (seconds < 0) {
      throw new Error('延迟时间不能为负数');
    }

    this.defaultDelaySeconds = seconds;
    console.log(`默认延迟时间已设置为 ${seconds} 秒`);
  }

  /**
   * 获取默认延迟时间
   */
  getDefaultDelaySeconds(): number {
    return this.defaultDelaySeconds;
  }

  /**
   * 检查调度器状态
   */
  getStatus(): {
    isRunning: boolean;
    defaultDelaySeconds: number;
    tenantId: number | null;
    lastProcessTime?: Date;
  } {
    return {
      isRunning: this.isRunning,
      defaultDelaySeconds: this.defaultDelaySeconds,
      tenantId: this.tenantId
    };
  }

  /**
   * 手动触发任务处理
   */
  async triggerManualProcess(tenantId?: number): Promise<{
    success: boolean;
    processedTasks: number;
    message: string;
  }> {
    try {
      // 使用指定的tenantId或调度器的tenantId
      const targetTenantId = tenantId !== undefined ? tenantId : this.tenantId;

      if (targetTenantId === null) {
        return {
          success: false,
          processedTasks: 0,
          message: '未指定租户ID，无法手动处理任务'
        };
      }

      const pendingTasks = await this.printTaskService.getPendingDelayedTasks(targetTenantId);
      let processedCount = 0;

      for (const task of pendingTasks) {
        try {
          await this.printTaskService.executePrintTask(targetTenantId, task.taskId);
          processedCount++;
        } catch (error) {
          console.error(`手动处理任务失败 ${task.taskId}:`, error);
        }
      }

      return {
        success: true,
        processedTasks: processedCount,
        message: `成功处理 ${processedCount} 个延迟打印任务`
      };
    } catch (error) {
      return {
        success: false,
        processedTasks: 0,
        message: `手动处理失败: ${error instanceof Error ? error.message : '未知错误'}`
      };
    }
  }

  /**
   * 健康检查
   */
  async healthCheck(): Promise<{
    healthy: boolean;
    isRunning: boolean;
    lastError?: string;
    timestamp: Date;
  }> {
    try {
      // 简单的健康检查：检查调度器是否在运行
      return {
        healthy: this.isRunning,
        isRunning: this.isRunning,
        timestamp: new Date()
      };
    } catch (error) {
      return {
        healthy: false,
        isRunning: this.isRunning,
        lastError: error instanceof Error ? error.message : '健康检查失败',
        timestamp: new Date()
      };
    }
  }

  /**
   * 获取有延迟打印任务的租户ID列表
   */
  private async getTenantsWithDelayedTasks(): Promise<number[]> {
    try {
      let query: string;
      let params: any[] = [];

      if (this.tenantId !== null) {
        // 只查询指定租户
        query = `
          SELECT DISTINCT tenant_id
          FROM feie_print_task_mt
          WHERE tenant_id = $1
            AND (print_status = 'DELAYED' OR print_status = 'PENDING')
            AND scheduled_at <= NOW()
          ORDER BY tenant_id
        `;
        params = [this.tenantId];
      } else {
        // 查询所有租户
        query = `
          SELECT DISTINCT tenant_id
          FROM feie_print_task_mt
          WHERE (print_status = 'DELAYED' OR print_status = 'PENDING')
            AND scheduled_at <= NOW()
          ORDER BY tenant_id
        `;
      }

      const result = await this.dataSource.query(query, params);
      return result.map((row: any) => row.tenant_id);
    } catch (error) {
      console.error('获取有延迟任务的租户失败:', error);
      return [];
    }
  }

}
