import { Body, Controller, Get, NotFoundException, Param, Post, UseGuards } from '@nestjs/common';
import { CommandBus, QueryBus } from '@nestjs/cqrs';
import {
  ApiBearerAuth,
  ApiOperation,
  ApiParam,
  ApiResponse,
  ApiTags,
} from '@nestjs/swagger';
import {
  type JwtPayload,
  CurrentUser,
  JwtAuthGuard,
  RolesGuard,
  Roles,
} from '@modules/auth';
import { RecalculateQualityScoreCommand } from '../../application/commands/recalculate-quality-score/recalculate-quality-score.command';
import { UpgradeToAgentCommand } from '../../application/commands/upgrade-to-agent/upgrade-to-agent.command';
import { type UpgradeToAgentResult } from '../../application/commands/upgrade-to-agent/upgrade-to-agent.handler';
import { GetAgentDashboardQuery } from '../../application/queries/get-agent-dashboard/get-agent-dashboard.query';
import { GetAgentPublicProfileQuery } from '../../application/queries/get-agent-public-profile/get-agent-public-profile.query';
import { type AgentDashboardData, type AgentPublicProfileData } from '../../domain/repositories/agent.repository';
import { UpgradeToAgentDto } from '../dto/upgrade-to-agent.dto';

@ApiTags('agents')
@Controller('agents')
export class AgentsController {
  constructor(
    private readonly commandBus: CommandBus,
    private readonly queryBus: QueryBus,
  ) {}

  @ApiBearerAuth('JWT')
  @ApiOperation({ summary: 'Get agent dashboard stats' })
  @ApiResponse({ status: 200, description: 'Agent dashboard data' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden — only agents' })
  @ApiResponse({ status: 404, description: 'Agent profile not found' })
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles('AGENT')
  @Get('me/dashboard')
  async getDashboard(
    @CurrentUser() user: JwtPayload,
  ): Promise<AgentDashboardData> {
    return this.queryBus.execute(new GetAgentDashboardQuery(user.sub));
  }

  @ApiOperation({ summary: 'Get public agent profile' })
  @ApiParam({ name: 'agentId', description: 'Agent ID' })
  @ApiResponse({ status: 200, description: 'Agent public profile data' })
  @ApiResponse({ status: 404, description: 'Agent not found' })
  @Get(':agentId/profile')
  async getPublicProfile(
    @Param('agentId') agentId: string,
  ): Promise<AgentPublicProfileData> {
    const profile = await this.queryBus.execute(
      new GetAgentPublicProfileQuery(agentId),
    );
    if (!profile) {
      throw new NotFoundException('Không tìm thấy môi giới');
    }
    return profile;
  }

  @ApiBearerAuth('JWT')
  @ApiOperation({ summary: 'Nâng cấp tài khoản lên đại lý' })
  @ApiResponse({ status: 201, description: 'Tài khoản đã được nâng cấp lên đại lý (chưa xác minh)' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Không tìm thấy người dùng' })
  @ApiResponse({ status: 409, description: 'Tài khoản đã là đại lý hoặc không được phép nâng cấp' })
  @UseGuards(JwtAuthGuard)
  @Post('me/upgrade')
  async upgradeToAgent(
    @CurrentUser() user: JwtPayload,
    @Body() dto: UpgradeToAgentDto,
  ): Promise<UpgradeToAgentResult> {
    return this.commandBus.execute(
      new UpgradeToAgentCommand(
        user.sub,
        dto.licenseNumber,
        dto.agency,
        dto.bio,
        dto.serviceAreas,
      ),
    );
  }

  @ApiBearerAuth('JWT')
  @ApiOperation({ summary: 'Recalculate quality score (admin/system)' })
  @ApiParam({ name: 'agentId', description: 'Agent ID' })
  @ApiResponse({ status: 201, description: 'Quality score recalculated' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden — only admins' })
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles('ADMIN')
  @Post(':agentId/recalculate-score')
  async recalculateScore(
    @Param('agentId') agentId: string,
  ): Promise<{ message: string }> {
    await this.commandBus.execute(
      new RecalculateQualityScoreCommand(agentId),
    );
    return { message: 'Quality score recalculated' };
  }
}
