import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
  IsArray,
  IsDateString,
  IsNotEmpty,
  IsNumber,
  IsOptional,
  IsString,
  IsUUID,
  Length,
  Min,
  ValidateNested,
} from 'class-validator';
import { DocumentosAsociadosDto } from 'src/common/dto/documento-asociado.dto';

// Vínculo remisión↔factura a nivel ítem. Estos valores alimentan un UPDATE de
// factura_det, por eso deben validarse estrictamente (factura_det_id UUID, cantidad >= 0).
export class AplicacionRemisionDto {
  @ApiProperty()
  @IsUUID()
  factura_det_id: string;

  @ApiProperty({ example: 10 })
  @IsNumber()
  @Min(0)
  cantidad: number;
}

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

  @ApiProperty()
  @IsUUID()
  @IsNotEmpty()
  numeracion_id: string;

  @ApiProperty()
  @IsUUID()
  @IsNotEmpty()
  transportista_id: string;

  @ApiProperty()
  @IsUUID()
  @IsNotEmpty()
  chofer_id: string;

  @ApiProperty()
  @IsUUID()
  @IsNotEmpty()
  vehiculo_id: string;

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

  @ApiPropertyOptional({ description: 'Depósito del cual descontar stock (remisión sin factura). Default: principal de la sucursal.' })
  @IsUUID()
  @IsOptional()
  deposito_id?: string;

  @ApiProperty({ example: '2026-04-12T10:00:00' })
  @IsNotEmpty()
  @Length(1, 19)
  dfeemide: string;

  @ApiProperty({ example: '2026-04-12' })
  @IsDateString()
  fecha_inicio_traslado: string;

  @ApiProperty({ example: '2026-04-15' })
  @IsDateString()
  fecha_fin_traslado: string;

  @ApiPropertyOptional({ example: '2026-04-20', description: 'Solo cuando no hay doc asociado' })
  @IsDateString()
  @IsOptional()
  fecha_futura_emision?: string;

  @ApiProperty({ example: 1, description: 'Motivo SIFEN: 1=traslado por ventas, etc.' })
  @IsNumber()
  @IsNotEmpty()
  motivo_emision: number;

  @ApiPropertyOptional({ example: 'Descripción del otro motivo' })
  @IsString()
  @IsOptional()
  otro_motivo?: string;

  @ApiProperty({ example: 1, description: '1=emisor factura, 2=receptor factura' })
  @IsNumber()
  @IsNotEmpty()
  tipo_responsable: number;

  @ApiProperty({ example: 1, description: '1=terrestre, 2=fluvial, 3=aéreo, 4=multimodal' })
  @IsNumber()
  @IsNotEmpty()
  tipo_transporte: number;

  @ApiProperty({ example: 1, description: 'Modalidad transporte SIFEN' })
  @IsNumber()
  @IsNotEmpty()
  modalidad_transporte: number;

  @ApiPropertyOptional({ example: 'FOB' })
  @IsString()
  @IsOptional()
  condicion_negociacion?: string;

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

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

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

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

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

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

  @ApiPropertyOptional({ example: 100 })
  @IsNumber()
  @IsOptional()
  kilometros?: number;

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

  // Dirección salida
  @ApiProperty({ example: 'Av. Mcal. López 1234' })
  @IsString()
  @IsNotEmpty()
  direccion_salida: string;

  @ApiPropertyOptional({ example: 0 })
  @IsNumber()
  @IsOptional()
  nro_casa_salida?: number;

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

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

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

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

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

  // Dirección entrega
  @ApiProperty({ example: 'Calle San Martín 567' })
  @IsString()
  @IsNotEmpty()
  direccion_entrega: string;

  @ApiPropertyOptional({ example: 0 })
  @IsNumber()
  @IsOptional()
  nro_casa_entrega?: number;

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

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

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

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

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

  @ApiPropertyOptional()
  @IsString()
  @IsOptional()
  @Length(1, 5000)
  info_adicional?: string;

  // Documento asociado
  @ApiPropertyOptional({ type: DocumentosAsociadosDto })
  @ValidateNested()
  @Type(() => DocumentosAsociadosDto)
  @IsOptional()
  documento_asociado?: DocumentosAsociadosDto;
}

export class NotaRemisionDetDto {
  @ApiProperty()
  @IsUUID()
  @IsNotEmpty()
  producto_id: string;

  @ApiProperty({ example: 'Producto X' })
  @IsString()
  @IsNotEmpty()
  @Length(1, 120)
  descripcion: string;

  @ApiProperty({ example: 'UNI' })
  @IsString()
  @IsNotEmpty()
  @Length(1, 5)
  unidad_medida: string;

  @ApiProperty({ example: 10 })
  @IsNumber()
  @Min(0)
  cantidad: number;

  @ApiPropertyOptional({ example: 50000 })
  @IsNumber()
  @IsOptional()
  precio_unitario?: number;

  @ApiPropertyOptional({ description: 'IDs de facturas_det a vincular con cantidad', type: [AplicacionRemisionDto] })
  @IsArray()
  @IsOptional()
  @ValidateNested({ each: true })
  @Type(() => AplicacionRemisionDto)
  aplicaciones?: AplicacionRemisionDto[];
}

export class CreateNotaRemisionDto {
  @ApiProperty({ type: NotaRemisionCabDto })
  @ValidateNested()
  @Type(() => NotaRemisionCabDto)
  cabecera: NotaRemisionCabDto;

  @ApiProperty({ type: [NotaRemisionDetDto] })
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => NotaRemisionDetDto)
  items: NotaRemisionDetDto[];

  @ApiPropertyOptional({ description: 'IDs de facturas asociadas a nivel de cabecera' })
  @IsArray()
  @IsOptional()
  facturas_ids?: string[];
}
