import { Injectable, Logger } from '@nestjs/common';
import { KafkaService } from '../messaging/kafka.service';

/**
 * 事件确认消息结构
 */
interface EventAckMessage {
  /** 原始事件的 aggregateId（如 orderNo） */
  eventId: string;
  /** 原始事件类型 */
  eventType: string;
  /** 消费服务名称 */
  consumerService: string;
  /** 处理结果 */
  success: boolean;
  /** 错误信息（如果失败） */
  error?: string;
  /** 确认时间 */
  confirmedAt: string;
}

/**
 * 事件确认发布器
 *
 * B方案核心组件：消费方处理事件后发送确认
 * 发送确认消息到 planting.events.ack topic
 */
@Injectable()
export class EventAckPublisher {
  private readonly logger = new Logger(EventAckPublisher.name);
  private readonly serviceName = 'referral-service';

  constructor(private readonly kafkaService: KafkaService) {}

  /**
   * 发送处理成功确认
   */
  async sendSuccess(eventId: string, eventType: string): Promise<void> {
    const ackMessage: EventAckMessage = {
      eventId,
      eventType,
      consumerService: this.serviceName,
      success: true,
      confirmedAt: new Date().toISOString(),
    };

    try {
      await this.kafkaService.publish({
        topic: 'planting.events.ack',
        key: eventId,
        value: ackMessage as unknown as Record<string, unknown>,
      });

      this.logger.log(`[ACK] ✓ Sent success confirmation for event ${eventId} (${eventType})`);
    } catch (error) {
      this.logger.error(`[ACK] Failed to send confirmation for event ${eventId}:`, error);
    }
  }

  /**
   * 发送处理失败确认
   */
  async sendFailure(eventId: string, eventType: string, errorMessage: string): Promise<void> {
    const ackMessage: EventAckMessage = {
      eventId,
      eventType,
      consumerService: this.serviceName,
      success: false,
      error: errorMessage,
      confirmedAt: new Date().toISOString(),
    };

    try {
      await this.kafkaService.publish({
        topic: 'planting.events.ack',
        key: eventId,
        value: ackMessage as unknown as Record<string, unknown>,
      });

      this.logger.warn(`[ACK] ✗ Sent failure confirmation for event ${eventId}: ${errorMessage}`);
    } catch (error) {
      this.logger.error(`[ACK] Failed to send failure confirmation for event ${eventId}:`, error);
    }
  }

  /**
   * 从消息中提取 outbox 信息
   */
  extractOutboxInfo(message: Record<string, unknown>): { id: string; aggregateId: string; eventType: string } | null {
    const outbox = message._outbox as { id: string; aggregateId: string; eventType: string } | undefined;
    if (!outbox) {
      this.logger.warn('[ACK] Message does not contain _outbox metadata');
      return null;
    }
    return outbox;
  }
}
