import {
  Controller,
  Get,
  Param,
  ParseIntPipe,
  Query,
  UseGuards,
} from '@nestjs/common';
import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
import { AdminViewTokenGuard } from '../admin-view-token/admin-view-token.guard';
import { CarViewAdminGuard } from '../auth/admin/car-view-admin.guard';
import { plainToInstance } from 'class-transformer';
import {
  GetAnalysisAggregateListDto,
  GetAnalysisAggregateListResponseDto,
  GetAnalysisBasicListDto,
  GetAnalysisBasicListResponseDto,
  GetAnalysisCarBasicListDto,
  GetAnalysisCarBasicListResponseDto,
  GetAnalysisCarDetailListDto,
  GetAnalysisCarDetailListResponseDto,
  GetAnalysisDetailListDto,
  GetAnalysisDetailListResponseDto,
  GetAnalysisPrescibeListResponseDto,
  GetAnalysisPrescribeListDto,
} from './analyze.dto';
import { AnalyzeService } from './analyze.service';

/**
 * 관리자 전용 일반회원 분석 API
 * - 관리자가 iframe으로 분석 상세를 조회할 때 사용 (/admin-view/analyze/:oddId/*)
 * - ★보안(C2): AdminViewTokenGuard로 scope(analyze)+oddId 스코프 단명 토큰(?t=) 검증. admin이 발급받아
 *   iframe URL에 실어 전달. ADMIN_VIEW_TOKEN_ENFORCE='true' 시 차단 활성(그 전엔 경고 로그만=무중단).
 */
@ApiTags('[Admin View] 일반회원 분석 상세')
@UseGuards(AdminViewTokenGuard)
@Controller('admin-view/analyze')
export class AdminViewAnalyzeController {
  constructor(private analyzeService: AnalyzeService) {}

  @ApiOperation({
    summary: '분석데이터(기본)',
    description: `관리자 전용 분석기본데이터를 요청합니다. (인증 없음)`,
  })
  @Get(':oddId/basic')
  @ApiOkResponse({ type: GetAnalysisBasicListResponseDto })
  async basicList(
    @Param('oddId', ParseIntPipe) oddId: number,
    @Query() dto: GetAnalysisBasicListDto,
  ) {
    const data = await this.analyzeService.getBasicList(oddId, dto);
    return plainToInstance(GetAnalysisBasicListResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @ApiOperation({
    summary: '분석데이터(상세)',
    description: `관리자 전용 분석상세데이터를 요청합니다. (인증 없음)`,
  })
  @Get(':asbId/detail')
  @ApiOkResponse({ type: GetAnalysisDetailListResponseDto })
  async detailList(
    @Param('asbId', ParseIntPipe) asbId: number,
    @Query() dto: GetAnalysisDetailListDto,
  ) {
    const data = await this.analyzeService.getDetailList(asbId, dto);
    return plainToInstance(GetAnalysisDetailListResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @ApiOperation({
    summary: `분석데이터(5년치계산분)`,
    description: `관리자 전용 분석기본데이터 중 계산이 필요한 데이터를 요청합니다. (인증 없음)`,
  })
  @Get(':oddId/aggregate')
  @ApiOkResponse({ type: GetAnalysisAggregateListResponseDto })
  async aggregateList(
    @Param('oddId', ParseIntPipe) oddId: number,
    @Query() dto: GetAnalysisAggregateListDto,
  ) {
    const data = await this.analyzeService.getAggregateList(oddId, dto);
    return plainToInstance(GetAnalysisAggregateListResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @ApiOperation({
    summary: `처방조제정보`,
    description: `관리자 전용 중복투약일 경우 해당일의 처방조제정보를 요청합니다. (인증 없음)`,
  })
  @Get(':oddId/prescribe')
  @ApiOkResponse({ type: GetAnalysisPrescibeListResponseDto })
  async prescribeList(
    @Param('oddId', ParseIntPipe) oddId: number,
    @Query() dto: GetAnalysisPrescribeListDto,
  ) {
    const data = await this.analyzeService.getPrescribeList(oddId, dto);
    return plainToInstance(GetAnalysisPrescibeListResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @ApiOperation({
    summary: `분석데이터(5년 내 7일이상 진료)`,
    description: `관리자 전용 5년 내 7일이상 진료 중분류 그루핑 데이터를 요청합니다. (인증 없음)`,
  })
  @Get(':oddId/treatment-7day-groups')
  async treatment7DayGroups(@Param('oddId', ParseIntPipe) oddId: number) {
    return await this.analyzeService.getTreatment7DayGroups(oddId);
  }

  @ApiOperation({
    summary: `분석데이터(5년 내 30일이상 투약)`,
    description: `관리자 전용 5년 내 30일이상 투약 약효 카테고리 그루핑 데이터를 요청합니다. (인증 없음)`,
  })
  @Get(':oddId/dosing-30day-groups')
  async dosing30DayGroups(@Param('oddId', ParseIntPipe) oddId: number) {
    return await this.analyzeService.getDosing30DayGroups(oddId);
  }

  @ApiOperation({
    summary: `분석데이터(동일 진단코드 내원 그룹)`,
    description: `관리자 전용 동일 주상병코드 내원 그룹 데이터를 요청합니다. (인증 없음, 약국 포함)`,
  })
  @Get(':oddId/disease-code-visit-groups')
  async diseaseCodeVisitGroups(@Param('oddId', ParseIntPipe) oddId: number) {
    return await this.analyzeService.getDiseaseCodeVisitGroups(oddId);
  }

  @ApiOperation({
    summary: `분석데이터(치아 숨은보험금 그룹)`,
    description: `관리자 전용 치아 숨은보험금(asdInTooth)별 그루핑 데이터를 요청합니다. (인증 없음)`,
  })
  @Get(':oddId/tooth-insurance-groups')
  async toothInsuranceGroups(@Param('oddId', ParseIntPipe) oddId: number) {
    return await this.analyzeService.getToothInsuranceGroups(oddId);
  }

  @ApiOperation({
    summary: `분석데이터(기타 숨은보험금 그룹)`,
    description: `관리자 전용 기타 숨은보험금(asdInEtc)별 그루핑 데이터를 요청합니다. (인증 없음)`,
  })
  @Get(':oddId/etc-insurance-groups')
  async etcInsuranceGroups(@Param('oddId', ParseIntPipe) oddId: number) {
    return await this.analyzeService.getEtcInsuranceGroups(oddId);
  }

  @Get(':oddId/car-basic')
  @UseGuards(CarViewAdminGuard)
  @ApiOperation({
    summary: `분석데이터(자동차보험) 목록`,
    description: `관리자 전용 자동차보험 분석데이터를 요청합니다. (인증 없음)`,
  })
  @ApiOkResponse({ type: GetAnalysisCarBasicListResponseDto })
  async carBasicList(
    @Param('oddId', ParseIntPipe) oddId: number,
    @Query() dto: GetAnalysisCarBasicListDto,
  ) {
    const data = await this.analyzeService.getCarBasicList(oddId, dto);
    return plainToInstance(GetAnalysisCarBasicListResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }

  @Get(':acbId/car-detail')
  @UseGuards(CarViewAdminGuard)
  @ApiOperation({
    summary: '분석데이터(자동차보험) 상세',
    description: `관리자 전용 자동차보험 분석상세데이터를 요청합니다. (인증 없음)`,
  })
  @ApiOkResponse({ type: GetAnalysisCarDetailListResponseDto })
  async carDetailList(
    @Param('acbId', ParseIntPipe) acbId: number,
    @Query() dto: GetAnalysisCarDetailListDto,
  ) {
    const data = await this.analyzeService.getCarDetailList(acbId, dto);
    return plainToInstance(GetAnalysisCarDetailListResponseDto, data, {
      excludeExtraneousValues: true,
    });
  }
}
