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

export const TIPOS_DESVINCULACION = [
  'RENUNCIA',
  'DESPIDO_JUSTIFICADO',
  'DESPIDO_INJUSTIFICADO',
  'MUTUO_ACUERDO',
  'JUBILACION',
  'FALLECIMIENTO',
  'ABANDONO',
  'FIN_CONTRATO',
] as const;

export const DESVINCULACION_ESTADOS = ['CALCULADO', 'APROBADO', 'PAGADO', 'ANULADO'] as const;

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

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

  @ApiProperty({ description: 'Último día de trabajo (define fin de período)' })
  @IsDateString()
  fecha_ultimo_dia!: string;

  @ApiPropertyOptional({ description: 'Fecha de comunicación de la desvinculación (default: hoy)' })
  @IsOptional()
  @IsDateString()
  fecha_comunicacion?: string;

  @ApiPropertyOptional({
    description: 'Si la empresa NO cumplió el preaviso (por defecto SÍ en DESPIDO_INJUSTIFICADO)',
  })
  @IsOptional()
  preaviso_omitido?: string | boolean;

  @ApiPropertyOptional({ description: 'Salario pendiente del último período (días no liquidados aún)' })
  @IsOptional()
  @IsNumber()
  @Min(0)
  salario_pendiente_override?: number;

  @ApiPropertyOptional({ description: 'Días de vacaciones de períodos anteriores no gozados' })
  @IsOptional()
  @IsNumber()
  @Min(0)
  dias_vacaciones_no_gozadas?: number;

  @ApiPropertyOptional({ description: 'Aguinaldo proporcional manual (sobreescribe el cálculo automático)' })
  @IsOptional()
  @IsNumber()
  @Min(0)
  aguinaldo_proporcional_override?: number;
}

export class CrearDesvinculacionDto extends CalcularDesvinculacionDto {
  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  observaciones?: string;
}

export class UpdateDesvinculacionDto {
  @ApiPropertyOptional()
  @IsOptional()
  @IsNumber()
  @Min(0)
  salario_pendiente?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @IsNumber()
  @Min(0)
  dias_vacaciones_proporcional?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @IsNumber()
  @Min(0)
  monto_vacaciones_proporcional?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @IsNumber()
  @Min(0)
  dias_vacaciones_no_gozadas?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @IsNumber()
  @Min(0)
  monto_vacaciones_no_gozadas?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @IsNumber()
  @Min(0)
  aguinaldo_proporcional?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @IsInt()
  @Min(0)
  dias_preaviso?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @IsNumber()
  @Min(0)
  monto_preaviso?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @IsInt()
  @Min(0)
  anios_indemnizacion?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @IsNumber()
  @Min(0)
  monto_indemnizacion?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @IsNumber()
  @Min(0)
  otros_haberes?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @IsNumber()
  @Min(0)
  otros_descuentos?: number;

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

export class AccionDesvinculacionDto {
  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  comentario?: string;

  @ApiPropertyOptional({ description: 'Cuenta de tesorería desde la que se paga el finiquito (requerida al pagar si la empresa usa Tesorería)' })
  @IsOptional()
  @IsUUID()
  cuenta_tesoreria_id?: string;
}

export class QueryDesvinculacionesDto {
  @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: DESVINCULACION_ESTADOS })
  @IsOptional()
  @IsString()
  @IsIn(DESVINCULACION_ESTADOS as unknown as string[])
  estado?: string;

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

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