import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
  IsDate,
  IsIn,
  IsNumber,
  IsObject,
  IsOptional,
  IsString,
  Min,
  MaxLength,
  ValidateNested,
} from 'class-validator';

export const TIPOS_GESTION = ['VISITA', 'LLAMADA', 'WHATSAPP', 'EMAIL', 'SMS', 'OTRO'] as const;
export type TipoGestionValor = (typeof TIPOS_GESTION)[number];

export const RESULTADOS_GESTION = [
  'COBRADO_TOTAL',
  'COBRADO_PARCIAL',
  'PROMESA_PAGO',
  'NO_ATIENDE',
  'CLIENTE_AUSENTE',
  'DIRECCION_INCORRECTA',
  'CLIENTE_DISPUTA',
  'RECHAZO_PAGAR',
  'COMPROMISO_LLAMADA_POSTERIOR',
  'CLIENTE_FALLECIDO',
  'OTRO',
] as const;
export type ResultadoGestionValor = (typeof RESULTADOS_GESTION)[number];

export const TIPOS_EVIDENCIA = ['VERBAL', 'WHATSAPP', 'EMAIL', 'SMS', 'DOCUMENTO_FIRMADO'] as const;
export type TipoEvidenciaValor = (typeof TIPOS_EVIDENCIA)[number];

export const TIPOS_PAGADOR = ['CLIENTE', 'GARANTE', 'TERCERO'] as const;
export type TipoPagadorValor = (typeof TIPOS_PAGADOR)[number];

/**
 * Datos opcionales de la promesa formal. Sólo se procesa cuando
 *   resultado === 'PROMESA_PAGO' && fuente === 'erp-novasis'
 * En ese caso se crea un registro real en `promesas_pago` junto con
 * la gestión, todo dentro de una transacción.
 */
export class PromesaFormalDto {
  @ApiProperty({ type: String, format: 'date-time' })
  @Type(() => Date)
  @IsDate()
  fecha_prometida!: Date;

  @ApiProperty({ required: false })
  @IsOptional()
  @Type(() => Number)
  @IsNumber()
  @Min(0)
  monto_prometido?: number;

  @ApiProperty({ enum: TIPOS_EVIDENCIA, required: false })
  @IsOptional()
  @IsIn(TIPOS_EVIDENCIA as unknown as string[])
  tipo_evidencia?: TipoEvidenciaValor;

  @ApiProperty({ enum: TIPOS_PAGADOR, required: false })
  @IsOptional()
  @IsIn(TIPOS_PAGADOR as unknown as string[])
  pagador_tipo?: TipoPagadorValor;

  @ApiProperty({ required: false })
  @IsOptional()
  @IsString()
  @MaxLength(2000)
  notas?: string;
}

export class RegistrarGestionDto {
  @ApiProperty({ enum: TIPOS_GESTION })
  @IsIn(TIPOS_GESTION as unknown as string[])
  tipo_gestion!: TipoGestionValor;

  @ApiProperty({ enum: RESULTADOS_GESTION })
  @IsIn(RESULTADOS_GESTION as unknown as string[])
  resultado!: ResultadoGestionValor;

  @ApiProperty({ required: false })
  @IsOptional()
  @IsString()
  @MaxLength(2000)
  observacion?: string;

  @ApiProperty({ required: false })
  @IsOptional()
  @IsString()
  @MaxLength(500)
  proxima_accion?: string;

  @ApiProperty({ required: false })
  @IsOptional()
  @Type(() => Date)
  @IsDate()
  proxima_fecha?: Date;

  @ApiProperty({ type: PromesaFormalDto, required: false })
  @IsOptional()
  @IsObject()
  @ValidateNested()
  @Type(() => PromesaFormalDto)
  promesa?: PromesaFormalDto;
}
