import {
  IsEnum,
  IsIn,
  IsNumber,
  IsOptional,
  IsPositive,
  IsString,
  Length,
  MaxLength,
} from "class-validator";
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import {
  InitiatePaymentRequest,
  PaymentPlatform,
  PaymentReferenceType,
  PaymentService,
  ProviderMethod,
} from "@edr/types";

/** Wire shape is the shared `InitiatePaymentRequest` contract from @edr/types. */
export class InitiatePaymentRequestDto implements InitiatePaymentRequest {
  @ApiProperty({ enum: PaymentService })
  @IsEnum(PaymentService)
  service!: PaymentService;

  @ApiProperty({ enum: PaymentReferenceType })
  @IsEnum(PaymentReferenceType)
  referenceType!: PaymentReferenceType;

  @ApiProperty({
    description:
      "Domain order id (booking/shipment id) — already validated by the calling app",
  })
  @IsString()
  @Length(1, 64)
  referenceId!: string;

  @ApiPropertyOptional({
    description:
      "Human-readable order ref shown on provider pages; defaults to referenceId",
  })
  @IsOptional()
  @IsString()
  @MaxLength(64)
  orderRef?: string;

  @ApiProperty({
    description:
      "Authoritative amount computed server-side by the app. Accepts decimals "
  })
  @IsNumber()
  @IsPositive()
  amountMinor!: number;

  @ApiProperty({ example: "ETB" })
  @IsString()
  @Length(3, 8)
  currency!: string;

  @ApiProperty({ enum: ProviderMethod })
  @IsEnum(ProviderMethod)
  provider!: ProviderMethod;

  @ApiPropertyOptional({ enum: ["web", "mobile"] })
  @IsOptional()
  @IsIn(["web", "mobile"])
  platform?: PaymentPlatform;

  @ApiPropertyOptional({
    description:
      "Payer wallet MSISDN for providers that pre-fill it (e.g. Waafi MWALLET_ACCOUNT)",
  })
  @IsOptional()
  @IsString()
  @MaxLength(32)
  payerAccount?: string;

  @ApiPropertyOptional({
    description:
      "Per-transaction browser return URL on success — each calling app passes its own UI " +
      "(passenger portal vs freight portal). UX only; never confirms payment. Falls back to " +
      "the provider config when omitted.",
  })
  @IsOptional()
  @IsString()
  @MaxLength(2048)
  returnUrl?: string;

  @ApiPropertyOptional({
    description: "Failure/cancel counterpart of returnUrl",
  })
  @IsOptional()
  @IsString()
  @MaxLength(2048)
  failureUrl?: string;

  @ApiPropertyOptional({
    description: "Caller key to dedupe retried initiations",
  })
  @IsOptional()
  @IsString()
  @MaxLength(128)
  idempotencyKey?: string;
}

export class IntentReferenceQueryDto {
  @ApiProperty({ enum: PaymentService })
  @IsEnum(PaymentService)
  service!: PaymentService;

  @ApiProperty({ enum: PaymentReferenceType })
  @IsEnum(PaymentReferenceType)
  referenceType!: PaymentReferenceType;

  @ApiProperty()
  @IsString()
  @Length(1, 64)
  referenceId!: string;
}
