/**
 * Advanced Booking Filter DTO
 *
 * Supports comprehensive filtering for booking searches
 */

import { ApiPropertyOptional } from '@nestjs/swagger';
import {
  IsOptional,
  IsString,
  IsArray,
  IsDateString,
  IsEnum,
  IsInt,
  Min,
  Max,
} from 'class-validator';
import { Type } from 'class-transformer';

export enum BookingStatusFilter {
  DRAFT = 'draft',
  PENDING_CONFIRMATION = 'pending_confirmation',
  CONFIRMED = 'confirmed',
  IN_TRANSIT = 'in_transit',
  DELIVERED = 'delivered',
  CANCELLED = 'cancelled',
}

export enum BookingSortField {
  CREATED_AT = 'createdAt',
  BOOKING_NUMBER = 'bookingNumber',
  STATUS = 'status',
  ETD = 'etd',
  ETA = 'eta',
}

export enum SortOrder {
  ASC = 'asc',
  DESC = 'desc',
}

export class BookingFilterDto {
  @ApiPropertyOptional({
    description: 'Page number (1-based)',
    example: 1,
    minimum: 1,
  })
  @IsOptional()
  @IsInt()
  @Min(1)
  @Type(() => Number)
  page?: number = 1;

  @ApiPropertyOptional({
    description: 'Number of items per page',
    example: 20,
    minimum: 1,
    maximum: 100,
  })
  @IsOptional()
  @IsInt()
  @Min(1)
  @Max(100)
  @Type(() => Number)
  pageSize?: number = 20;

  @ApiPropertyOptional({
    description: 'Filter by booking status (multiple)',
    enum: BookingStatusFilter,
    isArray: true,
    example: ['confirmed', 'in_transit'],
  })
  @IsOptional()
  @IsArray()
  @IsEnum(BookingStatusFilter, { each: true })
  status?: BookingStatusFilter[];

  @ApiPropertyOptional({
    description: 'Search by booking number (partial match)',
    example: 'WCM-2025',
  })
  @IsOptional()
  @IsString()
  search?: string;

  @ApiPropertyOptional({
    description: 'Filter by carrier name or code',
    example: 'Maersk',
  })
  @IsOptional()
  @IsString()
  carrier?: string;

  @ApiPropertyOptional({
    description: 'Filter by origin port code',
    example: 'NLRTM',
  })
  @IsOptional()
  @IsString()
  originPort?: string;

  @ApiPropertyOptional({
    description: 'Filter by destination port code',
    example: 'CNSHA',
  })
  @IsOptional()
  @IsString()
  destinationPort?: string;

  @ApiPropertyOptional({
    description: 'Filter by shipper name (partial match)',
    example: 'Acme Corp',
  })
  @IsOptional()
  @IsString()
  shipper?: string;

  @ApiPropertyOptional({
    description: 'Filter by consignee name (partial match)',
    example: 'XYZ Ltd',
  })
  @IsOptional()
  @IsString()
  consignee?: string;

  @ApiPropertyOptional({
    description: 'Filter by creation date from (ISO 8601)',
    example: '2025-01-01T00:00:00.000Z',
  })
  @IsOptional()
  @IsDateString()
  createdFrom?: string;

  @ApiPropertyOptional({
    description: 'Filter by creation date to (ISO 8601)',
    example: '2025-12-31T23:59:59.999Z',
  })
  @IsOptional()
  @IsDateString()
  createdTo?: string;

  @ApiPropertyOptional({
    description: 'Filter by ETD from (ISO 8601)',
    example: '2025-06-01T00:00:00.000Z',
  })
  @IsOptional()
  @IsDateString()
  etdFrom?: string;

  @ApiPropertyOptional({
    description: 'Filter by ETD to (ISO 8601)',
    example: '2025-06-30T23:59:59.999Z',
  })
  @IsOptional()
  @IsDateString()
  etdTo?: string;

  @ApiPropertyOptional({
    description: 'Sort field',
    enum: BookingSortField,
    example: BookingSortField.CREATED_AT,
  })
  @IsOptional()
  @IsEnum(BookingSortField)
  sortBy?: BookingSortField = BookingSortField.CREATED_AT;

  @ApiPropertyOptional({
    description: 'Sort order',
    enum: SortOrder,
    example: SortOrder.DESC,
  })
  @IsOptional()
  @IsEnum(SortOrder)
  sortOrder?: SortOrder = SortOrder.DESC;
}
