import {
  IsString,
  IsNotEmpty,
  IsOptional,
  IsNumber,
  ValidateNested,
  IsNumberString,
} from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type, Transform } from 'class-transformer';
import { IsNumberOrStringDto } from 'src/utils/common/numberOrStringDto';

/**
 * DTO representing individual tax details for a bonus payment.
 */
class TaxDetailsDto {
  /**
   * Name of the tax (e.g., GST, TDS).
   * Optional field.
   */
  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  tax_name?: string;

  /**
   * Tax percentage.
   * Optional field.
   * Must be a number if provided.
   */
  @ApiPropertyOptional()
  @IsOptional()
  @Type(() => Number)
  @IsNumber()
  tax_per?: number;

  /**
   * Tax amount.
   * Optional field.
   * Must be a number if provided.
   */
  @ApiPropertyOptional()
  @IsOptional()
  @Type(() => Number)
  @IsNumber()
  tax_amount?: number;
}

/**
 * DTO used to create a record for a received bonus payment.
 * Captures details about the bonus, taxes, deductions, payment, and attachments.
 */
export class CreateBonusReceivedDto {
  /**
   * ID of the bonus record (optional, used for updates or reference).
   */
  @ApiPropertyOptional()
  @IsOptional()
  @Transform(({ value }) => (value !== undefined ? String(value) : value))
  @IsString()
  id?: string;

  /**
   * Type of association (e.g., Sub-Agent, Affiliate).
   * Required field.
   */
  @ApiProperty()
  @IsNotEmpty()
  @Transform(({ value }) => String(value))
  @IsString()
  association_type: string;

  /**
   * Visa service country ID associated with the bonus.
   * Required field.
   */
  @ApiProperty()
  @IsNotEmpty()
  @Transform(({ value }) => String(value))
  @IsString()
  visa_service_country_id: string;

  /**
   * ID of the associate receiving the bonus.
   * Required field.
   */
  @ApiProperty()
  @IsNotEmpty()
  @Transform(({ value }) => String(value))
  @IsString()
  associate_id: string;

  /**
   * Currency of the bonus amount (e.g., USD, INR).
   * Required field.
   */
  @ApiProperty()
  @IsNotEmpty()
  @IsString()
  currency: string;

  /**
   * Total bonus amount in the specified currency.
   * Required field.
   */
  @ApiProperty()
  @IsNotEmpty()
  @IsString()
  total_amount: string;

  /**
   * Conversion rate to INR (optional).
   */
  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  conversion_rate?: string;

  /**
   * Total amount converted to INR (optional).
   */
  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  @Transform(({ value }) => (value !== undefined ? String(value) : value))
  total_amount_inr?: string;

  /**
   * List of tax details applied to the bonus (optional).
   */
  @ApiPropertyOptional({
    type: [TaxDetailsDto],
    description: 'Array of tax details objects',
  })
  @IsOptional()
  @Type(() => TaxDetailsDto)
  tax_details?: TaxDetailsDto[];

  /**
   * Total tax amount applied to the bonus (optional).
   */
  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  total_tax_amount?: string;

  /**
   * Other deductions applied to the bonus (optional).
   */
  @ApiPropertyOptional({ example: '50.00', description: 'Other deductions' })
  @IsOptional()
  @IsString()
  other_deductions?: string | null;

  /**
   * Reason for other deductions (optional).
   */
  @ApiPropertyOptional({
    example: 'Some adjustment',
    description: 'Reason for other deductions',
  })
  @IsOptional()
  @IsString()
  deduction_reason?: string | null;

  /**
   * Net amount in INR after all deductions.
   * Required field.
   */
  @ApiProperty()
  @IsNotEmpty()
  @IsString()
  net_amount_inr: string;

  /**
   * Payment date for the bonus.
   * Required field.
   */
  @ApiProperty()
  @IsNotEmpty()
  @IsString()
  payment_date: string;

  /**
   * Payment mode ID.
   * Required field.
   */
  @ApiProperty()
  @IsNotEmpty()
  @Transform(({ value }) => String(value))
  @IsString()
  payment_mode_id: string;

  /**
   * Bank account ID used for payment (optional).
   */
  @ApiPropertyOptional({
    example: 22,
    description: 'Bank account',
  })
  @IsOptional()
  @IsNumberOrStringDto(1, 'Bank account')
  bank_account_id?: number | string | null;

  /**
   * Transaction reference ID (optional).
   */
  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  transaction_id?: string;

  /**
   * Array of attached files related to the transaction (optional).
   */
  @ApiPropertyOptional({ type: [Object] })
  @IsOptional()
  attachment_files?: any | null;

  /**
   * Array of attached files (optional, duplicate field for flexibility).
   */
  @ApiPropertyOptional({ type: [Object] })
  @IsOptional()
  attachment_file?: any[];

  /**
   * Additional remarks for the bonus (optional).
   */
  @ApiPropertyOptional({
    example: 'Bonus Remarks',
    description: 'Remarks',
  })
  @IsOptional()
  @IsString()
  remarks?: string | null;
}
