import {
  Controller,
  Get,
  Param,
  Query,
  UseGuards,
  ParseUUIDPipe,
  ForbiddenException,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiBearerAuth,
  ApiResponse,
  ApiParam,
} from '@nestjs/swagger';
import { StatsService } from './stats.service';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { RolesGuard } from '../auth/guards/roles.guard';
import { Roles, UserRole } from '../../common/decorators/roles.decorator';
import {
  CurrentUser,
  JwtPayload,
} from '../../common/decorators/current-user.decorator';
import { StatsQueryDto, RatingQueryDto } from './dto';

@ApiTags('Stats')
@ApiBearerAuth()
@Controller('stats')
@UseGuards(JwtAuthGuard)
export class StatsController {
  constructor(private readonly statsService: StatsService) {}

  @Get('summary')
  @UseGuards(RolesGuard)
  @Roles(
    UserRole.TRAINER,
    UserRole.COORDINATOR,
    UserRole.MANAGER,
    UserRole.RECEPTIONIST,
    UserRole.CLUB_ADMIN,
  )
  @ApiOperation({
    summary: 'Get dashboard KPI summary',
    description:
      'Returns training counts, client counts, sales totals, upcoming trainings, and sleeping clients. ' +
      'TRAINER sees own stats only. COORDINATOR+ can see all or filter by trainerId.',
  })
  @ApiResponse({ status: 200, description: 'Dashboard KPI summary' })
  async getSummary(
    @CurrentUser() user: JwtPayload,
    @Query() query: StatsQueryDto,
  ) {
    const trainerId = this.resolveTrainerId(user, query.trainerId);

    return this.statsService.getSummary(
      user.clubId,
      trainerId,
      query.dateFrom,
      query.dateTo,
    );
  }

  @Get('funnel')
  @UseGuards(RolesGuard)
  @Roles(
    UserRole.TRAINER,
    UserRole.COORDINATOR,
    UserRole.MANAGER,
    UserRole.RECEPTIONIST,
    UserRole.CLUB_ADMIN,
  )
  @ApiOperation({
    summary: 'Get funnel conversion statistics',
    description:
      'Returns conversion rates between funnel stages with per-trainer breakdowns. ' +
      'TRAINER sees own funnel only. COORDINATOR+ can see all or filter by trainerId.',
  })
  @ApiResponse({ status: 200, description: 'Funnel conversion statistics' })
  async getFunnelConversion(
    @CurrentUser() user: JwtPayload,
    @Query() query: StatsQueryDto,
  ) {
    const trainerId = this.resolveTrainerId(user, query.trainerId);

    return this.statsService.getFunnelConversion(
      user.clubId,
      trainerId,
      query.dateFrom,
      query.dateTo,
    );
  }

  @Get('rating')
  @UseGuards(RolesGuard)
  @Roles(
    UserRole.TRAINER,
    UserRole.COORDINATOR,
    UserRole.MANAGER,
    UserRole.RECEPTIONIST,
    UserRole.CLUB_ADMIN,
  )
  @ApiOperation({
    summary: 'Get trainer rating/ranking list',
    description:
      'Returns all trainers sorted by score descending. ' +
      'Uses pre-calculated RatingPeriod snapshots when available, otherwise calculates on-the-fly.',
  })
  @ApiResponse({ status: 200, description: 'Trainer rating list' })
  async getRating(
    @CurrentUser() user: JwtPayload,
    @Query() query: RatingQueryDto,
  ) {
    return this.statsService.getRating(user.clubId, query.period);
  }

  @Get('trainer/:trainerId')
  @UseGuards(RolesGuard)
  @Roles(
    UserRole.TRAINER,
    UserRole.COORDINATOR,
    UserRole.MANAGER,
    UserRole.RECEPTIONIST,
    UserRole.CLUB_ADMIN,
  )
  @ApiOperation({
    summary: 'Get detailed stats for a specific trainer',
    description:
      'Returns training counts by status, sales amounts, funnel conversion, and client count. ' +
      'TRAINER can only view their own stats.',
  })
  @ApiParam({ name: 'trainerId', description: 'Trainer UUID' })
  @ApiResponse({ status: 200, description: 'Detailed trainer statistics' })
  @ApiResponse({
    status: 403,
    description: 'TRAINER role cannot view other trainers stats',
  })
  async getTrainerStats(
    @CurrentUser() user: JwtPayload,
    @Param('trainerId', ParseUUIDPipe) trainerId: string,
    @Query() query: StatsQueryDto,
  ) {
    // TRAINER can only view their own stats
    if (user.role === UserRole.TRAINER && user.sub !== trainerId) {
      throw new ForbiddenException(
        'Trainers can only view their own statistics',
      );
    }

    return this.statsService.getTrainerStats(
      user.clubId,
      trainerId,
      query.dateFrom,
      query.dateTo,
    );
  }

  // ---------------------------------------------------------------------------
  // Private helpers
  // ---------------------------------------------------------------------------

  /**
   * For TRAINER role, force the trainerId to their own user ID.
   * Other roles use the provided trainerId filter (or undefined for all).
   */
  private resolveTrainerId(
    user: JwtPayload,
    queryTrainerId?: string,
  ): string | undefined {
    if (user.role === UserRole.TRAINER) {
      return user.sub;
    }
    return queryTrainerId;
  }
}
