import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
import { Injectable } from '@nestjs/common';
import { RecordHeartbeatCommand } from './record-heartbeat.command';
import { PresenceRedisRepository } from '../../../infrastructure/redis/presence-redis.repository';
import { EventPublisherService } from '../../../infrastructure/kafka/event-publisher.service';
import { MetricsService } from '../../../infrastructure/metrics/metrics.service';
import { HeartbeatReceivedEvent } from '../../../domain/events/heartbeat-received.event';

export interface RecordHeartbeatResult {
  ok: boolean;
  serverTs: number;
}

@Injectable()
@CommandHandler(RecordHeartbeatCommand)
export class RecordHeartbeatHandler implements ICommandHandler<RecordHeartbeatCommand> {
  constructor(
    private readonly presenceRedisRepository: PresenceRedisRepository,
    private readonly eventPublisher: EventPublisherService,
    private readonly metricsService: MetricsService,
  ) {}

  async execute(command: RecordHeartbeatCommand): Promise<RecordHeartbeatResult> {
    const startTime = Date.now();
    const { userId, installId, appVersion, clientTs } = command;
    const now = Math.floor(Date.now() / 1000);

    // 1. 更新Redis在线状态 (userId is userSerialNum string, e.g. "D25121400005")
    await this.presenceRedisRepository.updateUserPresence(userId, now);

    // 2. 发布领域事件
    await this.eventPublisher.publish(
      HeartbeatReceivedEvent.EVENT_NAME,
      new HeartbeatReceivedEvent(userId, installId, new Date()),
    );

    // 3. 记录 Prometheus 指标
    const durationSeconds = (Date.now() - startTime) / 1000;
    this.metricsService.recordHeartbeat(appVersion, durationSeconds);

    return { ok: true, serverTs: now };
  }
}
