import { Body, Controller, Delete, Get, Param, Post, UseGuards } from "@nestjs/common";
import { ApiBearerAuth, ApiOperation, 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 { ApiKeyService } from "./api-key.service";
import { ApiKeyDto, CreatedApiKeyDto } from "./dto/api-key.dto";
import { CreateApiKeyDto } from "./dto/create-api-key.dto";

@ApiTags("API Keys")
@ApiBearerAuth("bearerAuth")
@ApiResponse({ status: 401, description: "API key faltante, inválida o revocada.", type: ApiErrorResponse })
@ApiResponse({ status: 403, description: "La API key autenticada no tiene scope `full`.", type: ApiErrorResponse })
@ApiResponse({ status: 429, description: "Rate limit excedido.", type: ApiErrorResponse })
@Controller("api-keys")
@UseGuards(ApiKeyGuard, RequireFullScopeGuard)
export class ApiKeyController {
  constructor(private readonly service: ApiKeyService) {}

  @Post()
  @ApiOperation({
    operationId: "apiKeysCreate",
    summary: "Crear API key",
    description:
      "Emite una nueva API key para el merchant autenticado. Requiere autenticarse con una key `secret` de scope `full`. " +
      "El valor completo (`secret`) se devuelve **una sola vez** en esta respuesta.",
  })
  @ApiResponse({ status: 201, type: CreatedApiKeyDto })
  @ApiResponse({ status: 400, description: "Validación de body falló.", type: ApiErrorResponse })
  create(@MerchantAuth() auth: ApiKeyAuthContext, @Body() dto: CreateApiKeyDto) {
    return this.service.create(auth.merchantId, dto);
  }

  @Get()
  @ApiOperation({
    operationId: "apiKeysList",
    summary: "Listar API keys del merchant",
    description: "Devuelve metadata. **Nunca** devuelve el valor completo, solo el `prefix`.",
  })
  @ApiResponse({ status: 200, type: [ApiKeyDto] })
  list(@MerchantAuth() auth: ApiKeyAuthContext) {
    return this.service.list(auth.merchantId);
  }

  @Delete(":id")
  @ApiOperation({
    operationId: "apiKeysRevoke",
    summary: "Revocar API key",
    description: "Marca la key como revocada (`revokedAt`). Idempotente: revocar una key ya revocada no falla.",
  })
  @ApiResponse({ status: 200, type: ApiKeyDto })
  @ApiResponse({ status: 404, description: "API key no encontrada o no pertenece al merchant.", type: ApiErrorResponse })
  revoke(@MerchantAuth() auth: ApiKeyAuthContext, @Param("id") id: string) {
    return this.service.revoke(auth.merchantId, id);
  }
}
