/**
 * Payload de facturación — docs/spec-crm-360.md §7.1.
 *
 * Es el contrato entre el CRM y el ERP: todo lo que FacturasService o
 * PedidosService necesitan para emitir, y nada más. El CRM **nunca** arma XML
 * SIFEN, ni toca stock, ni asienta en contabilidad.
 *
 * Existe como tipo propio y no como el DTO de facturas a propósito: el preview
 * del wizard tiene que poder mostrarlo sin que exista ningún documento todavía,
 * y la misma estructura sirve para la factura única y para cada ciclo del
 * contrato recurrente (F3).
 */

export type TipoCondicion = 'contado' | 'credito';
export type ModalidadCredito = 'plazo' | 'cuotas';

export interface CuotaPayload {
  numero: number;
  vencimiento: string;
  monto: number;
}

export interface ReceptorPayload {
  cliente_id: string;
  razon_social: string;
  ruc: string | null;
  dv: string | null;
  /** Para consumidor final sin RUC. */
  documento: string | null;
  email: string | null;
  direccion: string | null;
  /** SIFEN iNatRec: 1 contribuyente, 2 no contribuyente. */
  naturaleza: 1 | 2;
  /** SIFEN iTiOpe: 1 B2B, 2 B2C, 3 B2G, 4 B2F. */
  tipo_operacion: 1 | 2 | 3 | 4;
}

export interface ItemPayload {
  producto_id: string | null;
  descripcion: string;
  cantidad: number;
  precio_unitario: number;
  descuento_pct: number;
  iva_tasa: number;
  /** Neto de descuento, con IVA incluido. */
  subtotal: number;
  iva_monto: number;
}

export interface PayloadFacturacion {
  empresa_id: string;
  sucursal_id: string | null;
  /** SIFEN iTipTra: 1 mercadería, 2 servicio, 3 mixto. Se deriva de los ítems. */
  tipo_transaccion: 1 | 2 | 3;
  moneda_id: string | null;
  receptor: ReceptorPayload;
  condicion: {
    tipo: TipoCondicion;
    credito?: { modalidad: ModalidadCredito; plazo_dias?: number; cuotas?: CuotaPayload[] };
  };
  items: ItemPayload[];
  totales: {
    total: number;
    total_iva: number;
    base_gravada_10: number;
    base_gravada_5: number;
    exento: number;
  };
  info_adicional: string | null;
  trazabilidad: {
    oportunidad_id: string;
    oportunidad_numero: string;
    presupuesto_id: string | null;
    vendedor_id: string | null;
  };
}

/** Totales a partir de los ítems ya resueltos. */
export function totalesDePayload(items: ItemPayload[]): PayloadFacturacion['totales'] {
  const acum = (f: (i: ItemPayload) => number) => Number(items.reduce((a, i) => a + f(i), 0).toFixed(4));
  return {
    total: acum((i) => i.subtotal),
    total_iva: acum((i) => i.iva_monto),
    base_gravada_10: acum((i) => (i.iva_tasa === 10 ? i.subtotal - i.iva_monto : 0)),
    base_gravada_5: acum((i) => (i.iva_tasa === 5 ? i.subtotal - i.iva_monto : 0)),
    exento: acum((i) => (i.iva_tasa === 0 ? i.subtotal : 0)),
  };
}

/**
 * SIFEN iTipTra. Un ítem sin producto se cuenta como servicio: en la práctica
 * son fletes, instalaciones y honorarios cargados a mano.
 */
export function tipoTransaccionDeItems(
  items: Array<{ es_servicio: boolean }>,
): PayloadFacturacion['tipo_transaccion'] {
  const hayServicio = items.some((i) => i.es_servicio);
  const hayMercaderia = items.some((i) => !i.es_servicio);
  if (hayServicio && hayMercaderia) return 3;
  return hayServicio ? 2 : 1;
}
