import { Controller, Get, Post, Body, Param, Request } from "@nestjs/common";
import { createZodDto, ZodResponse } from "nestjs-zod";
import {
  cancellationPreviewSchema,
  subscriptionIdParamSchema,
  internetCancelRequestSchema,
} from "@customer-portal/domain/subscriptions";
import type {
  CancellationPreview,
  InternetCancelRequest,
} from "@customer-portal/domain/subscriptions";
import type { RequestWithUser } from "@bff/modules/auth/auth.types.js";
import { CancellationService } from "./cancellation.service.js";

// DTOs
class SubscriptionIdParamDto extends createZodDto(subscriptionIdParamSchema) {}
class CancelRequestDto extends createZodDto(internetCancelRequestSchema) {}
class CancellationPreviewDto extends createZodDto(cancellationPreviewSchema) {}

/**
 * Unified Cancellation Controller
 *
 * Provides generic endpoints for cancelling any service type (SIM / Internet).
 * Service type is auto-detected from the subscription product name.
 */
@Controller("subscriptions/:id/cancel")
export class CancellationController {
  constructor(private readonly cancellationService: CancellationService) {}

  /**
   * GET /subscriptions/:id/cancel/preview
   *
   * Returns unified cancellation preview for any service type.
   * Includes:
   * - Service info (dynamic fields based on type)
   * - Terms and warnings
   * - Cancellation status from Salesforce Opportunity (if linked)
   */
  @Get("preview")
  @ZodResponse({ description: "Cancellation preview", type: CancellationPreviewDto })
  async getPreview(
    @Request() req: RequestWithUser,
    @Param() params: SubscriptionIdParamDto
  ): Promise<CancellationPreview> {
    return this.cancellationService.getPreview(req.user.id, params.id);
  }

  /**
   * POST /subscriptions/:id/cancel
   *
   * Submit cancellation request for any service type.
   * Routes to appropriate handler (Freebit for SIM, Case for Internet).
   */
  @Post()
  async submit(
    @Request() req: RequestWithUser,
    @Param() params: SubscriptionIdParamDto,
    @Body() body: CancelRequestDto
  ): Promise<void> {
    return this.cancellationService.submit(req.user.id, params.id, body as InternetCancelRequest);
  }
}
