import {
  Controller,
  Get,
  Post,
  Body,
  Param,
  Req,
  UseGuards,
  UseInterceptors,
  UploadedFiles,
  HttpCode,
  HttpStatus,
  ForbiddenException,
} from '@nestjs/common';
import { FileFieldsInterceptor } from '@nestjs/platform-express';
import { AiService } from './ai.service';
import { AuthGuard } from '../auth/auth.guard';
import { FeatureFlagGuard } from '../feature-flags/feature-flag.guard';
import { RequireFeature } from '../feature-flags/require-feature.decorator';
import { SensitiveRateLimitGuard } from '@/middleware/sensitive-rate-limit.guard';
import { AttestationGuard } from '@/middleware/attestation.guard';
import { DetectBreedDto, DisputeDetectionFlagDto, QuickSnapMatchDto, ScanPostDto } from './ai.dto';
import { imageUploadOptions } from '@/utils/image/image-upload.options';

@Controller('ai')
@UseGuards(AuthGuard, FeatureFlagGuard)
@RequireFeature('feature_ai_matching_enabled')
export class AiController {
  constructor(private readonly aiService: AiService) {}

  @Get('matches/:report_id')
  @HttpCode(HttpStatus.OK)
  getMatches(@Param('report_id') reportId: string) {
    return this.aiService.getMatches(reportId);
  }

  @Post('quick-snap-match')
  @UseInterceptors(FileFieldsInterceptor([{ name: 'photo', maxCount: 1 }], imageUploadOptions(5)))
  @HttpCode(HttpStatus.OK)
  quickSnapMatch(
    @Body() body: QuickSnapMatchDto,
    @UploadedFiles() files?: { photo?: Express.Multer.File[] },
  ) {
    return this.aiService.quickSnapMatch(files?.photo ?? [], body.pet_type);
  }

  @Post('scan-post')
  @HttpCode(HttpStatus.OK)
  scanPost(@Req() req: any, @Body() body: ScanPostDto) {
    return this.aiService.scanPost(req.user.id, body.postText, body.url);
  }

  @Post('detect-breed')
  @UseGuards(SensitiveRateLimitGuard, AttestationGuard)
  @UseInterceptors(
    FileFieldsInterceptor(
      [
        { name: 'photos', maxCount: 5 },
        { name: 'files', maxCount: 5 },
      ],
      imageUploadOptions(25),
    ),
  )
  @HttpCode(HttpStatus.OK)
  detectBreed(
    @Req() req: any,
    @Body() body: DetectBreedDto,
    @UploadedFiles() files?: { photos?: Express.Multer.File[]; files?: Express.Multer.File[] },
  ) {
    const photoFiles = [...(files?.photos ?? []), ...(files?.files ?? [])];
    const idempotencyKey = String(req.headers['x-idempotency-key'] || '').trim() || undefined;
    return this.aiService.detectBreed(req.user.id, photoFiles, body.requestId, idempotencyKey);
  }

  @Post('detection-flag-dispute')
  @UseGuards(SensitiveRateLimitGuard)
  @HttpCode(HttpStatus.CREATED)
  disputeDetectionFlag(@Req() req: any, @Body() body: DisputeDetectionFlagDto) {
    const flagId = body.flag_id || body.flagId;
    return this.aiService.disputeDetectionFlag(
      req.user.id,
      flagId,
      body.reason,
      body.detection as Record<string, unknown> | undefined,
    ).catch((err) => {
      if (err.message === 'Not authorized to dispute this flag') throw new ForbiddenException(err.message);
      throw err;
    });
  }
}
