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

/**
 * Represents a single item in a commission enquiry.
 * Each item typically corresponds to a single student or a visa case
 * for which the commission is being calculated.
 */
export class MaCommissionEnquiryItemDto {
  /**
   * Unique identifier for the case.
   * This is the system-wide case ID that links this commission record
   * to the student's visa case.
   *
   * Example: "CASE01115"
   */
  @ApiProperty({
    description: 'Unique identifier for the case',
    example: 'CASE01115',
  })
  @IsNotEmpty()
  @IsString()
  case_uid: string;

  /**
   * Optional end date of the course associated with the student.
   * Must be in ISO 8601 date-time format.
   * Helps in determining commission eligibility and reporting.
   *
   * 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 start date of the course.
   * Useful for calculating duration-based 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;

  /**
   * First name of the student.
   * Used for reporting and display purposes in commission statements.
   *
   * Example: "Gauri"
   */
  @ApiProperty({ description: "Student's first name", example: 'Gauri' })
  @IsNotEmpty()
  @IsString()
  fname: string;

  /**
   * Internal record ID of the student/visa case.
   * Unique numeric ID used internally in the system for reference.
   *
   * Example: 1115
   */
  @ApiProperty({ description: 'Internal numeric record ID', example: 1115 })
  @IsNotEmpty()
  @IsInt()
  id: number;

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

  /**
   * Unique student identifier.
   * Typically assigned by the system to maintain uniqueness across all students.
   *
   * Example: "099695YZ"
   */
  @ApiProperty({
    description: 'Unique student identifier',
    example: '099695YZ',
  })
  @IsNotEmpty()
  @IsString()
  student_uid: string;

  /**
   * Optional date when the visa result was received.
   * Helps determine if commission is due (e.g., only after visa is granted).
   *
   * Example: "2025-07-09T04:14:00.000Z"
   */
  @ApiPropertyOptional({
    description: 'Date when the visa result was received',
    example: '2025-07-09T04:14:00.000Z',
    format: 'date-time',
  })
  @IsOptional()
  @IsDateString()
  visa_result_on?: string;

  /**
   * Optional numeric code representing visa status.
   * For example, 1 = visa granted, 0 = pending, -1 = rejected.
   */
  @ApiPropertyOptional({ description: 'Visa status code', example: 1 })
  @IsOptional()
  @IsInt()
  visa_status?: number;

  /**
   * Duplicate of case_uid for internal structural consistency.
   * Used in some reports and APIs where visa_case_id is expected instead of case_uid.
   */
  @ApiProperty({
    description: 'Duplicate of case_uid for internal use',
    example: 'CASE01115',
  })
  @IsNotEmpty()
  @IsString()
  visa_case_id: string;

  /**
   * Currency code used for commission calculation.
   * Ensures proper conversion if multiple currencies are involved.
   *
   * Example: "AUD"
   */
  @ApiProperty({ description: 'Currency code for commission', example: 'AUD' })
  @IsNotEmpty()
  @IsString()
  commission_currency: string;

  /**
   * Currency code used for tuition fees.
   * Typically matches the currency in which the tuition is billed.
   *
   * Example: "AUD"
   */
  @ApiProperty({
    description: 'Currency code for tuition fees',
    example: 'AUD',
  })
  @IsNotEmpty()
  @IsString()
  tuition_fees_currency: string;

  /**
   * Total tuition fees for the student/case.
   * Represented as a string to avoid floating point precision errors in JS.
   *
   * Example: "20409"
   */
  @ApiProperty({ description: 'Total tuition fees', example: '20409' })
  @IsNotEmpty()
  @IsNumberString()
  tuition_fees: string;

  /**
   * Type of commission applicable.
   * Could represent different schemes (e.g., fixed, percentage-based).
   *
   * Example: "2"
   */
  @ApiProperty({ description: 'Type of commission', example: '2' })
  @IsNotEmpty()
  @IsString()
  commission_type: string;

  /**
   * Commission percentage applied on tuition fees.
   * Stored as string to maintain decimal precision.
   *
   * Example: "2.00"
   */
  @ApiProperty({ description: 'Commission percentage', example: '2.00' })
  @IsNotEmpty()
  @IsNumberString()
  commission_percentage: string;

  /**
   * Calculated commission amount based on tuition fees and commission_percentage.
   *
   * Example: "408.18"
   */
  @ApiProperty({
    description: 'Calculated commission amount',
    example: '408.18',
  })
  @IsNotEmpty()
  @IsNumberString()
  commission_amount: string;

  /**
   * Type of MA (Marketing Associate) commission.
   * Similar to commission_type but specific to MA commission.
   *
   * Example: "2"
   */
  @ApiProperty({ description: 'Type of MA commission', example: '2' })
  @IsNotEmpty()
  @IsString()
  ma_commission_type: string;

  /**
   * MA commission percentage applied.
   *
   * Example: "2.00"
   */
  @ApiProperty({ description: 'MA commission percentage', example: '2.00' })
  @IsNotEmpty()
  @IsNumberString()
  ma_commission_percentage: string;

  /**
   * Calculated MA commission amount based on tuition fees and MA commission percentage.
   *
   * Example: "408.18"
   */
  @ApiProperty({
    description: 'Calculated MA commission amount',
    example: '408.18',
  })
  @IsNotEmpty()
  @IsNumberString()
  ma_commission_amount: string;
}

/**
 * Main DTO for creating a Marketing Associate commission enquiry.
 * Contains general information about the enquiry and an array of detailed items.
 */
export class CreateMaCommissionEnquiryDto {
  /**
   * Optional ID of the commission enquiry record.
   * Used when updating an existing enquiry.
   *
   * Example: "9"
   */
  @ApiPropertyOptional({ description: 'Record ID for update', example: '9' })
  @IsOptional()
  @IsNumberString()
  id?: string;

  /** ID of the associate (MA) for whom the commission is being calculated */
  @ApiProperty({ description: 'Associate ID', example: '9' })
  @IsNotEmpty()
  @IsNumberString()
  associate_id: string;

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

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

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

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

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

  /** Contract set ID */
  @ApiProperty({ description: 'Contract set ID', example: '2' })
  @IsNotEmpty()
  @IsNumberString()
  contract_set_id: string;

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

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

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

  /** Currency code used for the overall commission calculation */
  @ApiProperty({ description: 'Currency code', example: 'AUD' })
  @IsNotEmpty()
  @IsString()
  currency: string;

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

  /** Type of association for MA (numeric code) */
  @ApiProperty({ description: 'Association type', example: 1 })
  @IsNotEmpty()
  @IsNumber()
  association_type: number;

  /** MA commission type (e.g., percentage or fixed) */
  @ApiProperty({ description: 'MA commission type', example: '2' })
  @IsNotEmpty()
  @IsString()
  ma_commission_type: string;

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

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

  /** Array of commission enquiry items detailing individual students or cases */
  @ApiProperty({
    description: 'Commission enquiry items',
    type: [MaCommissionEnquiryItemDto],
  })
  @IsNotEmpty()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => MaCommissionEnquiryItemDto)
  items: MaCommissionEnquiryItemDto[];
}
