import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
  ArrayMinSize,
  IsArray,
  IsBoolean,
  IsDateString,
  IsEnum,
  IsIn,
  IsNumber,
  IsOptional,
  IsString,
  IsUUID,
  Min,
} from 'class-validator';
import { CobResultadoGestion, CobTipoGestion } from '@prisma/client';

const TIPOS_EVIDENCIA = ['VERBAL', 'WHATSAPP', 'EMAIL', 'DOCUMENTO_FIRMADO'] as const;
const PAGADOR_TIPOS = ['CLIENTE', 'GARANTE', 'TERCERO'] as const;

export class CreateGestionDto {
  @ApiProperty()
  @IsUUID()
  cliente_id: string;

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

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

  @ApiPropertyOptional({ description: 'Fecha/hora de la gestión (ISO). Default: now()' })
  @IsOptional()
  @IsDateString()
  fecha?: string;

  @ApiProperty({ enum: CobTipoGestion })
  @IsEnum(CobTipoGestion)
  tipo_gestion: CobTipoGestion;

  @ApiProperty({ enum: CobResultadoGestion })
  @IsEnum(CobResultadoGestion)
  resultado: CobResultadoGestion;

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

  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  proxima_accion?: string;

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

  @ApiPropertyOptional()
  @IsOptional()
  @IsNumber()
  geo_lat?: number;

  @ApiPropertyOptional()
  @IsOptional()
  @IsNumber()
  geo_lng?: number;

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

  @ApiPropertyOptional({ description: 'Lista de adjuntos (urls o metadata). Json libre.' })
  @IsOptional()
  adjuntos?: any;

  // Si resultado=PROMESA_PAGO, datos para crear la promesa
  @ApiPropertyOptional({ description: 'Solo si resultado=PROMESA_PAGO' })
  @IsOptional()
  @IsDateString()
  promesa_fecha?: string;

  @ApiPropertyOptional({ description: 'Solo si resultado=PROMESA_PAGO' })
  @IsOptional()
  @IsNumber()
  @Min(0)
  promesa_monto?: number;

  // ── Promesa enriquecida (Opción A unificada) ────────────────────────────────
  @ApiPropertyOptional({
    description: 'Cuotas a comprometer; si se envía, se crea una promesa por cuota con prorrateo del monto.',
    type: [String],
  })
  @IsOptional()
  @IsArray()
  @ArrayMinSize(1)
  @IsUUID('all', { each: true })
  promesa_cuota_ids?: string[];

  @ApiPropertyOptional({ enum: TIPOS_EVIDENCIA })
  @IsOptional()
  @IsIn(TIPOS_EVIDENCIA as unknown as string[])
  promesa_tipo_evidencia?: (typeof TIPOS_EVIDENCIA)[number];

  @ApiPropertyOptional({ enum: PAGADOR_TIPOS })
  @IsOptional()
  @IsIn(PAGADOR_TIPOS as unknown as string[])
  promesa_pagador_tipo?: (typeof PAGADOR_TIPOS)[number];

  @ApiPropertyOptional({ description: 'Requerido si promesa_pagador_tipo != CLIENTE' })
  @IsOptional()
  @IsUUID()
  promesa_pagador_cliente_id?: string;

  @ApiPropertyOptional({ description: 'Notas específicas del acuerdo de pago (no se piso con la observación de la gestión).' })
  @IsOptional()
  @IsString()
  promesa_notas?: string;
}

export class UpdateGestionDto {
  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  observacion?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  proxima_accion?: string;

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

  @ApiPropertyOptional({ enum: CobResultadoGestion })
  @IsOptional()
  @IsEnum(CobResultadoGestion)
  resultado?: CobResultadoGestion;

  @ApiPropertyOptional({ enum: CobTipoGestion })
  @IsOptional()
  @IsEnum(CobTipoGestion)
  tipo_gestion?: CobTipoGestion;
}

export class AnularGestionDto {
  @ApiProperty()
  @IsString()
  motivo: string;
}

export class QueryGestionesDto {
  @ApiPropertyOptional()
  @IsOptional()
  @IsUUID()
  clienteId?: string;

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

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

  @ApiPropertyOptional()
  @IsOptional()
  @IsEnum(CobResultadoGestion)
  resultado?: CobResultadoGestion;

  @ApiPropertyOptional()
  @IsOptional()
  @IsEnum(CobTipoGestion)
  tipo_gestion?: CobTipoGestion;

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

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

  @ApiPropertyOptional({ description: 'Incluir gestiones anuladas', default: false })
  @IsOptional()
  @IsBoolean()
  incluir_anuladas?: boolean;
}
