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

export class RouteStopInputDto {
  @ApiProperty({ example: 'station-uuid', description: 'Station UUID' }) @IsString() stationId: string;
  @ApiProperty({ example: 1, description: 'Stop order (1 = origin, ascending)' }) @IsInt() @Min(1) sequence: number;
  @ApiPropertyOptional({ example: 120.5, description: 'Cumulative distance in km from the route origin (not from the previous stop)' }) @IsOptional() @IsNumber() distanceKm?: number;
  @ApiPropertyOptional({ example: 45, description: 'Override check-in cutoff (minutes) for this stop. Falls back to route-level checkinMinutesBefore if omitted.' }) @IsOptional() @IsInt() @Min(1) checkinMinutesBefore?: number;
  @ApiPropertyOptional({ example: 40, description: 'Travel time in minutes from the previous stop, used to estimate this stop\'s arrival time. Ignored for sequence 1 (origin, no predecessor). Falls back to distance-proportional interpolation if omitted.' }) @IsOptional() @IsInt() @Min(1) travelMinutesToStop?: number;
}

export class CreateRouteDto {
  @ApiProperty({ example: 'ADD-DJI', description: 'Unique route code' }) @IsString() code: string;
  @ApiProperty({ example: 'Addis Ababa – Djibouti' }) @IsString() name: string;
  @ApiPropertyOptional({ example: 'Main corridor via Dire Dawa' }) @IsOptional() @IsString() description?: string;
  @ApiProperty({ example: '2026-01-01T00:00:00Z', description: 'Date from which this route is effective' }) @IsDateString() effectiveFrom: string;
  @ApiPropertyOptional({ example: '2027-12-31T23:59:59Z' }) @IsOptional() @IsDateString() effectiveUntil?: string | null;
  @ApiPropertyOptional({ example: true, description: 'Whether the route is active (defaults to true)' }) @IsOptional() @IsBoolean() active?: boolean;
  @ApiPropertyOptional({ example: 30, description: 'Minutes before departure to close check-in for this route (defaults to 30 if omitted)' }) @IsOptional() @IsInt() @Min(1) checkinMinutesBefore?: number;
  @ApiProperty({
    type: [RouteStopInputDto],
    description: 'Ordered stops for this route. Sequence 1 = origin, last sequence = destination.',
    example: [
      { stationId: 'uuid-ADD', sequence: 1 },
      { stationId: 'uuid-ADM', sequence: 2, distanceKm: 99 },
      { stationId: 'uuid-AWS', sequence: 3, distanceKm: 120 },
      { stationId: 'uuid-DDW', sequence: 4, distanceKm: 180 },
      { stationId: 'uuid-AYS', sequence: 5, distanceKm: 95 },
      { stationId: 'uuid-DJI', sequence: 6, distanceKm: 60 },
    ],
  })
  @IsArray() @ValidateNested({ each: true }) @Type(() => RouteStopInputDto)
  stops: RouteStopInputDto[];
}

export class AddRouteStopDto {
  @ApiProperty({ example: 'station-uuid' }) @IsString() stationId: string;
  @ApiProperty({ example: 3 }) @IsInt() @Min(1) sequence: number;
  @ApiPropertyOptional({ example: 75.5, description: 'Cumulative distance in km from the route origin (not from the previous stop)' }) @IsOptional() @IsNumber() distanceKm?: number;
  @ApiPropertyOptional({ example: 45, description: 'Override check-in cutoff (minutes) for this stop. Falls back to route-level checkinMinutesBefore if omitted.' }) @IsOptional() @IsInt() @Min(1) checkinMinutesBefore?: number;
  @ApiPropertyOptional({ example: 40, description: 'Travel time in minutes from the previous stop, used to estimate this stop\'s arrival time. Falls back to distance-proportional interpolation if omitted.' }) @IsOptional() @IsInt() @Min(1) travelMinutesToStop?: number;
}

export class UpdateRouteDto {
  @ApiPropertyOptional({ example: 'Addis Ababa – Djibouti Express' }) @IsOptional() @IsString() name?: string;
  @ApiPropertyOptional() @IsOptional() @IsString() description?: string;
  @ApiPropertyOptional({ example: true }) @IsOptional() @IsBoolean() active?: boolean;
  @ApiPropertyOptional({ example: '2026-01-01T00:00:00Z', description: 'Date from which this route is effective' }) @IsOptional() @IsDateString() effectiveFrom?: string;
  @ApiPropertyOptional({ example: '2027-12-31T23:59:59Z', description: 'Send null to clear (open-ended route)' }) @IsOptional() @IsDateString() effectiveUntil?: string | null;
  @ApiPropertyOptional({ example: 30, description: 'Minutes before departure to close check-in for this route' }) @IsOptional() @IsInt() @Min(1) checkinMinutesBefore?: number;
  @ApiPropertyOptional({ type: [RouteStopInputDto] }) @IsOptional() @IsArray() @ValidateNested({ each: true }) @Type(() => RouteStopInputDto) stops?: RouteStopInputDto[];
}

export class RouteCoachTemplateItemDto {
  @ApiProperty({ example: 'coach-uuid', description: 'Coach UUID' }) @IsString() coachId: string;
  @ApiProperty({ example: 1, description: 'Position in the train consist (1 = first coach)' }) @IsInt() @Min(1) positionNumber: number;
}

export class SetRouteCoachTemplateDto {
  @ApiProperty({ type: [RouteCoachTemplateItemDto], description: 'Ordered list of coaches for this route. Replaces the existing template.' })
  @IsArray() @ValidateNested({ each: true }) @Type(() => RouteCoachTemplateItemDto)
  coaches: RouteCoachTemplateItemDto[];
}
