import { GenericCrudService } from '@d8d/shared-crud';
import { DataSource, Repository, In } from 'typeorm';
import { OrderMt } from '../entities/order.mt.entity';
import { OrderGoodsMt } from '../entities/order-goods.mt.entity';
import { OrderRefundMt } from '../entities/order-refund.mt.entity';
import { GoodsMt } from '@d8d/goods-module-mt';
import { DeliveryAddressMt } from '@d8d/delivery-address-module-mt';
import { PaymentMtService } from '@d8d/mini-payment-mt';
import { CreditBalanceService } from '@d8d/credit-balance-module-mt';
import { PaymentMtEntity, PaymentStatus } from '@d8d/mini-payment-mt';
import type { CreateOrderRequest } from '../schemas/create-order.schema';

export class OrderMtService extends GenericCrudService<OrderMt> {
  private orderGoodsRepository: Repository<OrderGoodsMt>;
  private goodsRepository: Repository<GoodsMt>;
  private deliveryAddressRepository: Repository<DeliveryAddressMt>;
  private orderRefundRepository: Repository<OrderRefundMt>;
  private paymentMtService: PaymentMtService;
  private creditBalanceService: CreditBalanceService;

  constructor(dataSource: DataSource) {
    super(dataSource, OrderMt, {
      tenantOptions: { enabled: true, tenantIdField: 'tenantId' }
    });
    this.orderGoodsRepository = dataSource.getRepository(OrderGoodsMt);
    this.goodsRepository = dataSource.getRepository(GoodsMt);
    this.deliveryAddressRepository = dataSource.getRepository(DeliveryAddressMt);
    this.orderRefundRepository = dataSource.getRepository(OrderRefundMt);
    this.paymentMtService = new PaymentMtService(dataSource);
    this.creditBalanceService = new CreditBalanceService(dataSource);
  }

  /**
   * 创建订单
   * @param data 创建订单请求数据
   * @param userId 用户ID
   * @param tenantId 租户ID
   * @returns 创建的订单信息
   */
  async createOrder(data: CreateOrderRequest, userId: number, tenantId: number): Promise<{
    success: boolean;
    orderId: number;
    orderNo: string;
    amount: number;
    payAmount: number;
    message: string;
  }> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const { addressId, productOwn, consumeFrom, products, remark } = data;

      // 验证商品信息并计算总价
      let totalAmount = 0;
      let totalCostAmount = 0;
      const goodsInfo = [];

      for (const item of products) {
        const goods = await this.goodsRepository.findOne({
          where: { id: item.id, tenantId }
        });

        if (!goods) {
          throw new Error(`商品ID ${item.id} 不存在`);
        }

        if (goods.stock < item.num) {
          throw new Error(`商品 ${goods.name} 库存不足`);
        }

        const itemAmount = goods.price * item.num;
        const itemCostAmount = goods.costPrice * item.num;

        totalAmount += itemAmount;
        totalCostAmount += itemCostAmount;

        goodsInfo.push({
          goods,
          quantity: item.num,
          amount: itemAmount,
          costAmount: itemCostAmount
        });
      }

      // 收集需要查询的父商品ID
      const parentGoodsIds = new Set<number>();
      for (const info of goodsInfo) {
        if (info.goods.spuId > 0) {
          parentGoodsIds.add(info.goods.spuId);
        }
      }

      // 批量查询父商品信息
      const parentGoodsMap = new Map<number, GoodsMt>();
      if (parentGoodsIds.size > 0) {
        const parentGoods = await this.goodsRepository.find({
          where: { id: In([...parentGoodsIds]), tenantId }
        });
        parentGoods.forEach(g => parentGoodsMap.set(g.id, g));
      }

      // 获取收货地址信息
      let deliveryAddress = null;
      if (addressId) {
        deliveryAddress = await this.deliveryAddressRepository.findOne({
          where: { id: addressId, userId, tenantId }
        });

        if (!deliveryAddress) {
          throw new Error('收货地址不存在');
        }
      }

      // 生成订单号
      const orderNo = this.generateOrderNo();

      // 创建订单
      const order = this.repository.create({
        tenantId,
        orderNo,
        userId,
        amount: totalAmount,
        costAmount: totalCostAmount,
        payAmount: totalAmount, // 这里可以根据优惠规则计算实际支付金额
        orderType: 1, // 实物订单
        payType: consumeFrom === '积分兑换' ? 1 : 2, // 根据消费来源设置支付类型
        payState: 0, // 未支付
        state: 0, // 未发货
        addressId: addressId || 0,
        merchantId: goodsInfo[0]?.goods.merchantId || 0,
        supplierId: goodsInfo[0]?.goods.supplierId || 0,
        remark: remark || '',
        createdBy: userId,
        updatedBy: userId,
        // 设置收货地址信息（如果提供）
        ...(deliveryAddress && {
          receiverMobile: deliveryAddress.phone,
          recevierName: deliveryAddress.name,
          recevierProvince: deliveryAddress.receiverProvince,
          recevierCity: deliveryAddress.receiverCity,
          recevierDistrict: deliveryAddress.receiverDistrict,
          recevierTown: deliveryAddress.receiverTown,
          address: deliveryAddress.address
        })
      });

      const savedOrder = await queryRunner.manager.save(order);

      // 创建订单商品明细
      const orderGoodsList = goodsInfo.map(info => {
        let goodsName = info.goods.name;
        if (info.goods.spuId > 0) {
          const parentGoods = parentGoodsMap.get(info.goods.spuId);
          if (parentGoods) {
            goodsName = `${parentGoods.name} ${info.goods.name}`;
          }
        }

        return {
          tenantId,
          orderId: savedOrder.id,
          orderNo,
          goodsId: info.goods.id,
          goodsName,
          imageFileId: info.goods.imageFileId,
          goodsType: info.goods.goodsType,
          supplierId: info.goods.supplierId,
          costPrice: info.goods.costPrice,
          price: info.goods.price,
          num: info.quantity,
          freightAmount: 0,
          state: 0,
          createdBy: userId,
          updatedBy: userId,
          expressName: null,
          expressNo: null
        };
      });

      await queryRunner.manager.save(OrderGoodsMt, orderGoodsList);

      // 更新商品库存
      for (const item of goodsInfo) {
        await queryRunner.manager.update(GoodsMt, item.goods.id, {
          stock: () => `stock - ${item.quantity}`,
          salesNum: () => `sales_num + ${item.quantity}`
        });
      }

      await queryRunner.commitTransaction();

      return {
        success: true,
        orderId: savedOrder.id,
        orderNo: savedOrder.orderNo,
        amount: savedOrder.amount,
        payAmount: savedOrder.payAmount,
        message: '订单创建成功'
      };

    } catch (error) {
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 取消订单
   * @param tenantId 租户ID
   * @param orderId 订单ID
   * @param reason 取消原因
   * @param userId 用户ID
   * @returns Promise<void>
   */
  async cancelOrder(tenantId: number, orderId: number, reason: string, userId: number): Promise<void> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 查询订单信息
      const order = await this.repository.findOne({
        where: { id: orderId, tenantId, userId }
      });

      if (!order) {
        throw new Error('订单不存在');
      }

      // 验证订单状态（仅允许取消未发货且支付状态为0或2的订单）
      if (order.state !== 0) {
        throw new Error('当前订单状态不允许取消');
      }

      // 验证支付状态
      if (order.payState !== 0 && order.payState !== 2) {
        throw new Error('当前订单状态不允许取消');
      }

      // 对于已支付订单（支付状态=2），需要触发退款流程
      if (order.payState === 2) {
        console.debug(`[租户${tenantId}] 订单 ${orderId} 已支付，开始触发退款流程`);

        try {
          // 调用支付模块的退款功能
          const refundResult = await this.paymentMtService.refund(
            tenantId,
            order.orderNo,
            order.payAmount,
            `订单取消：${reason}`
          );

          console.debug(`[租户${tenantId}] 退款处理成功，退款流水号: ${refundResult.refundId}`);

          // 创建退款记录
          await this.createRefundRecord(tenantId, order, refundResult, userId);

        } catch (error) {
          console.debug(`[租户${tenantId}] 退款处理失败，订单ID: ${orderId}, 错误:`, error);
          // 退款失败不影响订单取消，但记录错误信息
          // 可以在这里添加重试机制或通知管理员
        }
      }

      // 更新订单状态为5（订单关闭），记录取消时间和原因
      await queryRunner.manager.update(OrderMt, { id: orderId, tenantId }, {
        payState: 5, // 订单关闭
        cancelReason: reason,
        cancelTime: new Date(),
        updatedBy: userId,
        updatedAt: new Date()
      });

      // 如果是额度支付订单（payType === 3），需要恢复额度
      if (order.payType === 3) {
        console.debug(`[租户${tenantId}] 额度支付订单 ${orderId} 取消，开始恢复额度`);
        try {
          await this.creditBalanceService.restoreBalanceForCancelOrder(
            tenantId,
            userId,
            order.orderNo,
            order.payAmount,
            userId
          );
          console.debug(`[租户${tenantId}] 额度恢复成功，订单号: ${order.orderNo}`);
        } catch (error) {
          console.debug(`[租户${tenantId}] 额度恢复失败，订单ID: ${orderId}, 错误:`, error);
          // 额度恢复失败不影响订单取消，但记录错误信息
        }
      }

      // 如果订单是未支付状态，需要恢复商品库存
      if (order.payState === 0) {
        // 查询订单商品明细
        const orderGoods = await this.orderGoodsRepository.find({
          where: { orderId, tenantId }
        });

        // 恢复商品库存
        for (const item of orderGoods) {
          await queryRunner.manager.update(GoodsMt, { id: item.goodsId, tenantId }, {
            stock: () => `stock + ${item.num}`,
            salesNum: () => `sales_num - ${item.num}`
          });
        }
      }

      await queryRunner.commitTransaction();
    } catch (error) {
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 确认收货
   * @param tenantId 租户ID
   * @param orderId 订单ID
   * @param userId 用户ID
   * @returns 更新后的订单信息
   */
  async confirmReceipt(tenantId: number, orderId: number, userId: number): Promise<{
    orderId: number;
    state: number;
    updatedAt: Date;
  }> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 查询订单信息
      const order = await this.repository.findOne({
        where: { id: orderId, tenantId, userId }
      });

      if (!order) {
        throw new Error('订单不存在');
      }

      // 验证订单状态：只有已发货的订单才能确认收货
      if (order.state !== 1) {
        throw new Error('只有已发货的订单才能确认收货');
      }

      // 验证支付状态：只有已支付的订单才能确认收货
      if (order.payState !== 2) {
        throw new Error('只有已支付的订单才能确认收货');
      }

      // 更新订单状态为收货成功 (state = 2)
      await queryRunner.manager.update(OrderMt, { id: orderId, tenantId }, {
        state: 2, // 收货成功
        updatedBy: userId,
        updatedAt: new Date()
      });

      // 提交事务
      await queryRunner.commitTransaction();

      // 返回更新后的订单信息
      const updatedOrder = await this.repository.findOne({
        where: { id: orderId, tenantId }
      });

      if (!updatedOrder) {
        throw new Error('订单更新后查询失败');
      }

      return {
        orderId: updatedOrder.id,
        state: updatedOrder.state,
        updatedAt: updatedOrder.updatedAt
      };

    } catch (error) {
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 生成订单号
   * 格式：年月日时分秒 + 6位随机数
   */
  private generateOrderNo(): string {
    const now = new Date();
    const year = now.getFullYear();
    const month = String(now.getMonth() + 1).padStart(2, '0');
    const day = String(now.getDate()).padStart(2, '0');
    const hour = String(now.getHours()).padStart(2, '0');
    const minute = String(now.getMinutes()).padStart(2, '0');
    const second = String(now.getSeconds()).padStart(2, '0');
    const random = String(Math.floor(Math.random() * 1000000)).padStart(6, '0');

    return `ORD${year}${month}${day}${hour}${minute}${second}${random}`;
  }

  /**
   * 创建退款记录
   */
  private async createRefundRecord(
    tenantId: number,
    order: OrderMt,
    refundResult: any,
    userId: number
  ): Promise<void> {
    const refundRecord = new OrderRefundMt();
    refundRecord.tenantId = tenantId;
    refundRecord.orderNo = order.orderNo;
    refundRecord.refundOrderNo = refundResult.outRefundNo;
    refundRecord.refundAmount = refundResult.refundAmount;
    refundRecord.state = 2; // 退款成功
    refundRecord.remark = `退款成功，微信退款流水号: ${refundResult.refundId}`;
    refundRecord.createdBy = userId;
    refundRecord.updatedBy = userId;

    await this.orderRefundRepository.save(refundRecord);
    console.debug(`[租户${tenantId}] 退款记录创建成功，退款订单号: ${refundResult.outRefundNo}`);
  }

  /**
   * 根据订单ID查询支付记录
   * @param tenantId 租户ID
   * @param orderId 订单ID
   * @param userId 用户ID（可选，用于权限验证）
   * @returns 支付记录信息，如果不存在则返回null
   */
  async getPaymentRecordByOrderId(
    tenantId: number,
    orderId: number,
    userId?: number
  ): Promise<PaymentMtEntity | null> {
    try {
      // 获取支付实体仓库
      const paymentRepository = this.dataSource.getRepository(PaymentMtEntity);

      // 构建查询条件
      const whereCondition: any = {
        externalOrderId: orderId,
        tenantId
      };

      // 如果提供了用户ID，则添加用户ID过滤（确保用户只能查询自己的支付记录）
      if (userId !== undefined) {
        whereCondition.userId = userId;
      }

      // 查询支付记录
      const paymentRecord = await paymentRepository.findOne({
        where: whereCondition,
        order: { createdAt: 'DESC' } // 按创建时间倒序，获取最新的支付记录
      });

      if (!paymentRecord) {
        console.debug(`[租户${tenantId}] 未找到订单ID ${orderId} 的支付记录`);
        return null;
      }

      console.debug(`[租户${tenantId}] 找到订单ID ${orderId} 的支付记录:`, {
        paymentId: paymentRecord.id,
        outTradeNo: paymentRecord.outTradeNo,
        wechatTransactionId: paymentRecord.wechatTransactionId,
        paymentStatus: paymentRecord.paymentStatus,
        totalAmount: paymentRecord.totalAmount
      });

      return paymentRecord;
    } catch (error) {
      console.error(`[租户${tenantId}] 查询订单ID ${orderId} 的支付记录失败:`, error);
      throw new Error(`查询支付记录失败: ${error instanceof Error ? error.message : '未知错误'}`);
    }
  }

  /**
   * 根据订单ID查询支付记录（简化版，返回必要信息）
   * @param tenantId 租户ID
   * @param orderId 订单ID
   * @param userId 用户ID（可选）
   * @returns 支付记录的关键信息
   */
  async getPaymentInfoByOrderId(
    tenantId: number,
    orderId: number,
    userId?: number
  ): Promise<{
    outTradeNo: string | null;
    wechatTransactionId: string | null;
    paymentStatus: string;
    exists: boolean;
    paymentId?: number;
    totalAmount?: number;
    createdAt?: Date;
    hasWechatTransactionId: boolean;
    paymentStatusDetail: string;
  }> {
    try {
      const paymentRecord = await this.getPaymentRecordByOrderId(tenantId, orderId, userId);

      if (!paymentRecord) {
        return {
          outTradeNo: null,
          wechatTransactionId: null,
          paymentStatus: '未找到支付记录',
          exists: false,
          hasWechatTransactionId: false,
          paymentStatusDetail: '支付记录不存在'
        };
      }

      const hasWechatTransactionId = !!paymentRecord.wechatTransactionId;
      let paymentStatusDetail = paymentRecord.paymentStatus || '未知状态';

      // 添加详细的支付状态说明
      if (!hasWechatTransactionId) {
        if (paymentRecord.paymentStatus === PaymentStatus.PAID) {
          paymentStatusDetail = '已支付（等待微信回调更新交易ID）';
        } else if (paymentRecord.paymentStatus === PaymentStatus.PROCESSING) {
          paymentStatusDetail = '支付处理中（微信交易ID将在支付成功后生成）';
        } else if (paymentRecord.paymentStatus === PaymentStatus.PENDING) {
          paymentStatusDetail = '待支付（尚未完成支付）';
        }
      }

      return {
        outTradeNo: paymentRecord.outTradeNo || null,
        wechatTransactionId: paymentRecord.wechatTransactionId || null,
        paymentStatus: paymentRecord.paymentStatus || '未知状态',
        exists: true,
        paymentId: paymentRecord.id,
        totalAmount: paymentRecord.totalAmount,
        createdAt: paymentRecord.createdAt,
        hasWechatTransactionId,
        paymentStatusDetail
      };
    } catch (error) {
      console.error(`[租户${tenantId}] 获取订单ID ${orderId} 的支付信息失败:`, error);
      return {
        outTradeNo: null,
        wechatTransactionId: null,
        paymentStatus: '查询失败',
        exists: false,
        hasWechatTransactionId: false,
        paymentStatusDetail: `查询失败: ${error instanceof Error ? error.message : '未知错误'}`
      };
    }
  }
}