import { ApiProperty } from "@nestjs/swagger";
import { PaymentMethod, Provider } from "@prisma/client";

export class ProviderCatalogEntryDto {
  @ApiProperty({
    enum: Provider,
    example: Provider.dlocal,
    description: "Identificador interno del provider — el mismo valor que se usa en provider-configs y en `defaultProvider`.",
  })
  id!: Provider;

  @ApiProperty({
    example: "dLocal Go",
    description: "Nombre comercial para mostrar en UI.",
  })
  displayName!: string;

  @ApiProperty({
    example: ["PY"],
    description: "Países (ISO 3166-1 alpha-2) en los que el provider opera.",
    type: [String],
  })
  countries!: string[];

  @ApiProperty({
    example: ["card", "transfer"],
    description: "Métodos de pago soportados.",
    type: [String],
  })
  paymentMethods!: string[];

  @ApiProperty({
    example: ["sandbox", "live"],
    description: "Modos de operación disponibles.",
    type: [String],
  })
  modes!: ("sandbox" | "live")[];

  @ApiProperty({
    example: true,
    description: "Si el adapter está implementado y listo para uso productivo. Los providers con `available: false` figuran como roadmap.",
  })
  available!: boolean;

  @ApiProperty({
    example: "https://docs.dlocalgo.com/integration-api",
    description: "Link a la documentación oficial del provider para integradores.",
    required: false,
    nullable: true,
  })
  docsUrl?: string | null;

  @ApiProperty({
    example: { PYG: 10000 },
    description:
      "Monto mínimo por moneda que el provider acepta, en la unidad principal (PYG en guaraníes). " +
      "Los clientes (ej. el ERP) validan el monto del cobro contra este mínimo según el provider ruteado.",
    required: false,
    nullable: true,
    additionalProperties: { type: "number" },
  })
  minAmount?: Record<string, number> | null;

  @ApiProperty({
    example: true,
    description:
      "Si el provider exige elegir un medio de pago (`platformId`) para el cobro DIRECTO. " +
      "Los clientes muestran el selector de método sólo cuando es true (ej. Dpago directo).",
    required: false,
  })
  requiresPlatformId?: boolean;

  @ApiProperty({
    example: ["email", "name", "docNumber", "phone"],
    description:
      "Campos del comprador que el provider necesita para un cobro DIRECTO (nombres canónicos del " +
      "gateway). Los clientes validan estos campos antes de confirmar. Vacío ⇒ el provider los pide " +
      "en su propio checkout (ej. dLocal hosted).",
    required: false,
    type: [String],
  })
  requiredCustomerFields?: string[];

  @ApiProperty({
    example: true,
    description: "Si soporta cobro DIRECTO (confirmar en el acto, ej. QR embebido).",
    required: false,
  })
  supportsDirect?: boolean;

  @ApiProperty({
    example: true,
    description: "Si soporta checkout HOSPEDADO de Novasis (link genérico con selector de método).",
    required: false,
  })
  supportsHosted?: boolean;

  @ApiProperty({
    example: true,
    description:
      "Si el provider ofrece un LINK DE PAGO nativo propio (ej. Dpago `/links`). Cuando es true, el " +
      "modo 'link de pago' usa el link del provider en vez del checkout hospedado de Novasis.",
    required: false,
  })
  supportsNativeLink?: boolean;

  @ApiProperty({
    example: ["qr"],
    description: "Capacidades extra soportadas (ej. `qr`, `refund`).",
    required: false,
    type: [String],
  })
  features?: string[];
}

export class ProviderCatalogResponseDto {
  @ApiProperty({ type: [ProviderCatalogEntryDto] })
  providers!: ProviderCatalogEntryDto[];
}

export class ProviderPaymentMethodDto {
  @ApiProperty({
    example: "18",
    description: "Código del medio de pago en el provider (ej. `platformId` de Dpago).",
  })
  platformId!: string;

  @ApiProperty({ example: "QR Ueno", description: "Nombre legible del medio de pago." })
  name!: string;

  @ApiProperty({
    enum: PaymentMethod,
    example: PaymentMethod.wallet,
    description: "Método interno normalizado del gateway.",
  })
  method!: PaymentMethod;
}

export class ProviderPaymentMethodsResponseDto {
  @ApiProperty({ type: [ProviderPaymentMethodDto] })
  methods!: ProviderPaymentMethodDto[];
}
