import {
  Body,
  Controller,
  Delete,
  Get,
  HttpCode,
  Param,
  Patch,
  Post,
  Query,
  UseGuards,
} from "@nestjs/common";
import {
  ApiBearerAuth,
  ApiOperation,
  ApiQuery,
  ApiResponse,
  ApiTags,
} from "@nestjs/swagger";
import { ApiKeyGuard } from "../common/auth/api-key.guard";
import { MerchantAuth } from "../common/auth/auth-context.decorator";
import type { ApiKeyAuthContext } from "../common/auth/auth.types";
import { RequireFullScopeGuard } from "../common/auth/restricted-scope.guard";
import { ApiErrorResponse } from "../common/swagger/api-error.schema";
import { CreateWebhookEndpointDto } from "./dto/create-webhook-endpoint.dto";
import { UpdateWebhookEndpointDto } from "./dto/update-webhook-endpoint.dto";
import {
  CreatedWebhookEndpointDto,
  WebhookEndpointDto,
  WebhookEndpointListDto,
} from "./dto/webhook-endpoint.dto";
import { WebhookEndpointService } from "./webhook-endpoint.service";

@ApiTags("Webhook Endpoints")
@ApiBearerAuth("bearerAuth")
@ApiResponse({ status: 401, description: "API key faltante, inválida o revocada.", type: ApiErrorResponse })
@ApiResponse({ status: 403, description: "La API key no tiene scope `full` o el merchant está inactivo.", type: ApiErrorResponse })
@ApiResponse({ status: 429, description: "Rate limit excedido.", type: ApiErrorResponse })
@Controller("webhook-endpoints")
@UseGuards(ApiKeyGuard, RequireFullScopeGuard)
export class WebhookEndpointController {
  constructor(private readonly service: WebhookEndpointService) {}

  @Post()
  @ApiOperation({
    operationId: "webhookEndpointsCreate",
    summary: "Crear webhook endpoint",
    description:
      "Registra una URL para recibir eventos firmados con HMAC-SHA256. El `secret` se devuelve **solo una vez** en esta respuesta.",
  })
  @ApiResponse({ status: 201, type: CreatedWebhookEndpointDto })
  @ApiResponse({ status: 400, description: "Validación de body falló.", type: ApiErrorResponse })
  create(@MerchantAuth() auth: ApiKeyAuthContext, @Body() dto: CreateWebhookEndpointDto) {
    return this.service.create(auth.merchantId, dto);
  }

  @Get()
  @ApiOperation({ operationId: "webhookEndpointsList", summary: "Listar webhook endpoints" })
  @ApiQuery({ name: "limit", required: false, type: Number, example: 20 })
  @ApiQuery({ name: "cursor", required: false, type: String })
  @ApiResponse({ status: 200, type: WebhookEndpointListDto })
  list(
    @MerchantAuth() auth: ApiKeyAuthContext,
    @Query("limit") limit?: string,
    @Query("cursor") cursor?: string,
  ) {
    return this.service.list(auth.merchantId, limit ? Number(limit) : undefined, cursor);
  }

  @Get(":id")
  @ApiOperation({ operationId: "webhookEndpointsRetrieve", summary: "Obtener webhook endpoint" })
  @ApiResponse({ status: 200, type: WebhookEndpointDto })
  @ApiResponse({ status: 404, description: "No encontrado.", type: ApiErrorResponse })
  findOne(@MerchantAuth() auth: ApiKeyAuthContext, @Param("id") id: string) {
    return this.service.findOne(auth.merchantId, id);
  }

  @Patch(":id")
  @ApiOperation({ operationId: "webhookEndpointsUpdate", summary: "Actualizar webhook endpoint" })
  @ApiResponse({ status: 200, type: WebhookEndpointDto })
  @ApiResponse({ status: 404, description: "No encontrado.", type: ApiErrorResponse })
  update(
    @MerchantAuth() auth: ApiKeyAuthContext,
    @Param("id") id: string,
    @Body() dto: UpdateWebhookEndpointDto,
  ) {
    return this.service.update(auth.merchantId, id, dto);
  }

  @Delete(":id")
  @HttpCode(200)
  @ApiOperation({ operationId: "webhookEndpointsDelete", summary: "Eliminar webhook endpoint" })
  @ApiResponse({ status: 200, description: "Eliminado." })
  @ApiResponse({ status: 404, description: "No encontrado.", type: ApiErrorResponse })
  remove(@MerchantAuth() auth: ApiKeyAuthContext, @Param("id") id: string) {
    return this.service.remove(auth.merchantId, id);
  }
}
