import {
  IsInt,
  IsOptional,
  IsString,
  IsDateString,
  IsNumberString,
  IsArray,
  ValidateNested,
  IsObject,
  IsNotEmpty,
} from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';

/* ------------------------------------ */
/*            ITEMS DTO                 */
/* ------------------------------------ */
/**
 * Represents a single commission-related visa case item.
 * Each item corresponds to one student / visa case
 * used for commission calculation.
 */
export class CommissionItemDto {
  /** Unique case identifier */
  @ApiProperty({ example: 'CASE00105' })
  @IsString()
  case_uid: string;

  /** Course end date (ISO format) */
  @ApiProperty({ example: '2025-12-11T18:30:00.000Z' })
  @IsDateString()
  course_end_date: string;

  /** Course start date (ISO format) */
  @ApiProperty({ example: '2025-02-09T18:30:00.000Z' })
  @IsDateString()
  course_start_date: string;

  /** Student first name */
  @ApiProperty({ example: 'Ashish' })
  @IsString()
  fname: string;

  /** Internal record ID */
  @ApiProperty({ example: 105 })
  @IsInt()
  id: number;

  /** Student last name */
  @ApiProperty({ example: 'Mahawar' })
  @IsString()
  lname: string;

  /** Unique student identifier */
  @ApiProperty({ example: '031751JH' })
  @IsString()
  student_uid: string;

  /** Visa result date */
  @ApiProperty({ example: '2025-03-17T04:42:50.000Z' })
  @IsDateString()
  visa_result_on: string;

  /** Visa status code */
  @ApiProperty({ example: 1 })
  @IsInt()
  visa_status: number;

  /** Visa case ID (string-based reference) */
  @ApiProperty({ example: '105' })
  @IsString()
  visa_case_id: string;

  /** Currency used for commission calculation */
  @ApiProperty({ example: 'USD' })
  @IsString()
  commission_currency: string;

  /** Tuition fee currency */
  @ApiProperty({ example: 'USD' })
  @IsString()
  tuition_fees_currency: string;

  /** Tuition fee amount */
  @ApiProperty({ example: '26744' })
  @IsNumberString()
  tuition_fees: string;

  /** Commission type identifier */
  @ApiProperty({ example: '1' })
  @IsString()
  commission_type: string;

  /** Commission percentage value */
  @ApiProperty({ example: '1000.00' })
  @IsString()
  commission_percentage: string;

  /** Calculated commission amount */
  @ApiProperty({ example: '1000.00' })
  @IsString()
  commission_amount: string;
}

/* ------------------------------------ */
/*          TAX DETAILS DTO             */
/* ------------------------------------ */
/**
 * Represents individual tax components
 * applied to the commission amount.
 */
export class TaxDetailDto {
  /** Tax name (e.g., GST, TDS) */
  @ApiProperty({ example: 'GST' })
  @IsString()
  tax_name: string;

  /** Tax percentage */
  @ApiProperty({ example: '7' })
  @IsNumberString()
  tax_per: string;

  /** Calculated tax amount */
  @ApiProperty({ example: 70 })
  @IsInt()
  tax_amount: number;
}

/* ------------------------------------ */
/*      MAIN CREATE DTO                 */
/* ------------------------------------ */
/**
 * Main DTO used to create a sub-agent commission payout.
 * Contains commission metadata, items, tax breakdown,
 * payment details, and optional attachments.
 */
export class CreateSubAgentCommissionDto {
  /** Sub-agent (associate) ID */
  @ApiProperty({ example: 1 })
  @IsNumberString()
  associate_id: number | string;

  /** Client originating country ID */
  @ApiProperty({ example: 80 })
  @IsNumberString()
  client_from_country_id: number | string;

  /** Visa service country ID */
  @ApiProperty({ example: 124 })
  @IsNumberString()
  visa_service_country_id: number | string;

  /** Institute ID */
  @ApiProperty({ example: 181 })
  @IsNumberString()
  institute_id: number | string;

  /** Intake ID */
  @ApiProperty({ example: 140757 })
  @IsNumberString()
  intake_id: number | string;

  /** Applicable-on configuration ID */
  @ApiProperty({ example: 9 })
  @IsNumberString()
  applicable_on_id: number | string;

  /** Commission contract set ID */
  @ApiProperty({ example: 9 })
  @IsNumberString()
  contract_set_id: number | string;

  /** Commission instance ID */
  @ApiProperty({ example: 15 })
  @IsNumberString()
  commission_instance_id: number | string;

  /** Commission currency */
  @ApiProperty({ example: 'USD' })
  @IsString()
  currency: string;

  /** Net commission amount before deductions */
  @ApiProperty({ example: 1000 })
  @IsNumberString()
  net_amount: number | string;

  /** Association type identifier */
  @ApiProperty({ example: 3 })
  @IsNumberString()
  association_type: number | string;

  /** Total tax amount */
  @ApiPropertyOptional({ example: 120 })
  // @IsNumberString()
  @IsOptional()
  total_tax_amount?: any;

  /** Other deduction amount */
  @ApiPropertyOptional({ example: '50.00' })
  @IsOptional()
  @IsString()
  other_deductions?: string | null;

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

  /** Final net amount in INR */
  @ApiProperty({
    example: '123375.00',
    description: 'Net amount in INR after all deductions',
  })
  @IsString()
  @IsNotEmpty({ message: 'Net amount in INR is required' })
  net_amount_inr: string;

  /** Payment date */
  @ApiProperty({
    example: '2025-10-15',
    description: 'Payment date (YYYY-MM-DD)',
  })
  @IsString()
  @IsNotEmpty({ message: 'Payment date is required' })
  payment_date: string;

  /** Payment mode ID */
  @ApiProperty({ example: 1, description: 'Payment mode (numeric value)' })
  @IsNumberString()
  @IsNotEmpty({ message: 'Payment mode is required' })
  payment_mode_id: number | string;

  /** Commission case items */
  @ApiPropertyOptional({
    type: [CommissionItemDto],
    description: 'List of commission case items',
  })
  @IsOptional()
  @Type(() => CommissionItemDto)
  items?: CommissionItemDto[];

  /** Tax breakdown details */
  @ApiPropertyOptional({
    type: [TaxDetailDto],
    description: 'Tax breakdown list',
  })
  @IsOptional()
  @Type(() => TaxDetailDto)
  tax_details?: TaxDetailDto[];

  /** Source bank account ID */
  @ApiPropertyOptional({ example: 15 })
  @IsNumberString()
  @IsOptional()
  from_bank_account_id?: number | string;

  /** Destination bank account ID */
  @ApiPropertyOptional({ example: 15 })
  @IsOptional()
  @IsNumberString()
  to_bank_account_id?: number | string;

  /** Transaction reference number */
  @ApiPropertyOptional({ example: 'TNN111' })
  @IsString()
  @IsOptional()
  transaction_id?: string;

  /** Uploaded attachment files */
  @ApiPropertyOptional({
    type: 'string',
    format: 'binary',
    required: false,
    description: 'Attachment files (optional)',
  })
  @IsOptional()
  attachment_files?: any;

  /** Uploaded tax-related files */
  @ApiPropertyOptional({
    type: 'string',
    format: 'binary',
    required: false,
    description: 'Attachment files (optional)',
  })
  @IsOptional()
  taxes?: any;

  /** Single attachment file */
  @ApiProperty({
    type: 'string',
    format: 'binary',
    required: false,
    description: 'Attachment files (optional)',
  })
  @IsOptional()
  attachment_file?: any;

  /** Remarks or internal notes */
  @ApiPropertyOptional({ example: 1000 })
  @IsString()
  @IsOptional()
  remarks?: string;
}
