// ─────────────────────────────────────────────────────
// INC-008 (Juanjo, 14 oct) — Órdenes de corte (Almacén › Órdenes de corte).
// Salen solas al dar entrada (recepción) a material que se pide por barra
// cuando las medidas son más cortas que la barra: una por recepción +
// material + RAL, con los cortes de cada cliente. Se imprimen para el taller
// y se marcan como hechas. Si se deshace la recepción, la pendiente se anula.
// Sobre /api/stock/ordenes-corte. Expuesto como window.OrdenesCorteView.
// ─────────────────────────────────────────────────────

const OCT_ESTADOS = [
  { v: 'PENDIENTE', label: 'Pendientes' },
  { v: 'HECHA', label: 'Hechas' },
  { v: 'ANULADA', label: 'Anuladas' },
  { v: 'todas', label: 'Todas' },
];
const octNum = (n) => (n == null ? '' : Number(n).toLocaleString('es-ES', { maximumFractionDigits: 2 }));
const octFecha = (f) => (f ? new Date(f).toLocaleDateString('es-ES', { day: '2-digit', month: '2-digit', year: 'numeric' }) : '');

// Cortes agrupados por cliente/expediente y largo.
const octPorCliente = (lineas) => {
  const m = new Map();
  for (const l of lineas) {
    const k = `${l.cliente || ''}|${l.expediente || ''}`;
    if (!m.has(k)) m.set(k, { cliente: l.cliente, expediente: l.expediente, cortes: new Map(), total: 0 });
    const g = m.get(k);
    g.cortes.set(l.largo_mm, (g.cortes.get(l.largo_mm) || 0) + l.uds);
    g.total += l.largo_mm * l.uds;
  }
  return [...m.values()].map(g => ({ ...g, cortes: [...g.cortes.entries()].sort((a, b) => b[0] - a[0]) }));
};

const OrdenCorteCard = ({ o, busy, onHecha, onPendiente, onImprimir }) => {
  const abrirOc = () => window.dispatchEvent(new CustomEvent('erp:open-orden', { detail: { id: o.compra_id } }));
  const link = { background: 'none', border: 0, padding: 0, color: 'var(--accent-ink, var(--info))', cursor: 'pointer', textDecoration: 'underline', font: 'inherit' };
  const pill = o.estado === 'PENDIENTE' ? 'warn' : o.estado === 'HECHA' ? 'ok' : 'err';
  return (
    <div style={{ border: '1px solid var(--line)', borderRadius: 8, marginBottom: 12, overflow: 'hidden', background: 'var(--surface)', opacity: o.estado === 'ANULADA' ? 0.7 : 1 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap', padding: '9px 12px', background: 'var(--surface-2)', fontSize: 13 }}>
        <span className="mono strong">{o.numero}</span>
        <span className={`pill ${pill}`}><span className="d" />{o.estado === 'PENDIENTE' ? 'Pendiente' : o.estado === 'HECHA' ? 'Hecha' : 'Anulada'}</span>
        <span className="strong">{o.referencia && <span className="mono">{o.referencia} · </span>}{o.material_nombre}</span>
        <span>RAL <b>{o.ral || '—'}</b></span>
        <span title={`Σ ${octNum(o.total_mm)} mm ÷ ${octNum(o.largo_barra_mm)} = ${octNum(o.total_mm / o.largo_barra_mm)}`}>
          <b>{o.barras}</b> {o.barras === 1 ? 'barra' : 'barras'} de {octNum(o.largo_barra_mm)} mm
        </span>
        <div style={{ flex: 1 }} />
        <span className="muted" style={{ fontSize: 12 }}>
          {o.recepcion_numero}{o.compra_id ? <> · <button type="button" style={link} onClick={abrirOc}>OC {o.compra_numero || o.compra_id}</button></> : null}
          {o.proveedor_nombre ? ` · ${o.proveedor_nombre}` : ''} · {octFecha(o.created_at)}
        </span>
        <button className="btn ghost sm" onClick={() => onImprimir(o)} title="Imprimir la hoja para el taller"><Icon name="print" size={12} /> Imprimir</button>
        {o.estado === 'PENDIENTE' && <button className="btn primary sm" disabled={busy} onClick={() => onHecha(o)}>Marcar hecha</button>}
        {o.estado === 'HECHA' && <button className="btn ghost sm" disabled={busy} onClick={() => onPendiente(o)} title={`Hecha ${octFecha(o.hecha_at)}${o.hecha_por_nombre ? ` por ${o.hecha_por_nombre}` : ''}`}>Volver a pendiente</button>}
      </div>
      {o.estado === 'ANULADA' && <div className="muted" style={{ fontSize: 12, padding: '4px 12px' }}>{o.motivo_anulacion || 'Anulada'} · {octFecha(o.anulada_at)}</div>}
      <table className="tbl" style={{ margin: 0 }}>
        <thead><tr>
          <th>Cliente · expediente</th><th style={{ width: 140, textAlign: 'right' }}>Largo (mm)</th>
          <th style={{ width: 80, textAlign: 'right' }}>Uds</th><th style={{ width: 130, textAlign: 'right' }}>Total mm</th>
        </tr></thead>
        <tbody>
          {octPorCliente(o.lineas).map(g => g.cortes.map(([largo, uds], i) => (
            <tr key={`${g.cliente}|${g.expediente}|${largo}`}>
              <td>{i === 0 ? <><span className="strong">{g.cliente || g.expediente || 'Sin cliente'}</span>{g.cliente && g.expediente && <span className="muted"> · {g.expediente}</span>}</> : ''}</td>
              <td className="strong" style={{ textAlign: 'right' }}>{octNum(largo)}</td>
              <td style={{ textAlign: 'right' }}>{octNum(uds)}</td>
              <td className="muted" style={{ textAlign: 'right' }}>{octNum(largo * uds)}</td>
            </tr>
          )))}
        </tbody>
      </table>
    </div>
  );
};

const OrdenesCorteView = ({ onToast }) => {
  const [estado, setEstado] = React.useState('PENDIENTE');
  const [search, setSearch] = React.useState('');
  const [ordenes, setOrdenes] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [busy, setBusy] = React.useState(null);
  const timer = React.useRef(null);

  const load = async (e = estado, q = search) => {
    setLoading(true);
    try {
      const params = { estado: e };
      if (q.trim()) params.search = q.trim();
      setOrdenes(await API.get('/api/stock/ordenes-corte', params));
    } catch (err) {
      onToast(err.message || 'Error', true);
    } finally {
      setLoading(false);
    }
  };
  React.useEffect(() => { load(); }, []);

  const onSearch = (v) => { setSearch(v); clearTimeout(timer.current); timer.current = setTimeout(() => load(estado, v), 300); };
  const onEstado = (v) => { setEstado(v); load(v, search); };

  const accion = async (o, ruta, msg) => {
    setBusy(o.id);
    try { await API.post(`/api/stock/ordenes-corte/${o.id}/${ruta}`, {}); onToast(msg); await load(); }
    catch (err) { onToast(err.message || 'Error', true); }
    finally { setBusy(null); }
  };
  const imprimir = async (o) => {
    const w = window.open('', '_blank');
    try {
      const res = await API.request(`/api/stock/ordenes-corte/${o.id}/pdf`);
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const url = URL.createObjectURL(await res.blob());
      if (w) w.location.href = url; else window.open(url, '_blank');
      setTimeout(() => URL.revokeObjectURL(url), 60000);
    } catch (err) {
      if (w) w.close();
      onToast(err.message || 'Error al generar el PDF', true);
    }
  };

  return (
    <div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14, flexWrap: 'wrap' }}>
        <div className="seg">
          {OCT_ESTADOS.map(s => <button key={s.v} className={estado === s.v ? 'on' : ''} onClick={() => onEstado(s.v)}>{s.label}</button>)}
        </div>
        <span className="muted" style={{ fontSize: 12 }}>{ordenes.length} {ordenes.length === 1 ? 'orden' : 'órdenes'}</span>
        <HelpTip label="órdenes de corte" text="Salen solas al dar entrada (recepción) en una OC a material que se pide por barra cuando las medidas son más cortas que la barra (forma de pedir y largo de barra en la ficha del artículo; 6400 si no hay dato). Una por recepción, material y RAL, con los cortes de cada cliente. Si se deshace la línea de la recepción, la orden pendiente se anula." />
        <div style={{ flex: 1 }} />
        <div className="tb-search">
          <Icon name="search" />
          <input placeholder="Material, RAL, cliente, OC…" value={search} onChange={e => onSearch(e.target.value)} />
        </div>
      </div>
      {loading && <div className="muted" style={{ padding: 24, textAlign: 'center' }}>Cargando…</div>}
      {!loading && !ordenes.length && <div className="muted" style={{ padding: 24, textAlign: 'center' }}>Sin órdenes de corte{estado !== 'todas' ? ` ${OCT_ESTADOS.find(s => s.v === estado).label.toLowerCase()}` : ''}.</div>}
      {!loading && ordenes.map(o => (
        <OrdenCorteCard key={o.id} o={o} busy={busy === o.id}
          onHecha={x => accion(x, 'hecha', `${x.numero} hecha ✓`)}
          onPendiente={x => accion(x, 'pendiente', `${x.numero} vuelve a pendiente`)}
          onImprimir={imprimir} />
      ))}
    </div>
  );
};

window.OrdenesCorteView = OrdenesCorteView;
