import { Body, Controller, Get, Param, Post, Request, UseGuards } from "@nestjs/common";
import { createZodDto, ZodResponse } from "nestjs-zod";
import { Public } from "@bff/modules/auth/decorators/public.decorator.js";
import { CheckoutService } from "../services/checkout.service.js";
import { CheckoutSessionService } from "../services/checkout-session.service.js";
import {
  checkoutCartSchema,
  checkoutBuildCartRequestSchema,
  checkoutSessionIdParamSchema,
  checkoutSessionDataSchema,
  checkoutValidateCartDataSchema,
} from "@customer-portal/domain/orders";
import type { RequestWithUser } from "@bff/modules/auth/auth.types.js";
import { SalesforceReadThrottleGuard } from "@bff/integrations/salesforce/guards/salesforce-read-throttle.guard.js";

class CheckoutBuildCartRequestDto extends createZodDto(checkoutBuildCartRequestSchema) {}
class CheckoutSessionIdParamDto extends createZodDto(checkoutSessionIdParamSchema) {}
class CheckoutCartDto extends createZodDto(checkoutCartSchema) {}
class CheckoutBuildCartResponseDto extends createZodDto(checkoutCartSchema) {}
class CheckoutSessionResponseDto extends createZodDto(checkoutSessionDataSchema) {}
class ValidateCartResponseDto extends createZodDto(checkoutValidateCartDataSchema) {}

@Controller("checkout")
@Public() // Cart building and validation can be done without authentication
export class CheckoutController {
  constructor(
    private readonly checkoutService: CheckoutService,
    private readonly checkoutSessions: CheckoutSessionService
  ) {}

  @Post("cart")
  @UseGuards(SalesforceReadThrottleGuard)
  @ZodResponse({
    status: 201,
    description: "Build checkout cart",
    type: CheckoutBuildCartResponseDto,
  })
  async buildCart(@Request() req: RequestWithUser, @Body() body: CheckoutBuildCartRequestDto) {
    return this.checkoutService.buildCart(
      body.orderType,
      body.selections,
      body.configuration,
      req.user?.id
    );
  }

  /**
   * Create a short-lived checkout session to avoid trusting client-side state.
   * This returns a cart summary (items + totals) and stores the full request+cart server-side.
   */
  @Post("session")
  @UseGuards(SalesforceReadThrottleGuard)
  @ZodResponse({
    status: 201,
    description: "Create checkout session",
    type: CheckoutSessionResponseDto,
  })
  async createSession(@Request() req: RequestWithUser, @Body() body: CheckoutBuildCartRequestDto) {
    const cart = await this.checkoutService.buildCart(
      body.orderType,
      body.selections,
      body.configuration,
      req.user?.id
    );

    return this.checkoutSessions.createSessionWithResponse(body, cart);
  }

  @Get("session/:sessionId")
  @UseGuards(SalesforceReadThrottleGuard)
  @ZodResponse({
    status: 200,
    description: "Get checkout session",
    type: CheckoutSessionResponseDto,
  })
  async getSession(@Param() params: CheckoutSessionIdParamDto) {
    return this.checkoutSessions.getSessionResponse(params.sessionId);
  }

  @Post("validate")
  @ZodResponse({
    status: 201,
    description: "Validate checkout cart",
    type: ValidateCartResponseDto,
  })
  validateCart(@Body() cart: CheckoutCartDto) {
    this.checkoutService.validateCart(cart);
    return { valid: true };
  }
}
