import {
  IsString,
  IsNotEmpty,
  IsOptional,
  IsDate,
  Matches,
} from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type, Transform } from 'class-transformer';

/**
 * DTO representing the details of a commission received transaction.
 * Used when recording or fetching commission payments for a Marketing Associate or similar entity.
 */
export class CommissionReceivedDto {
  /**
   * Type of association for which commission is received.
   * Typically a numeric string mapping to an association enum (e.g., 1 = Institute, 2 = Agent).
   *
   * Example: "1"
   */
  @ApiProperty({ description: 'Association type', example: '1' })
  @IsString()
  @IsNotEmpty()
  association_type: string;

  /**
   * Unique identifier for the commission enquiry record.
   * Links this received commission to a specific enquiry or contract.
   *
   * Example: "12345"
   */
  @ApiProperty({ description: 'Commission enquiry ID', example: '12345' })
  @IsString()
  @IsNotEmpty()
  commission_enquiry_id: string;

  /**
   * Total amount received as commission.
   * Must be a valid decimal number with up to 2 decimal places.
   * Stored as a string to prevent floating-point precision issues.
   *
   * Example: "1000.00"
   */
  @ApiProperty({ description: 'Total amount received', example: '0' })
  @IsString()
  @IsNotEmpty()
  @Matches(/^\d+(\.\d{1,2})?$/, {
    message: 'Total amount must be a valid number with up to 2 decimal places',
  })
  total_amount: string;

  /**
   * Currency code for the commission amount.
   * Usually matches ISO 4217 currency codes (e.g., USD, INR, AUD).
   *
   * Example: "USD"
   */
  @ApiProperty({ description: 'Currency code', example: '0' })
  @IsString()
  @IsNotEmpty()
  currency: string;

  /**
   * Conversion rate used to convert the commission into another currency (if applicable).
   * Decimal number with up to 6 decimal places.
   *
   * Example: "82.65" (USD to INR conversion rate)
   */
  @ApiProperty({ description: 'Conversion rate', example: '0' })
  @IsString()
  @IsNotEmpty()
  @Matches(/^\d+(\.\d{1,6})?$/, {
    message:
      'Conversion rate must be a valid number with up to 6 decimal places',
  })
  conversion_rate: string;

  /**
   * Total amount in INR (Indian Rupees) after conversion.
   * Optional if conversion is not applicable.
   *
   * Example: "82650.00"
   */
  @ApiPropertyOptional({ description: 'Total amount in INR', example: '' })
  @IsString()
  @IsOptional()
  total_amount_inr: string;

  /**
   * JSON object containing tax breakdown details.
   * Optional field; may be null if no taxes are applied.
   * Input as stringified JSON will be parsed automatically.
   *
   * Example: { gst: 18, tds: 5 }
   */
  @ApiPropertyOptional({ description: 'Tax details', example: null })
  @IsOptional()
  @Transform(({ value }) => {
    try {
      return value ? JSON.parse(value) : null;
    } catch {
      return value;
    }
  })
  tax_details: any;

  /**
   * Total tax amount deducted from the commission.
   * Must be a decimal number with up to 2 decimal places.
   *
   * Example: "180.00"
   */
  @ApiProperty({ description: 'Total tax amount', example: '0.00' })
  @IsString()
  @IsNotEmpty()
  @Matches(/^\d+(\.\d{1,2})?$/, {
    message:
      'Total tax amount must be a valid number with up to 2 decimal places',
  })
  total_tax_amount: string;

  /**
   * Optional field for other deductions (e.g., service charges, penalties).
   * Stored as a string for decimal precision. May be null or omitted.
   *
   * Example: "50.00"
   */
  @ApiProperty({ description: 'Other deductions', example: '0.00' })
  @IsString()
  @IsOptional()
  other_deductions?: string;

  /**
   * Optional reason for any deductions applied.
   *
   * Example: "Penalty for late submission"
   */
  @ApiPropertyOptional({ description: 'Deduction reason', example: '' })
  @IsString()
  @IsOptional()
  deduction_reason: string;

  /**
   * Net commission amount in INR after all deductions and taxes.
   * Must be a decimal number with up to 2 decimal places.
   *
   * Example: "795.00"
   */
  @ApiProperty({ description: 'Net amount in INR', example: '0.00' })
  @IsString()
  @IsNotEmpty()
  @Matches(/^\d+(\.\d{1,2})?$/, {
    message: 'Net amount must be a valid number with up to 2 decimal places',
  })
  net_amount_inr: string;

  /**
   * Date when the payment was made.
   * Optional if the payment date is not yet available.
   * Automatically transformed to a Date object if provided.
   */
  @ApiPropertyOptional({ description: 'Payment date', example: null })
  @IsOptional()
  @Transform(({ value }) => (value ? new Date(value) : null))
  @Type(() => Date)
  @IsDate()
  payment_date: Date | null;

  /**
   * ID representing the payment mode (e.g., bank transfer, cheque, cash).
   *
   * Example: "1" for bank transfer
   */
  @ApiProperty({ description: 'Payment mode ID', example: '' })
  @IsString()
  @IsNotEmpty()
  payment_mode_id: string;

  /**
   * ID of the bank account to which payment was made.
   *
   * Example: "BANK12345"
   */
  @ApiProperty({ description: 'Bank account ID', example: '' })
  @IsString()
  @IsNotEmpty()
  bank_account_id: string;

  /**
   * Optional transaction identifier for reference.
   * Useful for reconciliation purposes.
   *
   * Example: "TXN987654321"
   */
  @ApiPropertyOptional({ description: 'Transaction ID', example: '' })
  @IsString()
  @IsOptional()
  transaction_id: string;

  /**
   * Optional single attachment related to the payment (e.g., invoice, receipt).
   */
  @ApiPropertyOptional({ description: 'Attachment file', example: null })
  @IsOptional()
  attachment_file?: any;

  /**
   * Optional multiple attachments related to the payment.
   */
  @ApiPropertyOptional({ description: 'Attachment files', example: null })
  @IsOptional()
  attachment_files?: any;

  /**
   * Optional remarks about the payment.
   *
   * Example: "Payment received via NEFT"
   */
  @ApiPropertyOptional({ description: 'Remarks', example: '' })
  @IsString()
  @IsOptional()
  remarks: string;

  /**
   * Optional array containing itemized details related to this commission payment.
   * Can include breakdowns per student or per visa case.
   */
  @ApiPropertyOptional({ description: 'Items array', example: [] })
  @IsOptional()
  items?: any;
}
