import { ApiPropertyOptional } from '@nestjs/swagger';
import { IsIn, IsOptional, IsUUID } from 'class-validator';

import { PaginationQueryDto } from '../../../common/dto/pagination-query.dto';
import {
  TRAIN_SCHEDULE_STATUSES,
  TrainScheduleStatus,
} from '../../train-schedules/entities/train-schedule.entity';

export const TRAIN_SCHEDULE_SORT_FIELDS = [
  'createdAt',
  'scheduledDepartureDate',
  'reference',
  'trainNumber',
  'status',
] as const;
export type TrainScheduleSortField = (typeof TRAIN_SCHEDULE_SORT_FIELDS)[number];

/**
 * Schedules have no freight-type column — the type is DERIVED from the
 * bookings aboard (see `resolveScheduleFreightType`): a single kind yields
 * CONTAINER or BULK, both kinds yield MIXED, no bookings yield null (never
 * matched by this filter).
 */
export const TRAIN_SCHEDULE_FREIGHT_TYPES = ['CONTAINER', 'BULK', 'MIXED'] as const;
export type TrainScheduleFreightType = (typeof TRAIN_SCHEDULE_FREIGHT_TYPES)[number];

/**
 * Query for the train-schedule list (container/bulk boards). Pagination and
 * free-text `search` come from the shared {@link PaginationQueryDto}; search
 * matches schedule reference, train number, route yards, stations, or
 * locomotive code (case-insensitive). The remaining fields are exact-match
 * filters that the search never widens.
 */
export class ListTrainSchedulesQueryDto extends PaginationQueryDto {
  @ApiPropertyOptional({ enum: TRAIN_SCHEDULE_SORT_FIELDS, default: 'createdAt' })
  @IsOptional()
  @IsIn(TRAIN_SCHEDULE_SORT_FIELDS as unknown as string[])
  sortBy?: TrainScheduleSortField;

  /** Lifecycle status (exact match). */
  @ApiPropertyOptional({ enum: TRAIN_SCHEDULE_STATUSES })
  @IsOptional()
  @IsIn(TRAIN_SCHEDULE_STATUSES as unknown as string[])
  status?: TrainScheduleStatus;

  /** Derived freight type of the bookings aboard (exact match). */
  @ApiPropertyOptional({ enum: TRAIN_SCHEDULE_FREIGHT_TYPES })
  @IsOptional()
  @IsIn(TRAIN_SCHEDULE_FREIGHT_TYPES as unknown as string[])
  freightType?: TrainScheduleFreightType;

  /** Origin station/yard id (exact match). */
  @ApiPropertyOptional({ format: 'uuid' })
  @IsOptional()
  @IsUUID()
  originStationId?: string;

  /** Destination station/yard id (exact match). */
  @ApiPropertyOptional({ format: 'uuid' })
  @IsOptional()
  @IsUUID()
  destinationStationId?: string;
}
