import {
  Body,
  Controller,
  Get,
  Param,
  Patch,
  Post,
  Query,
  UseGuards,
} from "@nestjs/common";
import {
  ApiBearerAuth,
  ApiOperation,
  ApiQuery,
  ApiResponse,
  ApiTags,
} from "@nestjs/swagger";
import { AdminUserGuard } from "../admin-auth/admin-user.guard";
import { ApiErrorResponse } from "../common/swagger/api-error.schema";
import { CreateMerchantDto } from "./dto/create-merchant.dto";
import { MerchantDto, MerchantListDto } from "./dto/merchant.dto";
import { UpdateMerchantDto } from "./dto/update-merchant.dto";
import { MerchantService } from "./merchant.service";

@ApiTags("Admin · Merchants")
@ApiBearerAuth("adminUserAuth")
@ApiResponse({ status: 401, description: "Token admin faltante o inválido.", type: ApiErrorResponse })
@ApiResponse({ status: 429, description: "Rate limit excedido.", type: ApiErrorResponse })
@Controller("admin/merchants")
@UseGuards(AdminUserGuard)
export class MerchantAdminController {
  constructor(private readonly service: MerchantService) {}

  @Post()
  @ApiOperation({
    operationId: "adminMerchantsCreate",
    summary: "Crear merchant",
    description: "Crea un nuevo merchant en el gateway. Solo accesible con `ADMIN_API_TOKEN`.",
  })
  @ApiResponse({ status: 201, description: "Merchant creado.", type: MerchantDto })
  @ApiResponse({ status: 400, description: "Validación de body falló.", type: ApiErrorResponse })
  @ApiResponse({ status: 409, description: "Email o slug en uso.", type: ApiErrorResponse })
  create(@Body() dto: CreateMerchantDto) {
    return this.service.create(dto);
  }

  @Get()
  @ApiOperation({
    operationId: "adminMerchantsList",
    summary: "Listar merchants",
    description: "Paginación por cursor. Devuelve `nextCursor` cuando hay más resultados.",
  })
  @ApiQuery({ name: "limit", required: false, type: Number, example: 20, description: "1–100. Default 20." })
  @ApiQuery({ name: "cursor", required: false, type: String, description: "`id` del último merchant de la página anterior." })
  @ApiResponse({ status: 200, type: MerchantListDto })
  list(@Query("limit") limit?: string, @Query("cursor") cursor?: string) {
    return this.service.list(limit ? Number(limit) : undefined, cursor);
  }

  @Get(":id")
  @ApiOperation({ operationId: "adminMerchantsRetrieve", summary: "Obtener merchant por ID" })
  @ApiResponse({ status: 200, type: MerchantDto })
  @ApiResponse({ status: 404, description: "Merchant no encontrado.", type: ApiErrorResponse })
  findOne(@Param("id") id: string) {
    return this.service.findOne(id);
  }

  @Patch(":id")
  @ApiOperation({ operationId: "adminMerchantsUpdate", summary: "Actualizar merchant" })
  @ApiResponse({ status: 200, type: MerchantDto })
  @ApiResponse({ status: 400, description: "Validación de body falló.", type: ApiErrorResponse })
  @ApiResponse({ status: 404, description: "Merchant no encontrado.", type: ApiErrorResponse })
  @ApiResponse({ status: 409, description: "Email en uso.", type: ApiErrorResponse })
  update(@Param("id") id: string, @Body() dto: UpdateMerchantDto) {
    return this.service.update(id, dto);
  }
}
