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';

export class CsvRateSearchDto {
  @ApiProperty({ description: 'Origin UN/LOCODE', example: 'FRFOS' })
  @IsNotEmpty()
  @IsString()
  origin: string;

  @ApiProperty({ description: 'Destination UN/LOCODE', example: 'CNSHA' })
  @IsNotEmpty()
  @IsString()
  destination: string;

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

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

  @ApiPropertyOptional({ description: 'Container type filter', example: 'LCL' })
  @IsOptional()
  @IsString()
  containerType?: string;

  @ApiPropertyOptional({ description: 'Cargo contains dangerous goods', example: false })
  @IsOptional()
  @IsBoolean()
  hasDangerousGoods?: boolean;

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

export class CsvRateSearchResponseDto {
  @ApiProperty({ description: 'Array of matching rate results', type: [Object] })
  results: CsvRateResultDto[];

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

  @ApiProperty({ description: 'CSV files searched', type: [String] })
  searchedFiles: string[];

  @ApiProperty({ description: 'Timestamp of search', example: '2026-05-11T10:30:00Z' })
  searchedAt: Date;

  @ApiProperty({ description: 'Applied filters' })
  appliedFilters: RateSearchFiltersDto;
}

export class FobBreakdownDto {
  documentation: number;
  isps: number;
  handling: number;
  solas: number;
  customs: number;
  ams_aci: number;
  isf5: number;
  dgAdmin: number;
}

export class PriceBreakdownDto {
  @ApiProperty({ description: 'Freight charge', example: 420.0 })
  freightCharge: number;

  @ApiProperty({ description: 'Freight currency', example: 'USD' })
  freightCurrency: string;

  @ApiProperty({ description: 'Fixed FOB charges (doc+ISPS+solas+customs+AMS+ISF5)', example: 185 })
  fobFixed: number;

  @ApiProperty({ description: 'FOB handling charge', example: 60 })
  fobHandling: number;

  @ApiProperty({ description: 'DG admin fee (FOB currency, 0 if non-DG)', example: 0 })
  fobDG: number;

  @ApiProperty({ description: 'FOB currency', example: 'EUR' })
  fobCurrency: string;

  @ApiProperty({ description: 'Itemized FOB breakdown', type: FobBreakdownDto })
  fobBreakdown: FobBreakdownDto;

  @ApiPropertyOptional({
    description: 'DG surcharge amount (null if on_request/not_accepted)',
    example: null,
  })
  dgSurchargeAmount: number | null;

  @ApiProperty({ description: 'DG surcharge currency', example: 'EUR' })
  dgSurchargeCurrency: string;

  @ApiProperty({
    description: 'DG surcharge status',
    enum: ['computed', 'on_request', 'not_accepted'],
    example: 'computed',
  })
  dgSurchargeStatus: string;

  @ApiProperty({ description: 'Total freight in freightCurrency', example: 420.0 })
  totalFreight: number;

  @ApiProperty({ description: 'Total FOB in fobCurrency', example: 245 })
  totalFob: number;

  @ApiProperty({ description: 'Sum for sorting (currency-naive)', example: 665.0 })
  totalPriceForSorting: number;

  @ApiProperty({ description: 'Primary currency', example: 'USD' })
  primaryCurrency: string;
}

export class CsvRateResultDto {
  @ApiProperty({ example: 'SSC Consolidation' })
  companyName: string;

  @ApiProperty({ example: 'bookings@ssc.com' })
  companyEmail: string;

  @ApiProperty({ description: 'Origin CFS name', example: 'Fos Sur Mer' })
  originCFS: string;

  @ApiProperty({ description: 'Origin UN/LOCODE', example: 'FRFOS' })
  origin: string;

  @ApiProperty({ description: 'Port of loading', example: 'FOS SUR MER' })
  portOfLoading: string;

  @ApiProperty({ description: 'Routing type', example: 'Direct' })
  routing: string;

  @ApiProperty({ description: 'Destination CFS name', example: 'Shanghai' })
  destinationCFS: string;

  @ApiProperty({ description: 'Destination UN/LOCODE', example: 'CNSHA' })
  destination: string;

  @ApiProperty({ description: 'Destination country', example: 'China' })
  destinationCountry: string;

  @ApiProperty({ example: 'LCL' })
  containerType: string;

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

  @ApiProperty({ description: 'Departure frequency', example: 'Weekly' })
  frequency: string;

  @ApiProperty({ description: 'Transit time (adjusted if service level)', example: 28 })
  transitDays: number;

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

  @ApiProperty({ description: 'Whether DG cargo is accepted', example: true })
  dgAccepted: boolean;

  @ApiProperty({ description: 'DG surcharge status', example: 'computed' })
  dgSurchargeStatus: string;

  @ApiProperty({ description: 'Internal remarks', example: 'GR1/GR2' })
  remarks: string;

  @ApiProperty({ example: 'CSV' })
  source: 'CSV';

  @ApiProperty({ description: 'Match score 0-100', example: 95 })
  matchScore: number;

  @ApiPropertyOptional({ enum: ['RAPID', 'STANDARD', 'ECONOMIC'] })
  serviceLevel?: string;

  @ApiPropertyOptional({ description: 'Price multiplier for service level', example: 1.0 })
  priceMultiplier?: number;

  @ApiPropertyOptional({
    description: 'Original transit days before service level adjustment',
    example: 28,
  })
  originalTransitDays?: number;
}
