import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
  IsNotEmpty,
  IsString,
  IsNumber,
  Min,
  IsOptional,
  ValidateNested,
  IsBoolean,
} from 'class-validator';
import { Type } from 'class-transformer';
import { RateSearchFiltersDto } from './rate-search-filters.dto';

/**
 * CSV Rate Search Request DTO
 *
 * Request body for searching rates in CSV-based system
 * Includes basic search parameters + optional advanced filters
 */
export class CsvRateSearchDto {
  @ApiProperty({
    description: 'Origin port code (UN/LOCODE format)',
    example: 'NLRTM',
    pattern: '^[A-Z]{2}[A-Z0-9]{3}$',
  })
  @IsNotEmpty()
  @IsString()
  origin: string;

  @ApiProperty({
    description: 'Destination port code (UN/LOCODE format)',
    example: 'USNYC',
    pattern: '^[A-Z]{2}[A-Z0-9]{3}$',
  })
  @IsNotEmpty()
  @IsString()
  destination: string;

  @ApiProperty({
    description: 'Volume in cubic meters (CBM)',
    minimum: 0.01,
    example: 25.5,
  })
  @IsNotEmpty()
  @IsNumber()
  @Min(0.01)
  volumeCBM: number;

  @ApiProperty({
    description: 'Weight in kilograms',
    minimum: 1,
    example: 3500,
  })
  @IsNotEmpty()
  @IsNumber()
  @Min(1)
  weightKG: number;

  @ApiPropertyOptional({
    description: 'Number of pallets (0 if no pallets)',
    minimum: 0,
    example: 10,
    default: 0,
  })
  @IsOptional()
  @IsNumber()
  @Min(0)
  palletCount?: number;

  @ApiPropertyOptional({
    description: 'Container type filter (e.g., LCL, 20DRY, 40HC)',
    example: 'LCL',
  })
  @IsOptional()
  @IsString()
  containerType?: string;

  @ApiPropertyOptional({
    description: 'Advanced filters for narrowing results',
    type: RateSearchFiltersDto,
  })
  @IsOptional()
  @ValidateNested()
  @Type(() => RateSearchFiltersDto)
  filters?: RateSearchFiltersDto;

  // Service requirements for detailed price calculation
  @ApiPropertyOptional({
    description: 'Cargo contains dangerous goods (DG)',
    example: true,
    default: false,
  })
  @IsOptional()
  @IsBoolean()
  hasDangerousGoods?: boolean;

  @ApiPropertyOptional({
    description: 'Requires special handling',
    example: true,
    default: false,
  })
  @IsOptional()
  @IsBoolean()
  requiresSpecialHandling?: boolean;

  @ApiPropertyOptional({
    description: 'Requires tailgate lift',
    example: false,
    default: false,
  })
  @IsOptional()
  @IsBoolean()
  requiresTailgate?: boolean;

  @ApiPropertyOptional({
    description: 'Requires securing straps',
    example: true,
    default: false,
  })
  @IsOptional()
  @IsBoolean()
  requiresStraps?: boolean;

  @ApiPropertyOptional({
    description: 'Requires thermal protection cover',
    example: false,
    default: false,
  })
  @IsOptional()
  @IsBoolean()
  requiresThermalCover?: boolean;

  @ApiPropertyOptional({
    description: 'Contains regulated products requiring special documentation',
    example: false,
    default: false,
  })
  @IsOptional()
  @IsBoolean()
  hasRegulatedProducts?: boolean;

  @ApiPropertyOptional({
    description: 'Requires delivery appointment',
    example: true,
    default: false,
  })
  @IsOptional()
  @IsBoolean()
  requiresAppointment?: boolean;
}

/**
 * CSV Rate Search Response DTO
 *
 * Response containing matching rates with calculated prices
 */
export class CsvRateSearchResponseDto {
  @ApiProperty({
    description: 'Array of matching rate results',
    type: [Object], // Will be replaced with RateResultDto
  })
  results: CsvRateResultDto[];

  @ApiProperty({
    description: 'Total number of results found',
    example: 15,
  })
  totalResults: number;

  @ApiProperty({
    description: 'CSV files that were searched',
    type: [String],
    example: ['ssc-consolidation.csv', 'ecu-worldwide.csv'],
  })
  searchedFiles: string[];

  @ApiProperty({
    description: 'Timestamp when search was executed',
    example: '2025-10-23T10:30:00Z',
  })
  searchedAt: Date;

  @ApiProperty({
    description: 'Filters that were applied to the search',
    type: RateSearchFiltersDto,
  })
  appliedFilters: RateSearchFiltersDto;
}

/**
 * Surcharge Item DTO
 */
export class SurchargeItemDto {
  @ApiProperty({
    description: 'Surcharge code',
    example: 'DG_FEE',
  })
  code: string;

  @ApiProperty({
    description: 'Surcharge description',
    example: 'Dangerous goods fee',
  })
  description: string;

  @ApiProperty({
    description: 'Surcharge amount in currency',
    example: 65.0,
  })
  amount: number;

  @ApiProperty({
    description: 'Type of surcharge calculation',
    enum: ['FIXED', 'PER_UNIT', 'PERCENTAGE'],
    example: 'FIXED',
  })
  type: 'FIXED' | 'PER_UNIT' | 'PERCENTAGE';
}

/**
 * Price Breakdown DTO
 */
export class PriceBreakdownDto {
  @ApiProperty({
    description: 'Base price before any charges',
    example: 0,
  })
  basePrice: number;

  @ApiProperty({
    description: 'Charge based on volume (CBM)',
    example: 150.0,
  })
  volumeCharge: number;

  @ApiProperty({
    description: 'Charge based on weight (KG)',
    example: 25.0,
  })
  weightCharge: number;

  @ApiProperty({
    description: 'Charge for pallets',
    example: 125.0,
  })
  palletCharge: number;

  @ApiProperty({
    description: 'List of all surcharges',
    type: [SurchargeItemDto],
  })
  surcharges: SurchargeItemDto[];

  @ApiProperty({
    description: 'Total of all surcharges',
    example: 242.0,
  })
  totalSurcharges: number;

  @ApiProperty({
    description: 'Total price including all charges',
    example: 542.0,
  })
  totalPrice: number;

  @ApiProperty({
    description: 'Currency of the pricing',
    enum: ['USD', 'EUR'],
    example: 'USD',
  })
  currency: string;
}

/**
 * Single CSV Rate Result DTO
 */
export class CsvRateResultDto {
  @ApiProperty({
    description: 'Company name',
    example: 'SSC Consolidation',
  })
  companyName: string;

  @ApiProperty({
    description: 'Company email for booking requests',
    example: 'bookings@sscconsolidation.com',
  })
  companyEmail: string;

  @ApiProperty({
    description: 'Origin port code',
    example: 'NLRTM',
  })
  origin: string;

  @ApiProperty({
    description: 'Destination port code',
    example: 'USNYC',
  })
  destination: string;

  @ApiProperty({
    description: 'Container type',
    example: 'LCL',
  })
  containerType: string;

  @ApiProperty({
    description: 'Calculated price in USD',
    example: 1850.5,
  })
  priceUSD: number;

  @ApiProperty({
    description: 'Calculated price in EUR',
    example: 1665.45,
  })
  priceEUR: number;

  @ApiProperty({
    description: 'Primary currency of the rate',
    enum: ['USD', 'EUR'],
    example: 'USD',
  })
  primaryCurrency: string;

  @ApiProperty({
    description: 'Detailed price breakdown with all charges',
    type: PriceBreakdownDto,
  })
  priceBreakdown: PriceBreakdownDto;

  @ApiProperty({
    description: 'Whether this rate has separate surcharges',
    example: true,
  })
  hasSurcharges: boolean;

  @ApiProperty({
    description: 'Details of surcharges if any',
    example: 'BAF+CAF included',
    nullable: true,
  })
  surchargeDetails: string | null;

  @ApiProperty({
    description: 'Transit time in days',
    example: 28,
  })
  transitDays: number;

  @ApiProperty({
    description: 'Rate validity end date',
    example: '2025-12-31',
  })
  validUntil: string;

  @ApiProperty({
    description: 'Source of the rate',
    enum: ['CSV', 'API'],
    example: 'CSV',
  })
  source: 'CSV' | 'API';

  @ApiProperty({
    description: 'Match score (0-100) indicating how well this rate matches the search',
    minimum: 0,
    maximum: 100,
    example: 95,
  })
  matchScore: number;
}
