import { Body, Controller, Get, Header, Post, Req, UseGuards } from "@nestjs/common";
import { createZodDto, ZodResponse } from "nestjs-zod";
import type { RequestWithUser } from "@bff/modules/auth/auth.types.js";
import { RateLimit, RateLimitGuard } from "@bff/core/rate-limiting/index.js";
import { InternetEligibilityService } from "./application/internet-eligibility.service.js";
import type { InternetEligibilityDetails } from "@customer-portal/domain/services";
import {
  internetEligibilityDetailsSchema,
  internetEligibilityRequestSchema,
  internetEligibilityRequestResponseSchema,
} from "@customer-portal/domain/services";

class EligibilityRequestDto extends createZodDto(internetEligibilityRequestSchema) {}
class InternetEligibilityDetailsResponseDto extends createZodDto(
  internetEligibilityDetailsSchema
) {}
class InternetEligibilityRequestResponseDto extends createZodDto(
  internetEligibilityRequestResponseSchema
) {}

/**
 * Internet Eligibility Controller
 *
 * Authenticated endpoints for:
 * - fetching current Salesforce eligibility value
 * - requesting a (manual) eligibility/availability check
 *
 * Note: ServicesController is @Public, so we keep these endpoints in a separate controller
 * to ensure GlobalAuthGuard enforces authentication.
 */
@Controller("services/internet")
@UseGuards(RateLimitGuard)
export class InternetEligibilityController {
  constructor(private readonly eligibilityService: InternetEligibilityService) {}

  @Get("eligibility")
  @RateLimit({ limit: 60, ttl: 60 }) // 60/min per IP (cheap)
  @Header("Cache-Control", "private, no-store")
  @ZodResponse({
    description: "Get internet eligibility",
    type: InternetEligibilityDetailsResponseDto,
  })
  async getEligibility(@Req() req: RequestWithUser): Promise<InternetEligibilityDetails> {
    return this.eligibilityService.getEligibilityDetailsForUser(req.user.id);
  }

  @Post("eligibility-request")
  @RateLimit({ limit: 5, ttl: 300 }) // 5 per 5 minutes per IP
  @Header("Cache-Control", "private, no-store")
  @ZodResponse({
    description: "Request internet eligibility check",
    type: InternetEligibilityRequestResponseDto,
  })
  async requestEligibility(
    @Req() req: RequestWithUser,
    @Body() body: EligibilityRequestDto
  ): Promise<{ requestId: string }> {
    const requestId = await this.eligibilityService.requestEligibilityCheckForUser(req.user.id, {
      email: req.user.email,
      ...body,
    });
    return { requestId };
  }
}
