import {
  BadRequestException,
  Controller,
  Get,
  Post,
  Req,
  UseGuards,
  UseInterceptors,
  UploadedFile,
} from "@nestjs/common";
import { FileInterceptor } from "@nestjs/platform-express";
import type { RequestWithUser } from "@bff/modules/auth/auth.types.js";
import { RateLimit, RateLimitGuard } from "@bff/core/rate-limiting/index.js";
import { ResidenceCardService } from "./residence-card.service.js";
import type { ResidenceCardVerification } from "@customer-portal/domain/customer";

const MAX_FILE_BYTES = 5 * 1024 * 1024; // 5MB
const ALLOWED_MIME_TYPES = new Set(["image/jpeg", "image/png", "application/pdf"]);

type UploadedResidenceCard = {
  originalname: string;
  mimetype: string;
  size: number;
  buffer: Buffer;
};

@Controller("verification/residence-card")
@UseGuards(RateLimitGuard)
export class ResidenceCardController {
  constructor(private readonly residenceCards: ResidenceCardService) {}

  @Get()
  @RateLimit({ limit: 60, ttl: 60 })
  async getStatus(@Req() req: RequestWithUser): Promise<ResidenceCardVerification> {
    return this.residenceCards.getStatusForUser(req.user.id);
  }

  @Post()
  @RateLimit({ limit: 3, ttl: 300 })
  @UseInterceptors(
    FileInterceptor("file", {
      limits: { fileSize: MAX_FILE_BYTES },
      fileFilter: (_req, file, cb) => {
        if (!ALLOWED_MIME_TYPES.has(file.mimetype)) {
          cb(
            new BadRequestException("Unsupported file type. Please upload a JPG, PNG, or PDF."),
            false
          );
          return;
        }
        cb(null, true);
      },
    })
  )
  async submit(
    @Req() req: RequestWithUser,
    @UploadedFile() file?: UploadedResidenceCard
  ): Promise<ResidenceCardVerification> {
    if (!file) {
      throw new BadRequestException("Missing file upload.");
    }

    return this.residenceCards.submitForUser({
      userId: req.user.id,
      filename: file.originalname || "residence-card",
      mimeType: file.mimetype,
      sizeBytes: file.size,
      content: file.buffer,
    });
  }
}
