import { Controller, Post, Get, Body, Query, UseGuards } from '@nestjs/common';
import { CommandBus, QueryBus } from '@nestjs/cqrs';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { HeartbeatDto } from '../dto/request/heartbeat.dto';
import { QueryOnlineHistoryDto } from '../dto/request/query-online-history.dto';
import { RecordHeartbeatCommand } from '../../application/commands/record-heartbeat/record-heartbeat.command';
import { GetOnlineCountQuery } from '../../application/queries/get-online-count/get-online-count.query';
import { GetOnlineHistoryQuery } from '../../application/queries/get-online-history/get-online-history.query';
import { JwtAuthGuard } from '../../shared/guards/jwt-auth.guard';
import { AdminGuard } from '../../shared/guards/admin.guard';
import { CurrentUser } from '../../shared/decorators/current-user.decorator';

@ApiTags('Presence')
@Controller('presence')
export class PresenceController {
  constructor(
    private readonly commandBus: CommandBus,
    private readonly queryBus: QueryBus,
  ) {}

  @Post('heartbeat')
  @UseGuards(JwtAuthGuard)
  @ApiBearerAuth()
  @ApiOperation({ summary: '心跳上报' })
  async heartbeat(
    @CurrentUser('userId') userId: string,
    @Body() dto: HeartbeatDto,
  ) {
    return this.commandBus.execute(
      new RecordHeartbeatCommand(userId, dto.installId, dto.appVersion, dto.clientTs),
    );
  }

  @Get('online-count')
  @UseGuards(AdminGuard)
  @ApiBearerAuth()
  @ApiOperation({ summary: '实时在线人数（管理员）' })
  async getOnlineCount() {
    const result = await this.queryBus.execute(new GetOnlineCountQuery());
    return {
      count: result.count,
      windowSeconds: result.windowSeconds,
      queriedAt: result.queriedAt.toISOString(),
    };
  }

  @Get('online-history')
  @UseGuards(AdminGuard)
  @ApiBearerAuth()
  @ApiOperation({ summary: '历史在线人数（管理员）' })
  async getOnlineHistory(@Query() dto: QueryOnlineHistoryDto) {
    return this.queryBus.execute(
      new GetOnlineHistoryQuery(new Date(dto.startTime), new Date(dto.endTime), dto.interval || '5m'),
    );
  }
}
