// ─────────────────────────────────────────────────────
// GUT-261 — Piezas para las listas de materiales (Juanjo, compras/almacén):
//   MatTotalesPanel  "Demanda total por artículo": suma de cantidades por
//                    artículo + medidas + unidad de las líneas filtradas, con
//                    cuánto falta por pedir, cuánto está pedido y cuánto hay
//                    ya en fábrica, y cuántos proyectos lo piden.
//                    Lo usan Programación › Materiales y Necesidades de compra.
//   MatClienteCell   celda "Proyecto" de Programación › Materiales: nº y cliente
//                    entero; al pulsar, popover con los datos del cliente y
//                    enlaces a la ficha del proyecto / expediente / lead.
// Cálculo en el servidor: src/services/materialesTotales.js.
// ─────────────────────────────────────────────────────

const matNum = (n) => (n == null ? '' : Number(n).toLocaleString('es-ES', { maximumFractionDigits: 3 }));

// `url`: endpoint de totales con los mismos filtros que la lista. `version` cambia
// cuando la lista se recarga, para que el resumen no se quede atrás.
const MatTotalesPanel = ({ url, version, onToast, onElegir, elegidos = [] }) => {
  const [rows, setRows] = React.useState(null);
  React.useEffect(() => {
    let vivo = true;
    API.get(url).then((r) => { if (vivo) setRows(r); }).catch((e) => { if (vivo) { setRows([]); onToast && onToast(e.message, true); } });
    return () => { vivo = false; };
  }, [url, version]);
  const sel = new Set(elegidos);
  const th = { textAlign: 'right', width: 86 };
  // GUT-272: Necesidades de compra manda además el stock del artículo y lo que hay que pedir.
  const conStock = (rows || []).some((t) => t.a_pedir !== undefined);
  const nCols = conStock ? 11 : 9;
  return (
    <div style={{ border: '1px solid var(--line)', borderRadius: 8, background: 'var(--surface)', marginBottom: 14 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '8px 12px', borderBottom: '1px solid var(--line)' }}>
        <strong>Demanda total por artículo</strong>
        <span className="muted" style={{ fontSize: 12 }}>
          {rows ? `${rows.length} artículo${rows.length === 1 ? '' : 's'} · suma de las líneas que ves abajo, por artículo, medidas y unidad` : 'Calculando…'}
        </span>
        <HelpTip label="demanda total" text={`Suma las cantidades de las líneas filtradas. Un mismo artículo con otra medida o unidad sale en otra fila. «Por pedir» = aún sin pedir; «Pedido» = pedido y sin llegar; «En fábrica» = recibido, de stock, en proceso o preparado. Las líneas sin cantidad se cuentan aparte.${conStock ? ' «Stock» = lo que hay en Almacén de ese artículo del catálogo. «A pedir» = demanda por pedir − stock (nunca menos de 0): el stock se reparte primero a lo más urgente. Sin artículo del catálogo no hay stock y se pide todo.' : ''}`} />
      </div>
      <div className="tbl-scroll" style={{ maxHeight: 320, overflow: 'auto' }}>
        <table className="tbl tbl-compact">
          <thead><tr>
            <th style={{ width: 110 }}>Referencia</th><th>Artículo</th><th style={{ width: 110 }}>Medidas</th>
            <th style={th}>Total</th><th style={th}>Por pedir</th><th style={th}>Pedido</th><th style={th}>En fábrica</th>
            {conStock && <><th style={th}>Stock</th><th style={th}>A pedir</th></>}
            <th style={{ width: 70, textAlign: 'right' }}>Líneas</th><th style={{ width: 90, textAlign: 'right' }}>Proyectos</th>
          </tr></thead>
          <tbody>
            {rows && rows.length === 0 && <tr><td colSpan={nCols} className="muted" style={{ textAlign: 'center' }}>Sin líneas con estos filtros</td></tr>}
            {(rows || []).map((t) => {
              const u = t.unidad ? ` ${t.unidad}` : '';
              const cant = (v, strong) => (v ? <span className={strong ? 'strong' : ''}>{matNum(v)}{u}</span> : <span className="muted">—</span>);
              return (
                <tr key={t.key} style={sel.has(t.articulo_key) ? { background: 'var(--surface-2)' } : undefined}>
                  <td className="mono">{t.referencia || <span className="muted">—</span>}</td>
                  <td>
                    {onElegir
                      ? <a style={{ cursor: 'pointer' }} title="Ver solo las líneas de este artículo" onClick={() => onElegir(t.articulo_key)}>{t.descripcion}</a>
                      : t.descripcion}
                  </td>
                  <td>{t.medidas || <span className="muted">—</span>}</td>
                  <td style={{ textAlign: 'right' }}>{t.total ? cant(t.total, true) : <span className="muted">—</span>}</td>
                  <td style={{ textAlign: 'right', color: t.por_pedir ? 'var(--err)' : undefined }}>{cant(t.por_pedir)}</td>
                  <td style={{ textAlign: 'right' }}>{cant(t.pedido)}</td>
                  <td style={{ textAlign: 'right' }}>{cant(t.en_fabrica)}</td>
                  {conStock && <>
                    <td style={{ textAlign: 'right' }} title={t.stock == null ? 'Sin artículo del catálogo: no hay stock que mirar' : ''}>
                      {t.stock == null ? <span className="muted">—</span> : <span style={t.stock < 0 ? { color: 'var(--err)' } : undefined}>{matNum(t.stock)}{u}</span>}
                    </td>
                    <td style={{ textAlign: 'right', color: t.a_pedir ? 'var(--err)' : 'var(--ok)', fontWeight: 600 }}>
                      {t.a_pedir ? `${matNum(t.a_pedir)}${u}` : (t.por_pedir ? 'Cubierto' : '—')}
                    </td>
                  </>}
                  <td style={{ textAlign: 'right' }} title={t.sin_cantidad ? `${t.sin_cantidad} línea${t.sin_cantidad === 1 ? '' : 's'} sin cantidad` : ''}>
                    {t.lineas}{t.sin_cantidad ? <span className="muted" style={{ fontSize: 11 }}> ({t.sin_cantidad} s/c)</span> : null}
                  </td>
                  <td style={{ textAlign: 'right' }} title={t.proyectos_lista.join(', ')}>{t.proyectos}</td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
};

// Popover flotante (en el body, como los desplegables de Programación) que se cierra
// al pulsar fuera, con Escape o al hacer scroll fuera de él.
const MatPopover = ({ anchor, onClose, children, width = 340 }) => {
  const ref = React.useRef(null);
  const r = anchor.getBoundingClientRect();
  const left = Math.max(8, Math.min(r.left, window.innerWidth - width - 8));
  const abajo = window.innerHeight - r.bottom - 8;
  const pos = abajo < 260 && r.top > abajo
    ? { left, bottom: window.innerHeight - r.top + 2, width, maxHeight: r.top - 8 }
    : { left, top: r.bottom + 2, width, maxHeight: abajo };
  React.useEffect(() => {
    const fuera = (e) => { if (!ref.current?.contains(e.target) && !anchor.contains(e.target) && !e.target.closest?.('.pg-picker-dd')) onClose(); };
    const esc = (e) => { if (e.key === 'Escape') onClose(); };
    const scroll = (e) => { if (!ref.current?.contains(e.target) && !e.target.closest?.('.pg-picker-dd')) onClose(); };
    document.addEventListener('mousedown', fuera); document.addEventListener('keydown', esc); window.addEventListener('scroll', scroll, true);
    return () => { document.removeEventListener('mousedown', fuera); document.removeEventListener('keydown', esc); window.removeEventListener('scroll', scroll, true); };
  }, [anchor, onClose]);
  return ReactDOM.createPortal(
    <div ref={ref} className="pg-picker-dd" style={{ ...pos, padding: '10px 12px', overflow: 'auto', fontSize: 12.5 }}>{children}</div>,
    document.body,
  );
};

const MatDato = ({ label, children }) => (children ? (
  <div style={{ display: 'flex', gap: 8, padding: '3px 0' }}>
    <span className="muted" style={{ width: 78, flexShrink: 0 }}>{label}</span>
    <span style={{ flex: 1, overflowWrap: 'anywhere' }}>{children}</span>
  </div>
) : null);

// Celda "Proyecto": `m` es la línea de material (proyecto_id, pedido_id, proyecto_numero,
// proyecto_nombre, numero_expediente). `onOpen(id)` abre la ficha del proyecto;
// `picker` es el selector para mover la línea a otro proyecto (va dentro del popover).
const MatClienteCell = ({ m, onOpen, picker }) => {
  const [anchor, setAnchor] = React.useState(null);
  const [info, setInfo] = React.useState(null);
  const btn = React.useRef(null);
  const cerrar = React.useCallback(() => setAnchor(null), []);
  React.useEffect(() => { setAnchor(null); }, [m.proyecto_id]); // movida a otro proyecto: los datos ya no valen
  const tiene = m.proyecto_id || m.pedido_id;
  const abrir = () => {
    if (anchor) return setAnchor(null);
    setAnchor(btn.current);
    if (!tiene) return;
    setInfo(null);
    const u = new URLSearchParams();
    if (m.proyecto_id) u.set('proyecto_id', m.proyecto_id); else u.set('pedido_id', m.pedido_id);
    API.get(`/api/programacion/cliente-info?${u}`).then(setInfo).catch((e) => setInfo({ error: e.message }));
  };
  const nombre = (m.proyecto_nombre || '').replace(/^\d+[.,]?\s*/, '');
  const ev = (name, detail) => { window.dispatchEvent(new CustomEvent(name, { detail })); cerrar(); };
  const i = info || {};
  const direccion = [i.direccion, i.localidad, i.cliente_provincia].filter(Boolean).join(', ');
  const ubicacion = [i.ubicacion, i.provincia].filter(Boolean).join(', ');
  return (
    <>
      <button ref={btn} type="button" onClick={abrir} title="Ver los datos del cliente"
        style={{ all: 'unset', cursor: 'pointer', display: 'block', width: '100%', lineHeight: 1.3, whiteSpace: 'normal', overflowWrap: 'anywhere' }}>
        {tiene ? (
          <>
            <span className="mono strong">{m.proyecto_numero || (m.numero_expediente ? `Exp. ${m.numero_expediente}` : '—')}</span>
            {nombre && <div style={{ fontSize: 12 }}>{nombre}</div>}
          </>
        ) : <span className="muted">Sin proyecto</span>}
      </button>
      {anchor && (
        <MatPopover anchor={anchor} onClose={cerrar}>
          {tiene && !info && <div className="muted">Cargando…</div>}
          {info && info.error && <div style={{ color: 'var(--err)' }}>{info.error}</div>}
          {info && !info.error && (
            <>
              <div className="strong" style={{ fontSize: 13.5, marginBottom: 4 }}>{i.cliente_nombre || i.nombre_cliente || nombre || 'Cliente sin nombre'}</div>
              <MatDato label="Teléfono">{i.telefono && <a href={`tel:${String(i.telefono).replace(/\s+/g, '')}`}>{i.telefono}</a>}</MatDato>
              <MatDato label="Email">{i.email && <a href={`mailto:${i.email}`}>{i.email}</a>}</MatDato>
              <MatDato label="Dirección">{direccion}</MatDato>
              <MatDato label="Ubicación">{ubicacion !== direccion ? ubicacion : ''}</MatDato>
              <MatDato label="Proyecto">{i.proyecto_numero && `${i.proyecto_numero}${i.proyecto_nombre ? ` · ${i.proyecto_nombre}` : ''}`}</MatDato>
              <MatDato label="Expediente">{i.numero_expediente}</MatDato>
              <MatDato label="Lead">{i.lead_numero}</MatDato>
              {!i.telefono && !i.email && !direccion && <div className="muted" style={{ fontSize: 11.5, marginTop: 4 }}>Sin teléfono ni dirección del cliente: este proyecto no está enlazado a un lead ni a un expediente con cliente (suele pasar con los que vienen del Excel antiguo).</div>}
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 10 }}>
                {/* INC-018 (19 oct): el destino principal es el expediente de la línea; sin expediente, la ficha del proyecto. */}
                {i.pedido_id && <button className="btn primary sm" onClick={() => { cerrar(); ev('erp:open-expediente', { pedidoId: i.pedido_id }); }}>Expediente</button>}
                {i.proyecto_id && onOpen && <button className={`btn sm ${i.pedido_id ? '' : 'primary'}`} onClick={() => { cerrar(); onOpen(i.proyecto_id); }}>Ficha del proyecto</button>}
                {i.lead_id && <button className="btn sm" onClick={() => ev('erp:open-lead', { id: i.lead_id })}>Lead</button>}
              </div>
            </>
          )}
          {picker && (
            <div style={{ marginTop: 10, paddingTop: 8, borderTop: '1px solid var(--line)' }}>
              <div className="muted" style={{ fontSize: 11.5, marginBottom: 4 }}>{tiene ? 'Mover esta línea a otro proyecto' : 'Asignar esta línea a un proyecto'}</div>
              {picker}
            </div>
          )}
        </MatPopover>
      )}
    </>
  );
};

window.MatTotalesPanel = MatTotalesPanel;
window.MatClienteCell = MatClienteCell;
