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

/**
 * 관리자 전용 B2C 분석 API
 * - 관리자가 iframe으로 B2C 분석 상세를 조회할 때 사용 (/admin-view/b2c-analyze/:bodId/*)
 * - ★보안(C2): AdminViewTokenGuard로 scope(b2c-analyze)+bodId 스코프 단명 토큰(?t=) 검증.
 *   ADMIN_VIEW_TOKEN_ENFORCE='true' 시 차단 활성(그 전엔 경고 로그만=무중단).
 */
@ApiTags('[Admin View] B2C 분석 상세')
@UseGuards(AdminViewTokenGuard)
@Controller('admin-view/b2c-analyze')
export class AdminViewB2cAnalyzeController {
  constructor(
    private analyzeService: AnalyzeService,
    private analyzeRepository: AnalyzeRepository,
  ) {}

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

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

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

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

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

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

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

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

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

  @Get(':bodId/car-basic')
  @UseGuards(CarViewAdminGuard)
  @ApiOperation({
    summary: `분석데이터(자동차보험) 목록`,
    description: `관리자 전용 B2C 자동차보험 분석데이터를 요청합니다. (인증 없음)`,
  })
  @ApiOkResponse({ type: GetAnalysisCarBasicListResponseDto })
  async carBasicList(
    @Param('bodId', ParseIntPipe) bodId: number,
    @Query() dto: GetAnalysisCarBasicListDto,
  ) {
    // B2C 주문 및 사용자 정보 조회
    const orderDetail =
      await this.analyzeRepository.checkB2cOrderDetailByBodId(bodId);
    if (!orderDetail) {
      throw new NotFoundException('B2C 주문 정보를 찾을 수 없습니다.');
    }

    const user = await this.analyzeRepository.getB2cUserById(
      orderDetail.bcuId!,
    );

    // 자동차보험 데이터 조회
    const list = await this.analyzeRepository.getB2cCarBasicList(
      bodId,
      dto.page,
    );

    // count 계산 (전체 데이터 조회)
    const allList = await this.analyzeRepository.getB2cCarBasicList(bodId, 0);
    const count = allList.length;

    return plainToInstance(
      GetAnalysisCarBasicListResponseDto,
      {
        count,
        order: {
          member: {
            memLoginId: 'B2C',
          },
          user: {
            usrName: user?.bcuName || '',
            usrPhone: user?.bcuPhone || '',
            usrBirth: user?.bcuBirth || '',
          },
          orderDetail: {
            oddId: bodId,
            oddTransactionId: orderDetail.bodTransactionId,
            oddState: orderDetail.bodState,
            oddCompletedAt: orderDetail.bodCreatedAt,
          },
        },
        list,
      },
      {
        excludeExtraneousValues: true,
      },
    );
  }

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