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 ANTICIPO_ESTADOS = ['PENDIENTE', 'APROBADO', 'DESCONTADO', 'ANULADO'] as const;
export type AnticipoEstado = (typeof ANTICIPO_ESTADOS)[number];

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

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

  @ApiProperty()
  @IsNumber()
  @Min(1)
  monto!: number;

  @ApiProperty()
  @IsInt()
  @Min(2000)
  @Max(2100)
  periodo_anio!: number;

  @ApiProperty()
  @IsInt()
  @Min(1)
  @Max(12)
  periodo_mes!: number;

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

export class UpdateAnticipoDto {
  @ApiPropertyOptional()
  @IsOptional()
  @IsDateString()
  fecha_solicitud?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @IsNumber()
  @Min(1)
  monto?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @IsInt()
  @Min(2000)
  @Max(2100)
  periodo_anio?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @IsInt()
  @Min(1)
  @Max(12)
  periodo_mes?: number;

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

export class AccionAnticipoDto {
  @ApiPropertyOptional({ description: 'Comentario opcional al aprobar/anular' })
  @IsOptional()
  @IsString()
  comentario?: string;

  @ApiPropertyOptional({
    description:
      'Cuenta de tesorería desde la que se desembolsa el anticipo. Requerida al aprobar si la ' +
      'empresa usa Tesorería: genera el egreso y el asiento DEBE Anticipo al Personal / HABER Banco.',
  })
  @IsOptional()
  @IsUUID()
  cuenta_tesoreria_id?: string;

  @ApiPropertyOptional({
    description: 'Fecha real del desembolso (YYYY-MM-DD). Si no se envía se usa la de hoy.',
  })
  @IsOptional()
  @IsDateString()
  fecha_pago?: string;
}

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

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

  @ApiPropertyOptional()
  @IsOptional()
  @Transform(({ value }) => (value ? parseInt(String(value), 10) : undefined))
  @IsInt()
  periodo_anio?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @Transform(({ value }) => (value ? parseInt(String(value), 10) : undefined))
  @IsInt()
  periodo_mes?: number;
}
