import {
  Body,
  Controller,
  Delete,
  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 { CreateProviderConfigDto } from "./dto/create-provider-config.dto";
import { ProviderConfigDto, ProviderConfigListDto } from "./dto/provider-config.dto";
import { UpdateProviderConfigDto } from "./dto/update-provider-config.dto";
import { ProviderConfigService } from "./provider-config.service";

@ApiTags("Admin · Provider Configs")
@ApiBearerAuth("adminUserAuth")
@ApiResponse({ status: 401, description: "Token admin faltante o inválido.", type: ApiErrorResponse })
@ApiResponse({ status: 404, description: "Merchant o config no encontrada.", type: ApiErrorResponse })
@Controller("admin/merchants/:merchantId/provider-configs")
@UseGuards(AdminUserGuard)
export class ProviderConfigAdminController {
  constructor(private readonly service: ProviderConfigService) {}

  @Post()
  @ApiOperation({
    operationId: "adminProviderConfigsCreate",
    summary: "Registrar pasarela del comercio",
    description:
      "Asocia credenciales del comercio en un provider (dLocal, Bancard, etc.). " +
      "Las credenciales se encriptan en reposo y nunca se devuelven por API.",
  })
  @ApiResponse({ status: 201, type: ProviderConfigDto })
  @ApiResponse({ status: 409, description: "Ya existe config para esa combinación.", type: ApiErrorResponse })
  create(
    @Param("merchantId") merchantId: string,
    @Body() dto: CreateProviderConfigDto,
  ) {
    return this.service.create(merchantId, dto);
  }

  @Get()
  @ApiOperation({
    operationId: "adminProviderConfigsList",
    summary: "Listar pasarelas del comercio",
  })
  @ApiQuery({ name: "limit", required: false, type: Number, example: 20 })
  @ApiQuery({ name: "cursor", required: false, type: String })
  @ApiResponse({ status: 200, type: ProviderConfigListDto })
  list(
    @Param("merchantId") merchantId: string,
    @Query("limit") limit?: string,
    @Query("cursor") cursor?: string,
  ) {
    return this.service.list(merchantId, limit ? Number(limit) : undefined, cursor);
  }

  @Get(":id")
  @ApiOperation({ operationId: "adminProviderConfigsRetrieve", summary: "Obtener pasarela por ID" })
  @ApiResponse({ status: 200, type: ProviderConfigDto })
  findOne(@Param("merchantId") merchantId: string, @Param("id") id: string) {
    return this.service.findOne(merchantId, id);
  }

  @Patch(":id")
  @ApiOperation({
    operationId: "adminProviderConfigsUpdate",
    summary: "Actualizar pasarela",
    description: "Si se envían `credentials`, **reemplazan** las anteriores (se re-encriptan).",
  })
  @ApiResponse({ status: 200, type: ProviderConfigDto })
  update(
    @Param("merchantId") merchantId: string,
    @Param("id") id: string,
    @Body() dto: UpdateProviderConfigDto,
  ) {
    return this.service.update(merchantId, id, dto);
  }

  @Delete(":id")
  @ApiOperation({ operationId: "adminProviderConfigsDelete", summary: "Eliminar pasarela del comercio" })
  @ApiResponse({ status: 200, description: "Eliminada." })
  remove(@Param("merchantId") merchantId: string, @Param("id") id: string) {
    return this.service.remove(merchantId, id);
  }
}
