import { Controller, Get, Query, Req, UseGuards } from '@nestjs/common';
import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
import { plainToInstance } from 'class-transformer';
import { AdminJwtAuthGuard } from '../auth/admin/jwt.guard';
import {
  GetAnalysisDailyResponseDto,
  GetAnalysisDayDto,
  GetAnalysisMonthDto,
  GetAnalysisMonthlyResponseDto,
  GetRevenueDailyResponseDto,
  GetRevenueDayDto,
  GetRevenueMonthDto,
  GetRevenueMonthlyResponseDto,
  GetSignUpDailyResponseDto,
  GetSignUpDayDto,
  GetSignUpMonthDto,
  GetSignUpMonthlyResponseDto,
  GetStatisticsListDto,
  GetStatisticsResponseDto,
} from './statistics.dto';
import { StatisticsService } from './statistics.service';
import { RolesGuard } from '../auth/admin/roles.guard';
import { Roles } from '../auth/admin/roles.decorator';

@ApiTags('[관리자] 통계조회')
@UseGuards(AdminJwtAuthGuard, RolesGuard)
@Controller('admin/statistics')
export class StatisticsController {
  constructor(private statisticsService: StatisticsService) {}

  @ApiOperation({ summary: `통계조회` })
  @Get()
  @ApiOkResponse({ type: GetStatisticsResponseDto })
  @Roles('admin', 'sales')
  async getStatistics(
    @Query() query: GetStatisticsListDto,
    @Req() req: Request,
  ) {
    const { role, sagId } = req['admin'];

    let data;

    //* 영업대리점 관리자 일 경우
    if (role === 'admin') {
      data = await this.statisticsService.getStatistics(query);
    } else {
      data = await this.statisticsService.getSalesStatistics(query, sagId);
    }
    return plainToInstance(GetStatisticsResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @ApiOperation({ summary: `가입통계조회 - 월별` })
  @Get('signup/month')
  @ApiOkResponse({ type: GetSignUpMonthlyResponseDto })
  @Roles('admin')
  async getSignUpMonth(@Query() query: GetSignUpMonthDto) {
    const data = await this.statisticsService.getSignUpStatistics(
      'month',
      query.year,
      query.memType,
    );
    return plainToInstance(GetSignUpMonthlyResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @ApiOperation({ summary: `가입통계조회 - 일별` })
  @Get('signup/day')
  @ApiOkResponse({ type: GetSignUpDailyResponseDto })
  @Roles('admin')
  async getSignUpDay(@Query() query: GetSignUpDayDto) {
    const data = await this.statisticsService.getSignUpStatistics(
      'day',
      query.yearMonth,
      query.memType,
    );
    return plainToInstance(GetSignUpDailyResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @ApiOperation({ summary: `매출통계조회 - 월별` })
  @Get('revenue/month')
  @ApiOkResponse({ type: GetRevenueMonthlyResponseDto })
  @Roles('admin')
  async getRevenueMonth(@Query() query: GetRevenueMonthDto) {
    const data = await this.statisticsService.getRevenueStatistics(
      'month',
      query.year,
      query.memType,
    );
    return plainToInstance(GetRevenueMonthlyResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @ApiOperation({ summary: `매출통계조회 - 일별` })
  @Get('revenue/day')
  @ApiOkResponse({ type: GetRevenueDailyResponseDto })
  @Roles('admin')
  async getRevenueDay(@Query() query: GetRevenueDayDto) {
    const data = await this.statisticsService.getRevenueStatistics(
      'day',
      query.yearMonth,
      query.memType,
    );
    return plainToInstance(GetRevenueDailyResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @ApiOperation({ summary: `분석통계조회 - 월별` })
  @Get('analysis/month')
  @ApiOkResponse({ type: GetAnalysisMonthlyResponseDto })
  @Roles('admin')
  async getAnalysisMonth(@Query() query: GetAnalysisMonthDto) {
    const data = await this.statisticsService.getAnalysisStatistics(
      'month',
      query.year,
    );
    return plainToInstance(GetAnalysisMonthlyResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @ApiOperation({ summary: `분석통계조회 - 일별` })
  @Get('analysis/day')
  @ApiOkResponse({ type: GetAnalysisDailyResponseDto })
  @Roles('admin')
  async getAnalysisDay(@Query() query: GetAnalysisDayDto) {
    const data = await this.statisticsService.getAnalysisStatistics(
      'day',
      query.yearMonth,
    );
    return plainToInstance(GetAnalysisDailyResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }
}
