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

export const NOVEDAD_TIPOS = [
  'AUSENCIA',
  'TARDANZA',
  'SALIDA_ANTICIPADA',
  'AUSENCIA_JORNADA',
  'AUSENCIA_BLOQUE',
  'AUSENCIA_JUSTIFICADA',
  'TARDANZA_JUSTIFICADA',
] as const;

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

export class CreateNovedadDto {
  @ApiProperty()
  @IsUUID()
  empleado_id!: string;

  @ApiProperty()
  @IsDateString()
  fecha!: string;

  @ApiProperty({ enum: NOVEDAD_TIPOS })
  @IsString()
  @IsIn(NOVEDAD_TIPOS as unknown as string[])
  tipo_novedad!: (typeof NOVEDAD_TIPOS)[number];

  @ApiPropertyOptional({ description: 'HH:MM o HH:MM:SS' })
  @IsOptional()
  @IsString()
  @Matches(HHMM, { message: 'hora_entrada_real debe ser HH:MM' })
  hora_entrada_real?: string;

  @ApiPropertyOptional({ description: 'HH:MM o HH:MM:SS' })
  @IsOptional()
  @IsString()
  @Matches(HHMM, { message: 'hora_entrada_esperada debe ser HH:MM' })
  hora_entrada_esperada?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @IsInt()
  @Min(0)
  @Max(720)
  minutos_tardanza?: number;

  @ApiPropertyOptional({ default: false })
  @IsOptional()
  @IsBoolean()
  justificado?: boolean;

  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  @Length(0, 50)
  tipo_justificacion?: string;

  @ApiPropertyOptional({ default: true })
  @IsOptional()
  @IsBoolean()
  impacta_liquidacion?: boolean;

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

export class UpdateNovedadDto extends PartialType(CreateNovedadDto) {}

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

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

  @ApiPropertyOptional({ enum: NOVEDAD_TIPOS })
  @IsOptional()
  @IsString()
  @IsIn(NOVEDAD_TIPOS as unknown as string[])
  tipo_novedad?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @IsUUID()
  empleado_id?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @IsDateString()
  fecha_desde?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @IsDateString()
  fecha_hasta?: string;

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

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

  @ApiPropertyOptional({ enum: ['BORRADOR', 'CONFIRMADA', 'ANULADA'] })
  @IsOptional()
  @IsString()
  @IsIn(['BORRADOR', 'CONFIRMADA', 'ANULADA'])
  estado?: 'BORRADOR' | 'CONFIRMADA' | 'ANULADA';

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