import { DataSource } from 'typeorm';
import { PrintTaskService } from './print-task.service';
import { PrinterService } from './printer.service';
import { DelaySchedulerService } from './delay-scheduler.service';
import { FeieApiConfig, PrintType, PrintStatus, CancelReason } from '../types/feie.types';
import { FeieConfigMt } from '../entities/feie-config.mt.entity';
import { OrderMt } from '@d8d/orders-module-mt';

/**
 * 打印触发服务
 * 负责处理订单支付成功等事件触发的打印任务
 */
export class PrintTriggerService {
  private printTaskService: PrintTaskService;
  private printerService: PrinterService;
  private dataSource: DataSource;
  private feieConfig: FeieApiConfig;
  private configRepository: any;
  private orderRepository: any;

  constructor(dataSource: DataSource, feieConfig: FeieApiConfig) {
    this.dataSource = dataSource;
    this.feieConfig = feieConfig;
    this.printTaskService = new PrintTaskService(dataSource, feieConfig);
    this.printerService = new PrinterService(dataSource, feieConfig);
    this.configRepository = dataSource.getRepository(FeieConfigMt);
    this.orderRepository = dataSource.getRepository(OrderMt);
  }

  /**
   * 处理订单支付成功事件
   * @param tenantId 租户ID
   * @param orderId 订单ID
   * @param orderInfo 订单信息
   */
  async handleOrderPaymentSuccess(
    tenantId: number,
    orderId: number
  ): Promise<void> {
    try {
      console.debug(`[租户${tenantId}] 处理订单支付成功事件，订单ID: ${orderId}`);

      // 1. 获取完整的订单信息
      const fullOrderInfo = await this.getFullOrderInfo(tenantId, orderId);
      if (!fullOrderInfo) {
        console.warn(`[租户${tenantId}] 未找到订单信息，订单ID: ${orderId}，跳过打印任务`);
        return;
      }

      // 2. 获取防退款延迟时间
      const delaySeconds = await this.getAntiRefundDelaySeconds(tenantId);

      // 3. 获取默认打印机
      const defaultPrinter = await this.printerService.getDefaultPrinter(tenantId);
      if (!defaultPrinter) {
        console.warn(`[租户${tenantId}] 未找到默认打印机，跳过打印任务`);
        return;
      }

      // 4. 生成打印内容
      const printContent = await this.generateReceiptContent(tenantId, fullOrderInfo);

      // 5. 创建延迟打印任务
      await this.printTaskService.createPrintTask(tenantId, {
        orderId,
        printerSn: defaultPrinter.printerSn,
        content: printContent,
        printType: PrintType.RECEIPT,
        delaySeconds
      });

      console.debug(`[租户${tenantId}] 订单支付成功打印任务已创建，订单ID: ${orderId}, 延迟时间: ${delaySeconds}秒`);

      // 6. 自动启动延迟任务检查
      // 如果延迟时间为0或负数，立即触发打印
      // 如果延迟时间已过（比如配置错误或系统时间问题），也立即触发
      if (delaySeconds <= 0) {
        console.debug(`[租户${tenantId}] 延迟时间为${delaySeconds}秒，立即触发打印任务检查`);

        try {
          // 动态创建DelaySchedulerService实例
          const delaySchedulerService = new DelaySchedulerService(this.dataSource, this.feieConfig, tenantId);

          // 检查并启动调度器
          const status = delaySchedulerService.getStatus();
          if (!status.isRunning) {
            await delaySchedulerService.start();
            console.debug(`[租户${tenantId}] 延迟调度器已启动`);
          }

          const result = await delaySchedulerService.triggerManualProcess(tenantId);

          if (result.success) {
            console.debug(`[租户${tenantId}] 立即触发打印成功，处理了${result.processedTasks}个任务`);
          } else {
            console.warn(`[租户${tenantId}] 立即触发打印失败: ${result.message}`);
          }
        } catch (error) {
          console.warn(`[租户${tenantId}] 创建延迟调度器失败:`, error);
          // 不抛出错误，避免影响主流程
        }
      } else {
        // 对于有延迟的任务，也启动调度器（如果未运行）
        try {
          console.debug(`[租户${tenantId}] 检查并启动延迟调度器...`);
          const delaySchedulerService = new DelaySchedulerService(this.dataSource, this.feieConfig, tenantId);

          // 检查调度器状态
          const status = delaySchedulerService.getStatus();
          if (!status.isRunning) {
            await delaySchedulerService.start();
            console.debug(`[租户${tenantId}] 延迟调度器已启动`);
          } else {
            console.debug(`[租户${tenantId}] 延迟调度器已在运行中`);
          }
        } catch (error) {
          console.warn(`[租户${tenantId}] 启动调度器失败:`, error);
          // 不抛出错误，避免影响主流程
        }
      }
    } catch (error) {
      console.error(`[租户${tenantId}] 处理订单支付成功事件失败，订单ID: ${orderId}:`, error);
      // 不抛出错误，避免影响支付流程
    }
  }

  /**
   * 处理订单退款事件
   * @param tenantId 租户ID
   * @param orderId 订单ID
   */
  async handleOrderRefund(
    tenantId: number,
    orderId: number
  ): Promise<void> {
    try {
      console.debug(`[租户${tenantId}] 处理订单退款事件，订单ID: ${orderId}`);

      // 1. 查找关联的打印任务
      const { tasks: printTasks } = await this.printTaskService.getPrintTasks(tenantId, {
        orderId,
        printStatus: PrintStatus.PENDING // 先查询PENDING状态的任务
      });

      if (printTasks.length === 0) {
        console.debug(`[租户${tenantId}] 未找到关联的打印任务，订单ID: ${orderId}`);
        return;
      }

      // 2. 取消所有关联的打印任务
      for (const task of printTasks) {
        await this.printTaskService.cancelPrintTask(tenantId, task.taskId, CancelReason.REFUND);
        console.debug(`[租户${tenantId}] 打印任务已取消，任务ID: ${task.taskId}, 订单ID: ${orderId}`);
      }

      console.debug(`[租户${tenantId}] 订单退款事件处理完成，取消 ${printTasks.length} 个打印任务`);
    } catch (error) {
      console.error(`[租户${tenantId}] 处理订单退款事件失败，订单ID: ${orderId}:`, error);
      // 不抛出错误，避免影响退款流程
    }
  }

  /**
   * 获取防退款延迟时间（秒）
   */
  private async getAntiRefundDelaySeconds(tenantId: number): Promise<number> {
    try {
      const delayValue = await this.getConfigValue(tenantId, 'feie.anti_refund_delay', '120');
      const delaySeconds = parseInt(delayValue, 10);

      // 验证延迟时间范围
      if (isNaN(delaySeconds) || delaySeconds < 0) {
        console.warn(`[租户${tenantId}] 无效的防退款延迟时间配置: ${delayValue}，使用默认值120秒`);
        return 120;
      }

      // 限制最大延迟时间（例如24小时）
      const maxDelay = 24 * 60 * 60; // 24小时
      if (delaySeconds > maxDelay) {
        console.warn(`[租户${tenantId}] 防退款延迟时间超过最大值: ${delaySeconds}秒，限制为${maxDelay}秒`);
        return maxDelay;
      }

      return delaySeconds;
    } catch (error) {
      console.warn(`[租户${tenantId}] 获取防退款延迟时间失败，使用默认值120秒:`, error);
      return 120;
    }
  }

  /**
   * 获取完整的订单信息
   */
  private async getFullOrderInfo(
    tenantId: number,
    orderId: number
  ): Promise<{
    orderNo: string;
    amount: number;
    userId: number;
    items?: Array<{
      name: string | null;
      quantity: number;
      price: number;
    }>;
    // 新增字段
    payAmount: number;
    freightAmount: number;
    address: string | null;
    receiverMobile: string | null;
    recevierName: string | null;
    state: number;
    payState: number;
    createdAt: Date;
    remark: string | null;
  } | null> {
    try {
      const order = await this.orderRepository.findOne({
        where: { tenantId, id: orderId },
        relations: ['orderGoods'] // 关联订单商品
      });

      if (!order) {
        console.warn(`[租户${tenantId}] 未找到订单，订单ID: ${orderId}`);
        return null;
      }

      // 构建完整的订单信息
      return {
        orderNo: order.orderNo,
        amount: order.amount,
        userId: order.userId,
        items: order.orderGoods?.map((goods: any) => ({
          name: goods.goodsName,
          quantity: goods.num,
          price: goods.price
        })) || [],
        // 新增字段
        payAmount: order.payAmount,
        freightAmount: order.freightAmount,
        address: order.address,
        receiverMobile: order.receiverMobile,
        recevierName: order.recevierName,
        state: order.state,
        payState: order.payState,
        createdAt: order.createdAt,
        remark: order.remark
      };
    } catch (error) {
      console.error(`[租户${tenantId}] 获取完整订单信息失败，订单ID: ${orderId}:`, error);
      return null;
    }
  }

  /**
   * 获取配置值
   */
  private async getConfigValue(tenantId: number, key: string, defaultValue: string): Promise<string> {
    try {
      const config = await this.configRepository.findOne({
        where: { tenantId, configKey: key }
      });

      return config?.configValue || defaultValue;
    } catch (error) {
      console.warn(`[租户${tenantId}] 获取配置失败，key: ${key}:`, error);
      return defaultValue;
    }
  }

  /**
   * 获取打印模板
   */
  private async getPrintTemplate(tenantId: number): Promise<string> {
    try {
      const template = await this.getConfigValue(tenantId, 'feie.receipt_template', '');

      if (template) {
        return template;
      }

      // 如果没有配置模板，使用默认模板
      return `
<CB>订单收据</CB>
<BR>
订单号: {orderNo}
下单时间: {orderTime}
<BR>
<B>收货信息</B>
收货人: {receiverName}
联系电话: {receiverPhone}
收货地址: {address}
<BR>
<B>商品信息</B>
{goodsList}
<BR>
<B>费用明细</B>
商品总额: {totalAmount}
运费: {freightAmount}
实付金额: {payAmount}
<BR>
<B>订单状态</B>
订单状态: {orderStatus}
支付状态: {payStatus}
<BR>
<B>订单备注</B>
{remark}
<BR>
<C>感谢您的惠顾！</C>
<BR>
<QR>{orderNo}</QR>
`;
    } catch (error) {
      console.warn(`[租户${tenantId}] 获取打印模板失败，使用默认模板:`, error);
      return `
<CB>订单收据</CB>
<BR>
订单号: {orderNo}
下单时间: {orderTime}
<BR>
<B>收货信息</B>
收货人: {receiverName}
联系电话: {receiverPhone}
收货地址: {address}
<BR>
<B>商品信息</B>
{goodsList}
<BR>
<B>费用明细</B>
商品总额: {totalAmount}
运费: {freightAmount}
实付金额: {payAmount}
<BR>
<B>订单状态</B>
订单状态: {orderStatus}
支付状态: {payStatus}
<BR>
<B>订单备注</B>
{remark}
<BR>
<C>感谢您的惠顾！</C>
<BR>
<QR>{orderNo}</QR>
`;
    }
  }

  /**
   * 生成小票打印内容
   */
  private async generateReceiptContent(
    tenantId: number,
    orderInfo: {
      orderNo: string;
      amount: number;
      userId: number;
      items?: Array<{
        name: string | null;
        quantity: number;
        price: number;
      }>;
      // 新增字段
      payAmount: number;
      freightAmount: number;
      address: string | null;
      receiverMobile: string | null;
      recevierName: string | null;
      state: number;
      payState: number;
      createdAt: Date;
      remark: string | null;
    }
  ): Promise<string> {
    const {
      orderNo,
      amount,
      items = [],
      payAmount,
      freightAmount,
      address,
      receiverMobile,
      recevierName,
      state,
      payState,
      createdAt,
      remark
    } = orderInfo;

    // 字符串长度限制函数（按中文字符计算）
    const limitStringLength = (str: string, maxLength: number): string => {
      if (!str || str.length <= maxLength) {
        return str;
      }

      // 计算字符长度（中文字符算1个长度）
      let length = 0;
      let result = '';

      for (const char of str) {
        // 中文字符范围判断
        const charCode = char.charCodeAt(0);
        if (charCode >= 0x4E00 && charCode <= 0x9FFF) {
          length += 1; // 中文字符
        } else {
          length += 0.5; // 英文字符和数字算半个长度
        }

        if (length <= maxLength) {
          result += char;
        } else {
          break;
        }
      }

      // 如果被截断，添加省略号
      if (result.length < str.length) {
        result += '...';
      }

      return result;
    };

    try {
      // 1. 获取打印模板
      const template = await this.getPrintTemplate(tenantId);

      // 2. 准备模板变量
      // 状态映射函数
      const getOrderStatusLabel = (state: number): string => {
        const statusMap: Record<number, string> = {
          0: '未发货',
          1: '已发货',
          2: '收货成功',
          3: '已退货'
        };
        return statusMap[state] || '未知';
      };

      const getPayStatusLabel = (payState: number): string => {
        const payStatusMap: Record<number, string> = {
          0: '未支付',
          1: '支付中',
          2: '支付成功',
          3: '已退款',
          4: '支付失败',
          5: '订单关闭'
        };
        return payStatusMap[payState] || '未知';
      };

      // 确保金额是数字类型
      const safeAmount = typeof amount === 'number' ? amount : parseFloat(amount as any) || 0;
      const safePayAmount = typeof payAmount === 'number' ? payAmount : parseFloat(payAmount as any) || 0;
      const safeFreightAmount = typeof freightAmount === 'number' ? freightAmount : parseFloat(freightAmount as any) || 0;

      const variables = {
        orderNo,
        orderTime: new Date(createdAt).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' }),
        receiverName: recevierName || '客户',
        receiverPhone: receiverMobile || '未提供',
        phone: receiverMobile || '未提供', // 兼容变量
        address: address || '未提供地址',
        goodsList: (() => {
          const goodsLines = items.map(item => {
            const itemName = item.name || '未命名商品';
            const itemPrice = typeof item.price === 'number' ? item.price : parseFloat(item.price as any) || 0;
            const itemQuantity = typeof item.quantity === 'number' ? item.quantity : parseInt(item.quantity as any, 10) || 0;
            const itemTotal = itemPrice * itemQuantity;
            return `${itemName}  ${itemPrice} × ${itemQuantity} = ${itemTotal.toFixed(2)}`;
          }).join('\n') || '暂无商品信息';

          // 限制商品列表总长度在500字以内
          return limitStringLength(goodsLines, 2000);
        })(),
        totalAmount: `${safeAmount.toFixed(2)}`,
        freightAmount: `${safeFreightAmount.toFixed(2)}`,
        payAmount: `${safePayAmount.toFixed(2)}`,
        orderStatus: getOrderStatusLabel(state),
        payStatus: getPayStatusLabel(payState),
        remark: remark || '无备注'
      };

      // 替换模板变量
      let content = template;
      for (const [key, value] of Object.entries(variables)) {
        content = content.replace(new RegExp(`{${key}}`, 'g'), value);
      }

      return content.trim();
    } catch (error) {
      console.warn(`[租户${tenantId}] 生成打印内容失败，使用简单模板:`, error);

      // 失败时使用简单的回退模板
      const lines = [
        '<CB>订单小票</CB><BR>',
        '------------------------<BR>',
        `<B>订单号：</B>${orderNo}<BR>`,
        `<B>下单时间：</B>${new Date(createdAt).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })}<BR>`,
        `<B>收货人：</B>${recevierName || '客户'}<BR>`,
        `<B>联系电话：</B>${receiverMobile || '未提供'}<BR>`,
        `<B>地址：</B>${address || '未提供地址'}<BR>`,
        '------------------------<BR>',
        '<B>商品明细：</B><BR>'
      ];

      // 添加商品明细
      const goodsDetails: string[] = [];
      items.forEach(item => {
        const itemPrice = typeof item.price === 'number' ? item.price : parseFloat(item.price as any) || 0;
        const itemQuantity = typeof item.quantity === 'number' ? item.quantity : parseInt(item.quantity as any, 10) || 0;
        const itemTotal = itemPrice * itemQuantity;
        const itemName = item.name || '未命名商品';
        goodsDetails.push(`${itemName} x${itemQuantity}<BR>`);
        goodsDetails.push(`  ￥${itemPrice.toFixed(2)} x ${itemQuantity} = ￥${itemTotal.toFixed(2)}<BR>`);
      });

      // 限制商品明细总长度在100字以内
      const goodsDetailsStr = goodsDetails.join('');
      const limitedGoodsDetails = limitStringLength(goodsDetailsStr, 2000);

      // 将限制后的商品明细添加到lines中
      if (limitedGoodsDetails) {
        lines.push(limitedGoodsDetails);
      } else {
        lines.push('暂无商品信息<BR>');
      }

      // 添加总计
      const safeAmount = typeof amount === 'number' ? amount : parseFloat(amount as any) || 0;
      const safePayAmount = typeof payAmount === 'number' ? payAmount : parseFloat(payAmount as any) || 0;
      const safeFreightAmount = typeof freightAmount === 'number' ? freightAmount : parseFloat(freightAmount as any) || 0;

      lines.push('------------------------<BR>');
      lines.push(`<B>商品总额：</B>￥${safeAmount.toFixed(2)}<BR>`);
      lines.push(`<B>运费：</B>￥${safeFreightAmount.toFixed(2)}<BR>`);
      lines.push(`<B>实付金额：</B>￥${safePayAmount.toFixed(2)}<BR>`);
      lines.push('------------------------<BR>');
      // 添加备注信息
      const displayRemark = remark || '无备注';
      lines.push(`<B>订单备注：</B>${displayRemark}<BR>`);
      lines.push('------------------------<BR>');
      lines.push('<B>感谢您的惠顾！</B><BR>');
      lines.push('<QR>https://example.com/order/' + orderNo + '</QR><BR>');

      return lines.join('');
    }
  }
}