import { Type } from "class-transformer";
import {
  IsArray,
  IsDateString,
  IsEnum,
  IsNumber,
  IsObject,
  IsOptional,
  IsString,
  MinLength,
  ValidateNested,
} from "class-validator";

/** One document's confirmed-after-review state. The service reads these
 *  fields and writes them onto either a matched Policy or a freshly created
 *  one. Anything null here is not written. */
export class ConfirmPolicyDocumentDto {
  @IsString() documentId!: string;

  /** Required when creating a new Policy; ignored if `policyId` is set. */
  @IsOptional() @IsString() customerId?: string;
  /** Set when the document matched an existing Policy. */
  @IsOptional() @IsString() policyId?: string;

  @IsOptional() @IsString() policyNumber?: string;
  @IsOptional() @IsString() insuredName?: string;
  @IsOptional() @IsString() additionalInsured?: string;
  @IsOptional() @IsString() agentName?: string;
  @IsOptional() @IsString() legalAddress?: string;
  @IsOptional() @IsString() zip?: string;
  @IsOptional() @IsDateString() policyFrom?: string;
  @IsOptional() @IsDateString() policyTo?: string;
  @IsOptional() @IsDateString() policyDate?: string;
  @IsOptional() @IsEnum(["MXN", "USD", "EUR"]) currency?: "MXN" | "USD" | "EUR";
  @IsOptional() @IsNumber() netPremium?: number;
  @IsOptional() @IsNumber() policyFee?: number;
  @IsOptional() @IsNumber() brokerFee?: number;
  @IsOptional() @IsNumber() total?: number;
  @IsOptional() @IsString() premiumPayment?: string;
  /** Coverages parsed off the PDF, passed through verbatim to Policy.coveragesJson. */
  @IsOptional() @IsObject() coveragesJson?: unknown;

  /** When true, write a Transaction(domain=INSURANCE, amount=-netPremium)
   *  in addition to creating/updating the Policy. Skipped if netPremium is
   *  null or zero. */
  @IsOptional() postPremium?: boolean;
}

export class ConfirmPolicyBatchDto {
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => ConfirmPolicyDocumentDto)
  documents!: ConfirmPolicyDocumentDto[];
}

/** Staff correction of one document's extracted fields or its match. */
export class ReviewPolicyDocumentDto {
  @IsOptional() @IsString() policyNumber?: string;
  @IsOptional() @IsString() insuredName?: string;
  @IsOptional() @IsString() additionalInsured?: string;
  @IsOptional() @IsString() agentName?: string;
  @IsOptional() @IsString() legalAddress?: string;
  @IsOptional() @IsString() zip?: string;
  @IsOptional() @IsDateString() policyFrom?: string;
  @IsOptional() @IsDateString() policyTo?: string;
  @IsOptional() @IsDateString() policyDate?: string;
  @IsOptional() @IsString() currency?: string;
  @IsOptional() @IsNumber() netPremium?: number;
  @IsOptional() @IsNumber() policyFee?: number;
  @IsOptional() @IsNumber() brokerFee?: number;
  @IsOptional() @IsNumber() total?: number;
  @IsOptional() @IsString() premiumPayment?: string;
  @IsOptional() @IsObject() coveragesJson?: unknown;

  /** Set by the reviewer when the document matched an existing Policy. */
  @IsOptional() @IsString() matchedPolicyId?: string;
  /** Set by the reviewer when creating a new Policy. */
  @IsOptional() @IsString() matchedCustomerId?: string;
  /** Force-confirm a doc even when the matcher left it ambiguous. */
  @IsOptional() forceConfirm?: boolean;
}

export class CreatePolicyOcrBatchDto {
  @IsOptional() @IsString() @MinLength(1) label?: string;
}