import { ApiProperty, ApiPropertyOptional, PartialType } from '@nestjs/swagger';
import { Transform, Type } from 'class-transformer';
import {
  ArrayMinSize,
  IsArray,
  IsBoolean,
  IsEnum,
  IsInt,
  IsOptional,
  IsString,
  IsUUID,
  Length,
  Matches,
  Max,
  Min,
  ValidateNested,
} from 'class-validator';

export enum TurnoTipo {
  SIMPLE = 'SIMPLE',
  CORTADO = 'CORTADO',
}

export enum TurnoAsignacionTipo {
  PERPETUA = 'PERPETUA',
  OCASIONAL = 'OCASIONAL',
}

const HHMM = /^([01]\d|2[0-3]):[0-5]\d(:[0-5]\d)?$/;

export class TurnoBloqueDto {
  @ApiProperty({ minimum: 1, example: 1 })
  @Type(() => Number)
  @IsInt()
  @Min(1)
  @Max(10)
  orden!: number;

  @ApiProperty({ example: '08:00', description: 'Hora de entrada del bloque (HH:MM)' })
  @IsString()
  @Matches(HHMM, { message: 'hora_entrada debe ser HH:MM' })
  hora_entrada!: string;

  @ApiProperty({ example: '12:00', description: 'Hora de salida del bloque (HH:MM)' })
  @IsString()
  @Matches(HHMM, { message: 'hora_salida debe ser HH:MM' })
  hora_salida!: string;
}

export class CreateTurnoDto {
  @ApiProperty({ example: 'Turno Mañana' })
  @IsString()
  @Length(1, 100)
  nombre!: string;

  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  descripcion?: string;

  @ApiProperty({ enum: TurnoTipo, example: TurnoTipo.SIMPLE })
  @IsEnum(TurnoTipo)
  tipo!: TurnoTipo;

  @ApiProperty({ default: false })
  @IsOptional()
  @IsBoolean()
  lunes?: boolean = false;

  @ApiProperty({ default: false })
  @IsOptional()
  @IsBoolean()
  martes?: boolean = false;

  @ApiProperty({ default: false })
  @IsOptional()
  @IsBoolean()
  miercoles?: boolean = false;

  @ApiProperty({ default: false })
  @IsOptional()
  @IsBoolean()
  jueves?: boolean = false;

  @ApiProperty({ default: false })
  @IsOptional()
  @IsBoolean()
  viernes?: boolean = false;

  @ApiProperty({ default: false })
  @IsOptional()
  @IsBoolean()
  sabado?: boolean = false;

  @ApiProperty({ default: false })
  @IsOptional()
  @IsBoolean()
  domingo?: boolean = false;

  @ApiProperty({ default: true })
  @IsOptional()
  @IsBoolean()
  activo?: boolean = true;

  @ApiProperty({ type: [TurnoBloqueDto], description: 'SIMPLE → 1 bloque; CORTADO → 2+ bloques no solapados' })
  @IsArray()
  @ArrayMinSize(1)
  @ValidateNested({ each: true })
  @Type(() => TurnoBloqueDto)
  bloques!: TurnoBloqueDto[];
}

export class UpdateTurnoDto extends PartialType(CreateTurnoDto) {}

export class QueryTurnosDto {
  @ApiPropertyOptional({ default: 1 })
  @IsOptional()
  @Transform(({ value }) => parseInt(String(value), 10) || 1)
  @IsInt()
  @Min(1)
  page?: number = 1;

  @ApiPropertyOptional({ default: 50 })
  @IsOptional()
  @Transform(({ value }) => parseInt(String(value), 10) || 50)
  @IsInt()
  @Min(1)
  @Max(200)
  limit?: number = 50;

  @ApiPropertyOptional({ enum: TurnoTipo })
  @IsOptional()
  @IsEnum(TurnoTipo)
  tipo?: TurnoTipo;

  @ApiPropertyOptional()
  @IsOptional()
  @Transform(({ value }) =>
    value === 'true' || value === true ? true : value === 'false' || value === false ? false : undefined,
  )
  @IsBoolean()
  activo?: boolean;

  @ApiPropertyOptional({ example: 'mañana' })
  @IsOptional()
  @IsString()
  q?: string;
}

export class AsignarTurnoDto {
  @ApiProperty()
  @IsUUID()
  turno_id!: string;

  @ApiProperty({ enum: TurnoAsignacionTipo, example: TurnoAsignacionTipo.PERPETUA })
  @IsEnum(TurnoAsignacionTipo)
  tipo_asignacion!: TurnoAsignacionTipo;

  @ApiPropertyOptional({ description: 'Obligatorio para OCASIONAL', example: '2026-05-20' })
  @IsOptional()
  @IsString()
  @Matches(/^\d{4}-\d{2}-\d{2}$/, { message: 'fecha_inicio debe ser YYYY-MM-DD' })
  fecha_inicio?: string;

  @ApiPropertyOptional({ description: 'Obligatorio para OCASIONAL', example: '2026-05-21' })
  @IsOptional()
  @IsString()
  @Matches(/^\d{4}-\d{2}-\d{2}$/, { message: 'fecha_fin debe ser YYYY-MM-DD' })
  fecha_fin?: string;

  @ApiPropertyOptional({ default: 100, description: 'Menor número = mayor precedencia' })
  @IsOptional()
  @Type(() => Number)
  @IsInt()
  @Min(0)
  @Max(10000)
  prioridad?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  observacion?: string;
}

export class QueryAsignacionesDto {
  @ApiPropertyOptional({ enum: TurnoAsignacionTipo })
  @IsOptional()
  @IsEnum(TurnoAsignacionTipo)
  tipo_asignacion?: TurnoAsignacionTipo;

  @ApiPropertyOptional({ example: '2026-05-20' })
  @IsOptional()
  @IsString()
  @Matches(/^\d{4}-\d{2}-\d{2}$/, { message: 'fecha debe ser YYYY-MM-DD' })
  fecha?: string;
}
