import { ApiPropertyOptional } from '@nestjs/swagger';
import { Transform, Type } from 'class-transformer';
import {
  IsBoolean,
  IsDateString,
  IsEnum,
  IsInt,
  IsNotEmpty,
  IsOptional,
  IsString,
  IsUUID,
  ValidateIf,
  Max,
  Matches,
  Min,
} from 'class-validator';

export enum MarcacionEstadoQuery {
  PENDIENTE = 'PENDIENTE',
  PROCESADO = 'PROCESADO',
  DUPLICADO = 'DUPLICADO',
  ERROR = 'ERROR',
}

export enum MarcacionFuenteQuery {
  API = 'API',
  PLANILLA = 'PLANILLA',
}

export class QueryMarcacionesDto {
  @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(500)
  limit?: number = 50;

  @ApiPropertyOptional({ example: '2026-05-01' })
  @IsOptional()
  @IsDateString()
  fecha_desde?: string;

  @ApiPropertyOptional({ example: '2026-05-31' })
  @IsOptional()
  @IsDateString()
  fecha_hasta?: string;

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

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

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

  @ApiPropertyOptional({ enum: MarcacionEstadoQuery })
  @IsOptional()
  @IsEnum(MarcacionEstadoQuery)
  estado?: MarcacionEstadoQuery;

  @ApiPropertyOptional({ enum: MarcacionFuenteQuery })
  @IsOptional()
  @IsEnum(MarcacionFuenteQuery)
  fuente?: MarcacionFuenteQuery;
}

export class QueryMarcacionesLimpiasDto {
  @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(500)
  limit?: number = 50;

  @ApiPropertyOptional({ example: '2026-05-01' })
  @IsOptional()
  @IsDateString()
  fecha_desde?: string;

  @ApiPropertyOptional({ example: '2026-05-31' })
  @IsOptional()
  @IsDateString()
  fecha_hasta?: string;

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

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

export class QueryBatchesDto {
  @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(100)
  limit?: number = 20;

  @ApiPropertyOptional({ enum: MarcacionFuenteQuery })
  @IsOptional()
  @IsEnum(MarcacionFuenteQuery)
  fuente?: MarcacionFuenteQuery;
}

export class QueryLogCorreccionesDto {
  @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(500)
  limit?: number = 50;

  @ApiPropertyOptional({ example: '2026-05-01' })
  @IsOptional()
  @IsDateString()
  fecha_desde?: string;

  @ApiPropertyOptional({ example: '2026-05-31' })
  @IsOptional()
  @IsDateString()
  fecha_hasta?: string;

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

  @ApiPropertyOptional()
  @IsOptional()
  @IsUUID()
  batch_importacion_id?: string;
}

export class ImportarMarcacionesDto {
  @ApiPropertyOptional({ description: 'Reloj asociado a esta importación (opcional)' })
  @IsOptional()
  @IsUUID()
  reloj_id?: string;
}

export class SincronizarRelojDto {
  @ApiPropertyOptional({ example: '2026-05-01T00:00:00Z' })
  @IsOptional()
  @IsDateString()
  desde?: string;

  @ApiPropertyOptional({ example: '2026-05-31T23:59:59Z' })
  @IsOptional()
  @IsDateString()
  hasta?: string;
}

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

export class AjustarMarcacionLimpiaDto {
  @ApiPropertyOptional({ example: '08:05' })
  @IsOptional()
  @IsString()
  @Matches(HHMM, { message: 'hora_entrada debe ser HH:MM' })
  hora_entrada?: string;

  @ApiPropertyOptional({ example: '17:12' })
  @IsOptional()
  @IsString()
  @Matches(HHMM, { message: 'hora_salida debe ser HH:MM' })
  hora_salida?: string;

  @ApiPropertyOptional({
    description: 'ID de turno. null para limpiar',
    type: 'string',
    format: 'uuid',
    nullable: true,
  })
  @IsOptional()
  @Transform(({ value }) => (value === '' ? null : value))
  @ValidateIf((_, value) => value !== null && value !== undefined)
  @IsUUID()
  turno_id?: string | null;

  @ApiPropertyOptional({ description: 'Motivo obligatorio del ajuste manual' })
  @IsString()
  @IsNotEmpty()
  motivo!: string;
}
