import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Order } from '@/entities/order.entity';
import { RoomCalendar } from '@/entities/room-calendar.entity';
import { WechatPayService } from '@/modules/shared/payment/wechat-pay.service';
import { AccountService } from '@/modules/shared/finance/account.service';

@Injectable()
export class PaymentService {
  private readonly logger = new Logger(PaymentService.name);

  constructor(
    @InjectRepository(Order)
    private orderRepo: Repository<Order>,
    @InjectRepository(RoomCalendar)
    private calendarRepo: Repository<RoomCalendar>,
    private readonly wechatPayService: WechatPayService,
    private readonly accountService: AccountService,
  ) {}

  /**
   * 验证微信支付签名
   */
  async verifyWechatSignature(params: {
    timestamp: string;
    nonce: string;
    body: string;
    signature: string;
    serial: string;
  }): Promise<boolean> {
    return this.wechatPayService.verifySignature(params);
  }

  /**
   * 处理微信支付回调
   */
  async handleWechatNotify(body: any) {
    const { resource } = body;

    if (!resource) {
      throw new Error('回调数据格式错误');
    }

    // 解密数据
    const decryptedData = this.wechatPayService.decryptData(
      resource.ciphertext,
      resource.nonce,
      resource.associated_data,
    );

    const {
      out_trade_no: orderNo,
      transaction_id: transactionId,
      trade_state: tradeState,
      trade_state_desc: tradeStateDesc,
    } = decryptedData;

    this.logger.log(`微信支付回调: 订单号=${orderNo}, 交易状态=${tradeState}`);

    // 查询订单
    const order = await this.orderRepo.findOne({
      where: { orderNo },
      relations: ['room'],
    });

    if (!order) {
      throw new Error(`订单不存在: ${orderNo}`);
    }

    // 如果订单已支付，直接返回成功
    if (order.status !== 'pending_pay') {
      this.logger.warn(`订单已处理: ${orderNo}, 当前状态=${order.status}`);
      return;
    }

    // 只处理支付成功的回调
    if (tradeState !== 'SUCCESS') {
      this.logger.warn(`支付未成功: ${orderNo}, 状态=${tradeState}, 描述=${tradeStateDesc}`);
      return;
    }

    // 使用事务处理支付成功逻辑
    const queryRunner = this.orderRepo.manager.connection.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 1. 更新订单状态为已支付
      const paymentNo = `PAY${Date.now()}${Math.floor(Math.random() * 10000)}`;
      await queryRunner.manager.update(Order, order.id, {
        status: 'pending_confirm',
        paymentNo,
        transactionId,
        paidAt: new Date(),
      });

      // 2. 记录系统总账户收入（用户实付金额）
      const transactionNo = `TXN${Date.now()}${Math.floor(Math.random() * 10000)}`;
      await this.accountService.addSystemIncome(
        order.payAmount,
        transactionNo,
        'order_payment',
        order.id,
        order.orderNo,
        `用户支付订单：${order.orderNo}`,
      );

      // 3. 扣减房态库存（注意：创建订单时已经扣减了sold，这里不需要再扣减）
      // 如果创建订单时没有扣减库存，则需要在这里扣减
      // 根据之前的代码，创建订单时已经扣减了库存，所以这里不需要再次扣减

      // 提交事务
      await queryRunner.commitTransaction();
      this.logger.log(`订单支付成功: ${orderNo}`);
    } catch (error) {
      // 回滚事务
      await queryRunner.rollbackTransaction();
      this.logger.error(`处理支付回调失败: ${error.message}`, error.stack);
      throw error;
    } finally {
      // 释放连接
      await queryRunner.release();
    }
  }

  /**
   * 处理微信退款回调
   */
  async handleWechatRefundNotify(body: any) {
    const { resource } = body;

    if (!resource) {
      throw new Error('回调数据格式错误');
    }

    // 解密数据
    const decryptedData = this.wechatPayService.decryptData(
      resource.ciphertext,
      resource.nonce,
      resource.associated_data,
    );

    const {
      out_trade_no: orderNo,
      out_refund_no: refundNo,
      refund_status: refundStatus,
    } = decryptedData;

    this.logger.log(`微信退款回调: 订单号=${orderNo}, 退款单号=${refundNo}, 状态=${refundStatus}`);

    // 查询订单
    const order = await this.orderRepo.findOne({
      where: { orderNo },
    });

    if (!order) {
      throw new Error(`订单不存在: ${orderNo}`);
    }

    // 只处理退款成功的回调
    if (refundStatus === 'SUCCESS') {
      // 使用事务处理退款成功逻辑
      const queryRunner = this.orderRepo.manager.connection.createQueryRunner();
      await queryRunner.connect();
      await queryRunner.startTransaction();

      try {
        // 1. 更新订单状态为已退款
        await queryRunner.manager.update(Order, order.id, {
          status: 'refunded',
          refundAmount: order.payAmount,
          refundAt: new Date(),
          cancelledAt: new Date(),
        });

        // 2. 恢复房态库存
        const checkIn = new Date(order.checkInDate);
        const checkOut = new Date(order.checkOutDate);
        for (let d = new Date(checkIn); d < checkOut; d.setDate(d.getDate() + 1)) {
          const dateStr = d.toISOString().split('T')[0];
          await queryRunner.manager.decrement(
            RoomCalendar,
            { roomId: order.roomId, date: dateStr },
            'sold',
            order.roomCount,
          );
        }

        // 3. 记录系统账户退款支出
        const transactionNo = `REFUND_TXN_${Date.now()}${Math.floor(Math.random() * 10000)}`;
        await this.accountService.addSystemRefund(
          order.payAmount,
          transactionNo,
          'order_refund',
          order.id,
          order.orderNo,
          `订单退款：${order.orderNo}`,
        );

        // 提交事务
        await queryRunner.commitTransaction();
        this.logger.log(`订单退款成功: ${orderNo}`);
      } catch (error) {
        // 回滚事务
        await queryRunner.rollbackTransaction();
        this.logger.error(`处理退款回调失败: ${error.message}`, error.stack);
        throw error;
      } finally {
        // 释放连接
        await queryRunner.release();
      }
    } else if (refundStatus === 'ABNORMAL') {
      this.logger.error(`订单退款异常: ${orderNo}`);
    }
  }
}
