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

/**
 * DTO representing a single student/case item within a commission enquiry.
 * Each item contains all the relevant student, course, and commission data
 * required for processing, calculation, and reporting of commissions.
 */
export class CommissionEnquiryItemDto {
  /**
   * Unique identifier for the case.
   * This is usually a system-generated alphanumeric ID used to identify the case
   * across all modules.
   * Example: 'CASE01115'
   */
  @ApiProperty({
    description: 'Unique identifier for the case',
    example: 'CASE01115',
  })
  @IsNotEmpty()
  @IsString()
  case_uid: string;

  /**
   * Optional: ISO 8601 formatted course end date.
   * Used for calculating commission timelines, reporting, or eligibility.
   * Example: '2028-06-29T18:30:00.000Z'
   */
  @ApiPropertyOptional({
    description: 'Course end date in ISO 8601 format',
    example: '2028-06-29T18:30:00.000Z',
    format: 'date-time',
  })
  @IsOptional()
  @IsDateString()
  course_end_date?: string;

  /**
   * Optional: ISO 8601 formatted course start date.
   * Useful to determine duration, deadlines, or eligibility for commissions.
   * Example: '2025-07-06T18:30:00.000Z'
   */
  @ApiPropertyOptional({
    description: 'Course start date in ISO 8601 format',
    example: '2025-07-06T18:30:00.000Z',
    format: 'date-time',
  })
  @IsOptional()
  @IsDateString()
  course_start_date?: string;

  /**
   * Student's first name.
   * Used for personalization, reporting, and identifying the student.
   * Example: 'Gauri'
   */
  @ApiProperty({
    description: "Student's first name",
    example: 'Gauri',
  })
  @IsNotEmpty()
  @IsString()
  fname: string;

  /**
   * Internal numeric ID for the student/case.
   * This is used internally in the database for fast referencing.
   * Example: 1115
   */
  @ApiProperty({
    description: 'Internal numeric ID of the student/case',
    example: 1115,
  })
  @IsNotEmpty()
  @IsInt()
  id: number;

  /**
   * Student's last name.
   * Used along with first name for full identification.
   * Example: 'Johar'
   */
  @ApiProperty({
    description: "Student's last name",
    example: 'Johar',
  })
  @IsNotEmpty()
  @IsString()
  lname: string;

  /**
   * Unique student identifier.
   * This could be a roll number or system-wide UID.
   * Example: '099695YZ'
   */
  @ApiProperty({
    description: "Student's unique identifier",
    example: '099695YZ',
  })
  @IsNotEmpty()
  @IsString()
  student_uid: string;

  /**
   * Optional: Date when the visa result was received (ISO 8601 format).
   * Used for reporting and determining if the commission is applicable.
   * Example: '2025-07-09T04:14:00.000Z'
   */
  @ApiPropertyOptional({
    description: 'Date when visa result was received (ISO 8601 format)',
    example: '2025-07-09T04:14:00.000Z',
    format: 'date-time',
  })
  @IsOptional()
  @IsDateString()
  visa_result_on?: string;

  /**
   * Optional: Visa status of the student.
   * 1 indicates granted, 0 indicates rejected, null if pending.
   * Used for conditional commission logic.
   * Example: 1
   */
  @ApiPropertyOptional({
    description: 'Visa status indicator (1=granted, 0=rejected)',
    example: 1,
  })
  @IsOptional()
  @IsInt()
  visa_status?: number;

  /**
   * Duplicate of case_uid.
   * Kept for structure consistency across modules.
   * Example: 'CASE01115'
   */
  @ApiProperty({
    description: 'Duplicate of case_uid for structure consistency',
    example: 'CASE01115',
  })
  @IsNotEmpty()
  @IsString()
  visa_case_id: string;

  /**
   * Currency code for the commission.
   * Example: 'AUD'
   */
  @ApiProperty({
    description: 'Currency code for commission',
    example: 'AUD',
  })
  @IsNotEmpty()
  @IsString()
  commission_currency: string;

  /**
   * Currency code for tuition fees.
   * Example: 'AUD'
   */
  @ApiProperty({
    description: 'Currency code for tuition fees',
    example: 'AUD',
  })
  @IsNotEmpty()
  @IsString()
  tuition_fees_currency: string;

  /**
   * Total tuition fees for the case.
   * Stored as string to handle large numbers or formatted values.
   * Example: '20409'
   */
  @ApiProperty({
    description: 'Total tuition fees as a string',
    example: '20409',
  })
  @IsNotEmpty()
  @IsNumberString()
  tuition_fees: string;

  /**
   * Type of commission applied.
   * Could be flat, percentage, or another predefined type.
   * Example: '2'
   */
  @ApiProperty({
    description: 'Type of commission applied',
    example: '2',
  })
  @IsNotEmpty()
  @IsString()
  commission_type: string;

  /**
   * Commission percentage applied.
   * Required if commission type is percentage-based.
   * Example: '2.00'
   */
  @ApiProperty({
    description: 'Commission percentage applied',
    example: '2.00',
  })
  @IsNotEmpty()
  @IsNumberString()
  commission_percentage: string;

  /**
   * Calculated commission amount in the commission_currency.
   * Computed based on tuition_fees and commission_percentage.
   * Example: '408.18'
   */
  @ApiProperty({
    description: 'Calculated commission amount',
    example: '408.18',
  })
  @IsNotEmpty()
  @IsNumberString()
  commission_amount: string;
}

/**
 * Main DTO for creating a Commission Enquiry.
 * Contains general commission enquiry information along with a nested array
 * of individual student/case items.
 */
export class CreateCommissionEnquiryDto {
  /**
   * Optional: ID of the record.
   * Used for updating existing records.
   * Example: '9'
   */
  @ApiPropertyOptional({
    description: 'ID of the record (used for updates)',
    example: '9',
  })
  @IsOptional()
  @IsNumberString()
  id?: string;

  /** Visa service country ID */
  @ApiProperty({
    description: 'ID of the visa service country',
    example: '9',
  })
  @IsNotEmpty()
  @IsNumberString()
  visa_service_country_id: string;

  /** Educational institute ID */
  @ApiProperty({
    description: 'ID of the educational institute',
    example: '459',
  })
  @IsNotEmpty()
  @IsNumberString()
  institute_id: string;

  /** Client originating country ID */
  @ApiProperty({
    description: "ID of the client's home country",
    example: '80',
  })
  @IsNotEmpty()
  @IsNumberString()
  client_from_country_id: string;

  /** Intake/session ID */
  @ApiProperty({
    description: 'ID of the intake/session',
    example: '95504',
  })
  @IsNotEmpty()
  @IsNumberString()
  intake_id: string;

  /** Applicable entity ID for commission */
  @ApiProperty({
    description: 'ID indicating what the commission is applicable on',
    example: '2',
  })
  @IsNotEmpty()
  @IsNumberString()
  applicable_on_id: string;

  /** Contract set ID used in this commission */
  @ApiProperty({
    description: 'ID of the contract set used',
    example: '2',
  })
  @IsNotEmpty()
  @IsNumberString()
  contract_set_id: string;

  /** Commission instance ID */
  @ApiProperty({
    description: 'ID of the commission instance',
    example: '3',
  })
  @IsNotEmpty()
  @IsNumberString()
  commission_instance_id: string;

  /** Branch ID for invoicing */
  @ApiProperty({
    description: 'ID of the branch for invoicing',
    example: '3',
  })
  @IsNotEmpty()
  @IsNumberString()
  invoice_branch_id: string;

  /** Bank account ID for invoicing */
  @ApiProperty({
    description: 'ID of the bank account for invoicing',
    example: '4',
  })
  @IsNotEmpty()
  @IsNumberString()
  invoice_bank_account_id: string;

  /** Currency code for tuition fees */
  @ApiProperty({
    description: 'Currency code for tuition fees',
    example: 'AUD',
  })
  @IsNotEmpty()
  @IsString()
  currency: string;

  /** Net commission amount calculated */
  @ApiProperty({
    description: 'Calculated net commission amount',
    example: '408.18',
  })
  @IsNotEmpty()
  @IsNumberString()
  net_amount: string;

  /** Association type (numeric enum) */
  @ApiProperty({
    description: 'Association type (numeric)',
  })
  @IsNotEmpty()
  @IsNumber()
  association_type: number;

  /** Optional: MA commission type */
  @ApiPropertyOptional({
    description: 'Type of MA commission (if applicable)',
    example: '2',
  })
  @IsOptional()
  @IsString()
  ma_commission_type?: string;

  /** Optional: MA commission percentage */
  @ApiPropertyOptional({
    description: 'MA commission percentage',
    example: '2.00',
  })
  @IsOptional()
  @IsNumberString()
  ma_commission_percentage?: string;

  /** Optional: Calculated MA commission amount */
  @ApiPropertyOptional({
    description: 'Calculated MA commission amount',
    example: '408.18',
  })
  @IsOptional()
  @IsNumberString()
  ma_commission_amount?: string;

  /** Array of student/case items under this commission enquiry */
  @ApiProperty({
    description: 'Array of commission enquiry items (student/case details)',
    type: [CommissionEnquiryItemDto],
  })
  @IsNotEmpty()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => CommissionEnquiryItemDto)
  items: CommissionEnquiryItemDto[];
}
