import {
  IsEnum,
  IsIn,
  IsInt,
  IsISO8601,
  IsOptional,
  IsPositive,
  IsString,
  IsUUID,
} from "class-validator";
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import {
  PaymentEventType,
  PaymentReferenceType,
  PaymentService,
  ProviderMethod,
} from "@edr/types";

/**
 * Wire shape of the `PaymentEvent` envelope (@edr/types) delivered by the payment
 * microservice's outbox relay. Delivery is at-least-once — the consumer is idempotent.
 */
export class PaymentEventDto {
  @ApiProperty({ enum: [1] }) @IsIn([1]) version!: 1;
  @ApiProperty() @IsUUID() eventId!: string;
  @ApiProperty({ enum: ["payment.succeeded", "payment.failed"] })
  @IsIn(["payment.succeeded", "payment.failed"])
  eventType!: PaymentEventType;

  @ApiProperty() @IsISO8601() occurredAt!: string;
  @ApiProperty({ enum: PaymentService })
  @IsEnum(PaymentService)
  service!: string;
  @ApiProperty() @IsUUID() intentId!: string;
  @ApiProperty({ enum: PaymentReferenceType })
  @IsEnum(PaymentReferenceType)
  referenceType!: string;

  @ApiProperty() @IsString() referenceId!: string;
  @ApiProperty() @IsString() merchantOrderId!: string;
  @ApiProperty({ enum: ProviderMethod })
  @IsEnum(ProviderMethod)
  provider!: string;
  @ApiProperty() @IsInt() @IsPositive() amountMinor!: number;
  @ApiProperty() @IsString() currency!: string;

  @ApiPropertyOptional() @IsOptional() @IsString() providerTxnId?: string;
  @ApiPropertyOptional() @IsOptional() @IsISO8601() paidAt?: string;
  @ApiPropertyOptional() @IsOptional() @IsString() failureCode?: string;
  @ApiPropertyOptional() @IsOptional() @IsString() failureMessage?: string;
}

export class MarkPaidResponseDto {
  @ApiProperty() processed!: boolean;
  @ApiPropertyOptional() alreadyFinalized?: boolean;
  @ApiPropertyOptional() reason?: string;
}
