/**
 * 转让回滚处理器（纯新增）
 * 消费 transfer.trees.unlock 事件
 * 解锁卖方的树，恢复可转让状态
 *
 * 回滚方式：删除此文件并从 infrastructure.module.ts 中移除引用
 */

import { Controller, Logger, Inject } from '@nestjs/common';
import { EventPattern, Payload, Ctx, KafkaContext } from '@nestjs/microservices';
import { ClientKafka } from '@nestjs/microservices';
import { PrismaService } from '../persistence/prisma/prisma.service';

interface TransferUnlockPayload {
  transferOrderNo: string;
  sourceOrderNo: string;
  treeCount: number;
}

@Controller()
export class TransferRollbackHandler {
  private readonly logger = new Logger(TransferRollbackHandler.name);

  constructor(
    private readonly prisma: PrismaService,
    @Inject('KAFKA_SERVICE')
    private readonly kafkaClient: ClientKafka,
  ) {}

  @EventPattern('transfer.trees.unlock')
  async handle(
    @Payload() message: TransferUnlockPayload,
    @Ctx() context: KafkaContext,
  ): Promise<void> {
    const { transferOrderNo, sourceOrderNo, treeCount } = message;

    this.logger.log(
      `[TRANSFER-ROLLBACK] Received unlock request: ${transferOrderNo}, orderNo=${sourceOrderNo}`,
    );

    try {
      // 幂等性检查
      const existing = await this.prisma.plantingTransferRecord.findUnique({
        where: { transferOrderNo },
      });

      if (!existing) {
        this.logger.warn(
          `[TRANSFER-ROLLBACK] Record not found: ${transferOrderNo}, sending success ACK`,
        );
        this.publishAck(transferOrderNo, true);
        return;
      }

      if (existing.status === 'ROLLED_BACK') {
        this.logger.log(
          `[TRANSFER-ROLLBACK] Already rolled back: ${transferOrderNo}`,
        );
        this.publishAck(transferOrderNo, true);
        return;
      }

      if (existing.status !== 'LOCKED') {
        this.logger.error(
          `[TRANSFER-ROLLBACK] Cannot rollback: ${transferOrderNo}, status=${existing.status}`,
        );
        this.publishAck(
          transferOrderNo,
          false,
          `状态不允许回滚: ${existing.status}`,
        );
        return;
      }

      // 事务：更新记录状态 + 恢复锁定计数
      await this.prisma.executeTransaction(async (tx) => {
        await tx.plantingTransferRecord.update({
          where: { transferOrderNo },
          data: {
            status: 'ROLLED_BACK',
            rolledBackAt: new Date(),
          },
        });

        await tx.plantingOrder.update({
          where: { id: existing.sourceOrderId },
          data: {
            transferLockedCount: { decrement: existing.treeCount },
          },
        });
      });

      this.logger.log(
        `[TRANSFER-ROLLBACK] ✓ Trees unlocked: ${transferOrderNo}, ${existing.treeCount} trees`,
      );

      this.publishAck(transferOrderNo, true);
    } catch (error) {
      this.logger.error(
        `[TRANSFER-ROLLBACK] ✗ Failed to rollback ${transferOrderNo}:`,
        error,
      );
      this.publishAck(
        transferOrderNo,
        false,
        `回滚失败: ${(error as Error).message}`,
      );
    }
  }

  private publishAck(
    transferOrderNo: string,
    success: boolean,
    error?: string,
  ): void {
    const message = {
      key: transferOrderNo,
      value: JSON.stringify({
        transferOrderNo,
        success,
        error,
        confirmedAt: new Date().toISOString(),
      }),
    };

    this.kafkaClient.emit('transfer.trees.unlock.ack', message);
    this.logger.log(
      `[TRANSFER-ROLLBACK] ACK sent: ${transferOrderNo}, success=${success}`,
    );
  }
}
