import {
  IsString,
  IsNotEmpty,
  IsEnum,
  IsOptional,
  IsNumber,
  IsBoolean,
  IsUUID,
  Length,
  Matches,
  Min,
  Max,
} from 'class-validator';
import { TipoCfdiCartaPorte } from '../entities';

/**
 * DTO para crear una nueva Carta Porte
 * Cumple con requerimientos SAT CFDI 3.1
 */
export class CreateCartaPorteDto {
  /**
   * ID del viaje asociado
   */
  @IsUUID()
  @IsNotEmpty({ message: 'viajeId es requerido' })
  viajeId!: string;

  /**
   * Tipo de CFDI: INGRESO (servicio cobrado) o TRASLADO (propio)
   */
  @IsEnum(TipoCfdiCartaPorte, { message: 'tipoCfdi debe ser INGRESO o TRASLADO' })
  @IsNotEmpty({ message: 'tipoCfdi es requerido' })
  tipoCfdi!: TipoCfdiCartaPorte;

  /**
   * Version del complemento Carta Porte (default 3.1)
   */
  @IsOptional()
  @IsString()
  versionCartaPorte?: string;

  /**
   * Serie del CFDI (opcional)
   */
  @IsOptional()
  @IsString()
  @Length(1, 25, { message: 'serie debe tener entre 1 y 25 caracteres' })
  serie?: string;

  // ========== DATOS DEL EMISOR ==========

  /**
   * RFC del emisor (12-13 caracteres)
   */
  @IsString()
  @IsNotEmpty({ message: 'emisorRfc es requerido' })
  @Matches(/^[A-Z&Ñ]{3,4}[0-9]{6}[A-Z0-9]{3}$/, {
    message: 'emisorRfc debe ser un RFC valido',
  })
  emisorRfc!: string;

  /**
   * Razon social o nombre del emisor
   */
  @IsString()
  @IsNotEmpty({ message: 'emisorNombre es requerido' })
  @Length(1, 300)
  emisorNombre!: string;

  /**
   * Regimen fiscal del emisor (catalogo SAT c_RegimenFiscal)
   */
  @IsOptional()
  @IsString()
  @Length(3, 3, { message: 'emisorRegimenFiscal debe ser codigo de 3 digitos' })
  emisorRegimenFiscal?: string;

  // ========== DATOS DEL RECEPTOR ==========

  /**
   * RFC del receptor
   */
  @IsString()
  @IsNotEmpty({ message: 'receptorRfc es requerido' })
  @Matches(/^([A-Z&Ñ]{3,4}[0-9]{6}[A-Z0-9]{3}|XAXX010101000|XEXX010101000)$/, {
    message: 'receptorRfc debe ser un RFC valido o generico (XAXX/XEXX)',
  })
  receptorRfc!: string;

  /**
   * Nombre o razon social del receptor
   */
  @IsString()
  @IsNotEmpty({ message: 'receptorNombre es requerido' })
  @Length(1, 300)
  receptorNombre!: string;

  /**
   * Uso del CFDI (catalogo SAT c_UsoCFDI)
   */
  @IsOptional()
  @IsString()
  @Length(3, 4)
  receptorUsoCfdi?: string;

  /**
   * Codigo postal del domicilio fiscal del receptor
   */
  @IsOptional()
  @IsString()
  @Length(5, 5, { message: 'receptorDomicilioFiscalCp debe ser de 5 digitos' })
  receptorDomicilioFiscalCp?: string;

  // ========== TOTALES (requeridos para CFDI INGRESO) ==========

  /**
   * Subtotal del CFDI (sin impuestos)
   */
  @IsOptional()
  @IsNumber({}, { message: 'subtotal debe ser un numero' })
  @Min(0)
  subtotal?: number;

  /**
   * Total del CFDI (con impuestos)
   */
  @IsOptional()
  @IsNumber({}, { message: 'total debe ser un numero' })
  @Min(0)
  total?: number;

  /**
   * Moneda (default MXN)
   */
  @IsOptional()
  @IsString()
  @Length(3, 3)
  moneda?: string;

  // ========== TRANSPORTE INTERNACIONAL ==========

  /**
   * Indica si es transporte internacional
   */
  @IsOptional()
  @IsBoolean()
  transporteInternacional?: boolean;

  /**
   * Entrada o Salida de mercancia (Entrada/Salida)
   */
  @IsOptional()
  @IsString()
  @IsEnum(['Entrada', 'Salida'], { message: 'entradaSalidaMerc debe ser Entrada o Salida' })
  entradaSalidaMerc?: string;

  /**
   * Pais de origen o destino (ISO 3166-1 alpha-3)
   */
  @IsOptional()
  @IsString()
  @Length(3, 3)
  paisOrigenDestino?: string;

  // ========== DATOS AUTOTRANSPORTE FEDERAL ==========

  /**
   * Tipo de permiso SCT (catalogo c_TipoPermiso)
   */
  @IsOptional()
  @IsString()
  permisoSct?: string;

  /**
   * Numero de permiso SCT
   */
  @IsOptional()
  @IsString()
  @Length(1, 50)
  numPermisoSct?: string;

  /**
   * Configuracion vehicular (catalogo c_ConfigAutotransporte)
   */
  @IsOptional()
  @IsString()
  configVehicular?: string;

  /**
   * Peso bruto total en KG
   */
  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(100000)
  pesoBrutoTotal?: number;

  /**
   * Unidad de peso (catalogo c_ClaveUnidadPeso, default KGM)
   */
  @IsOptional()
  @IsString()
  @Length(2, 3)
  unidadPeso?: string;

  /**
   * Numero total de mercancias transportadas
   */
  @IsOptional()
  @IsNumber()
  @Min(1)
  numTotalMercancias?: number;

  // ========== SEGUROS ==========

  /**
   * Nombre de la aseguradora de responsabilidad civil
   */
  @IsOptional()
  @IsString()
  @Length(1, 100)
  aseguraRespCivil?: string;

  /**
   * Numero de poliza de responsabilidad civil
   */
  @IsOptional()
  @IsString()
  @Length(1, 50)
  polizaRespCivil?: string;

  /**
   * Nombre de la aseguradora de medio ambiente
   */
  @IsOptional()
  @IsString()
  @Length(1, 100)
  aseguraMedAmbiente?: string;

  /**
   * Numero de poliza de medio ambiente
   */
  @IsOptional()
  @IsString()
  @Length(1, 50)
  polizaMedAmbiente?: string;

  /**
   * Nombre de la aseguradora de carga
   */
  @IsOptional()
  @IsString()
  @Length(1, 100)
  aseguraCarga?: string;

  /**
   * Numero de poliza de carga
   */
  @IsOptional()
  @IsString()
  @Length(1, 50)
  polizaCarga?: string;

  /**
   * Prima del seguro de carga
   */
  @IsOptional()
  @IsNumber()
  @Min(0)
  primaSeguro?: number;
}
