import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { inm_ajuste_tipo, inm_operacion_estado, inm_titular_rol } from '@prisma/client';
import { Type } from 'class-transformer';
import {
  ArrayMaxSize,
  IsArray,
  IsBoolean,
  IsDateString,
  IsEnum,
  IsInt,
  IsNotEmpty,
  IsNumber,
  IsOptional,
  IsString,
  IsUUID,
  Max,
  MaxLength,
  Min,
  ValidateNested,
} from 'class-validator';
import { OpcionCotizacionDto } from '../../cotizaciones/dto/cotizacion.dto';

export class TitularDto {
  @ApiProperty() @IsUUID() cliente_id: string;
  @ApiPropertyOptional({ enum: inm_titular_rol }) @IsOptional() @IsEnum(inm_titular_rol) rol?: inm_titular_rol;
  @ApiPropertyOptional({ example: 50 })
  @IsOptional()
  @IsNumber({ maxDecimalPlaces: 2 })
  @Min(0)
  @Max(100, { message: 'El porcentaje de un titular no puede pasar del 100 %' })
  porcentaje?: number;
}

export class ReservarDto {
  @ApiPropertyOptional({ description: 'Opción de una cotización vigente (camino normal)' })
  @IsOptional()
  @IsUUID()
  cotizacion_opcion_id?: string;

  @ApiPropertyOptional({ description: 'Reserva directa, sin cotización previa' })
  @IsOptional()
  @IsUUID()
  unidad_id?: string;

  @ApiPropertyOptional({ type: OpcionCotizacionDto, description: 'Plan y descuento de la reserva directa' })
  @IsOptional()
  @ValidateNested()
  @Type(() => OpcionCotizacionDto)
  opcion?: OpcionCotizacionDto;

  @ApiProperty({ description: 'Titular principal: tiene que ser cliente del ERP (se le factura)' })
  @IsUUID()
  cliente_id: string;

  @ApiPropertyOptional({ type: [TitularDto], description: 'Cotitulares, cónyuge o garantes' })
  @IsOptional()
  @IsArray()
  @ArrayMaxSize(10)
  @ValidateNested({ each: true })
  @Type(() => TitularDto)
  titulares?: TitularDto[];

  @ApiPropertyOptional({
    enum: inm_ajuste_tipo,
    description: 'En guaraníes, por defecto IPC_BCP; en dólares, siempre NINGUNO',
  })
  @IsOptional()
  @IsEnum(inm_ajuste_tipo)
  ajuste?: inm_ajuste_tipo;

  @ApiPropertyOptional({ description: 'Versión de la unidad leída (bloqueo optimista)' })
  @IsOptional()
  @IsInt()
  version?: number;
  @ApiPropertyOptional() @IsOptional() @IsString() @MaxLength(2000) notas?: string;
}

export class ProrrogarReservaDto {
  @ApiProperty({ example: 7 }) @IsInt() @Min(1) @Max(90) dias: number;
  @ApiProperty({ example: 'El banco demora la aprobación del crédito' })
  @IsString()
  @IsNotEmpty()
  @MaxLength(255)
  motivo: string;
}

export class MotivoDto {
  @ApiProperty({ example: 'El comprador desiste' }) @IsString() @IsNotEmpty() @MaxLength(255) motivo: string;
}

export class LegajoDto {
  @ApiPropertyOptional({ description: 'Persona expuesta políticamente' }) @IsOptional() @IsBoolean() pep?: boolean;
  @ApiPropertyOptional({ example: 'Ahorros y venta de vehículo' })
  @IsOptional()
  @IsString()
  @MaxLength(255)
  origen_fondos?: string;
  @ApiPropertyOptional() @IsOptional() @IsString() @MaxLength(2000) observaciones?: string;
}

export class FirmarBoletoDto {
  @ApiPropertyOptional({ example: '2026-11-15', description: 'Por defecto, hoy. Es la fecha base del cronograma.' })
  @IsOptional()
  @IsDateString()
  fecha_boleto?: string;
}

export class ActualizarCuotaDto {
  @ApiProperty({ example: '2028-07-31', description: 'Vencimiento (ej. cuando se fija la fecha de posesión)' })
  @IsDateString()
  fecha_vencimiento: string;
}

export class FiltrosOperacionesDto {
  @IsOptional() @IsUUID() proyecto_id?: string;
  @IsOptional() @IsEnum(inm_operacion_estado) estado?: inm_operacion_estado;
  @IsOptional() @IsString() q?: string;
}
