// ROCA GOLF — Gantt por insumo/presupuesto + alertas automáticas como pins

function daysBetween(a, b) {
  const da = new Date(a + "T00:00:00"), db = new Date(b + "T00:00:00");
  return Math.round((db - da) / 86400000);
}
function addDaysISO(iso, n) {
  const d = new Date(iso + "T00:00:00");
  d.setDate(d.getDate() + n);
  return d.toISOString().slice(0, 10);
}
function monthLabelES(iso) {
  const m = ["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"];
  const d = new Date(iso + "T00:00:00");
  return `${m[d.getMonth()]} ${d.getFullYear().toString().slice(2)}`;
}
function shortDate(iso) {
  const d = new Date(iso + "T00:00:00");
  return `${String(d.getDate()).padStart(2,"0")}/${String(d.getMonth()+1).padStart(2,"0")}`;
}

const GANTT_FAM_COLORS = {
  "01": "#2d6a44", "02": "#a88838", "03": "#1976d2", "04": "#b22222",
  "05": "#7c4dff", "06": "#0d2818", "07": "#0e8a7a", "08": "#c8651b"
};

// Color de barra según % de utilización del presupuesto
function ganttBarColor(pct) {
  if (pct >= 100) return "#b71c1c";
  if (pct >= 90)  return "#e53935";
  if (pct >= 80)  return "#f57c00";
  if (pct >= 70)  return "#f9a825";
  return "#2d6a44";
}

function GanttChart({ proyecto, presupuestos, alertas, onAlertClick, onAddAlert }) {
  const today = new Date().toISOString().slice(0, 10);
  const [fullscreen, setFullscreen] = useState(false);
  const [tooltip,   setTooltip]    = useState(null);
  const tooltipRef = useRef(null);

  useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') { setFullscreen(false); setTooltip(null); } };
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, []);

  useEffect(() => {
    if (!tooltip) return;
    function onDown(e) {
      if (tooltipRef.current && !tooltipRef.current.contains(e.target)) setTooltip(null);
    }
    document.addEventListener('mousedown', onDown);
    document.addEventListener('touchstart', onDown);
    return () => { document.removeEventListener('mousedown', onDown); document.removeEventListener('touchstart', onDown); };
  }, [tooltip]);

  async function openTooltip(pp, e) {
    e.stopPropagation();
    if (tooltip && tooltip.pp.id === pp.id) { setTooltip(null); return; }
    const rect = e.currentTarget.getBoundingClientRect();
    const x = Math.min(rect.left, window.innerWidth - 334);
    const y = rect.bottom + 6;
    setTooltip({ pp, ocs: [], loading: true, x, y });
    try {
      const data = await apiFetch(`presupuestos_proyecto.php?mode=ocs&proyectoid=${pp.proyectoid}&insumoid=${pp.insumoid}`);
      setTooltip(t => t && t.pp.id === pp.id ? { ...t, ocs: Array.isArray(data) ? data : [], loading: false } : t);
    } catch {
      setTooltip(t => t && t.pp.id === pp.id ? { ...t, ocs: [], loading: false } : t);
    }
  }

  const startISO  = proyecto.inicio;
  const endISO    = proyecto.fin;

  // Expandir rango para incluir todas las fechas de presupuestos
  let effectiveStart = startISO;
  let effectiveEnd   = endISO;
  (presupuestos || []).forEach(pp => {
    if (pp.fecha_inicio && pp.fecha_inicio < effectiveStart) effectiveStart = pp.fecha_inicio;
    if (pp.fecha_fin   && pp.fecha_fin   > effectiveEnd)   effectiveEnd   = pp.fecha_fin;
  });

  const totalDays = Math.max(1, daysBetween(effectiveStart, effectiveEnd));
  const COL_LEFT  = 300;
  const ROW_H     = 42;
  const HEAD_H    = 56; // meses(26) + semanas(30); left head forced to same via CSS height:56px
  const PAD_BARS  = 8;
  const innerW    = Math.max(1000, totalDays * 10);
  const dayW      = innerW / totalDays;

  const rows = presupuestos || [];

  // Marcas de mes
  const months = [];
  let cur = new Date(effectiveStart + "T00:00:00");
  cur.setDate(1);
  while (cur <= new Date(effectiveEnd + "T00:00:00")) {
    const iso = cur.toISOString().slice(0, 10);
    const offset = daysBetween(effectiveStart, iso);
    months.push({ iso, offset: Math.max(0, offset), label: monthLabelES(iso) });
    cur.setMonth(cur.getMonth() + 1);
  }
  const weeks = [];
  for (let d = 0; d <= totalDays; d += 7) weeks.push(d);
  const todayOffset = daysBetween(effectiveStart, today);

  const rowsH = Math.max(rows.length * ROW_H + 12, 60);
  const THRESHOLDS = [70, 80, 90, 100];

  return (
    <div className={"rg-gantt" + (fullscreen ? " rg-gantt-fullscreen" : "")}>

      {/* ── Layout principal: columna fija izquierda + scroll derecho ── */}
      <div className="rg-gantt-wrap">

        {/* Columna izquierda fija */}
        <div className="rg-gantt-col-left" style={{ width: COL_LEFT }}>

          {/* Cabecera izquierda: info + botones */}
          <div className="rg-gantt-head-left" style={{ height: HEAD_H }}>
            <div style={{ minWidth: 0 }}>
              <div style={{ fontSize: 10, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--rg-muted)", fontWeight: 600 }}>Insumo · clave</div>
              <div style={{ fontSize: 11.5, color: "var(--rg-ink-2)", marginTop: 3, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                {rows.length} insumos · {proyecto.nombre}
              </div>
            </div>
            <div style={{ display: "flex", flexDirection: "row", gap: 4, alignItems: "center", flexShrink: 0 }}>
              <button className="rg-btn primary" onClick={onAddAlert}
                style={{ height: 24, padding: "0 8px", fontSize: 11, gap: 4 }}>
                {Icon.bell(12)} Alerta
              </button>
              <button className="rg-btn" onClick={() => setFullscreen(f => !f)}
                style={{ height: 24, width: 28, padding: 0, justifyContent: "center" }}
                title={fullscreen ? "Salir pantalla completa (Esc)" : "Ver en pantalla completa"}>
                {fullscreen
                  ? <svg width="12" height="12" viewBox="0 0 11 11" fill="none"><path d="M1 4H4V1M7 1v3h3M10 7H7v3M4 10V7H1" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/></svg>
                  : <svg width="12" height="12" viewBox="0 0 11 11" fill="none"><path d="M1 4V1h3M7 1h3v3M10 7v3H7M4 10H1V7" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/></svg>
                }
              </button>
            </div>
          </div>

          {/* Etiquetas de filas */}
          <div style={{ flex: 1 }}>
            {rows.length === 0 ? (
              <div style={{ padding: "20px 14px", fontSize: 12, color: "var(--rg-muted)", textAlign: "center", lineHeight: 1.6 }}>
                Sin presupuestos asignados.<br/>
                <span style={{ fontSize: 11 }}>Usa <strong>Asignar presupuesto</strong> para ver insumos aquí.</span>
              </div>
            ) : rows.map(pp => {
              const c = ganttBarColor(pp.pct);
              return (
                <div key={pp.id} className="rg-gantt-row-left" style={{ height: ROW_H }}>
                  <span className="rg-fam-chip">
                    <span className="swatch" style={{ background: GANTT_FAM_COLORS[pp.codigofamilia] || "var(--rg-muted)" }}/>
                    {pp.insumo_clave}
                  </span>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 11.5, color: "var(--rg-ink)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }} title={pp.insumo_descripcion}>
                      {pp.insumo_descripcion}
                    </div>
                    {(pp.fecha_inicio || pp.fecha_fin) && (
                      <div style={{ fontSize: 9.5, color: "var(--rg-muted)", fontFamily: "var(--rg-font-mono)", marginTop: 1 }}>
                        {shortDate(pp.fecha_inicio || startISO)} → {shortDate(pp.fecha_fin || endISO)}
                      </div>
                    )}
                  </div>
                  {pp.severidad && (
                    <span style={{
                      fontSize: 9.5, fontFamily: "var(--rg-font-mono)", fontWeight: 700,
                      color: c, background: c + "18", border: "1px solid " + c + "66",
                      borderRadius: 3, padding: "1px 4px", flexShrink: 0
                    }}>{pp.pct.toFixed(0)}%</span>
                  )}
                </div>
              );
            })}
          </div>
        </div>

        {/* Scroll horizontal único: encabezado de meses/semanas + barras */}
        <div className="rg-gantt-scroll">
          <div style={{ minWidth: innerW, position: "relative" }}>

            {/* Meses */}
            <div className="rg-gantt-months">
              {months.map((m, i) => {
                const next = months[i + 1];
                const w = next ? (next.offset - m.offset) * dayW : (totalDays - m.offset) * dayW;
                return (
                  <div key={i} style={{ width: w, paddingLeft: 8, flexShrink: 0 }}>
                    <span className="lbl">{m.label}</span>
                  </div>
                );
              })}
            </div>

            {/* Semanas */}
            <div className="rg-gantt-weeks">
              {weeks.map((d, i) => (
                <div key={i} className="tick" style={{ left: d * dayW }}>
                  <span>{shortDate(addDaysISO(effectiveStart, d))}</span>
                </div>
              ))}
            </div>

            {/* Área de barras */}
            <div className="rg-gantt-rows-right" style={{ height: rowsH }}>
              {/* Líneas de semana */}
              {weeks.map((d, i) => <div key={i} className="rg-gantt-vline" style={{ left: d * dayW }}/>)}

              {/* Marcador HOY */}
              {todayOffset >= 0 && todayOffset <= totalDays && (
                <div className="rg-gantt-today" style={{ left: todayOffset * dayW }}>
                  <span className="dot"/>
                  <span className="lbl">HOY</span>
                </div>
              )}

              {/* Fondos de fila */}
              {rows.map((pp, i) => (
                <div key={"bg-"+pp.id} className="rg-gantt-rowbg" style={{ top: i * ROW_H, height: ROW_H }}/>
              ))}

              {/* Barras de presupuesto por insumo */}
              {rows.map((pp, i) => {
                const c = ganttBarColor(pp.pct);
                // Usar fechas del presupuesto si están definidas, si no usar el rango del proyecto
                const barStart = pp.fecha_inicio || startISO;
                const barEnd   = pp.fecha_fin   || endISO;
                const barOffset = Math.max(0, daysBetween(effectiveStart, barStart));
                const barDays  = Math.max(1, daysBetween(barStart, barEnd));
                const barLeft  = barOffset * dayW;
                const barWidth = barDays * dayW;
                const fillW    = (barWidth * Math.min(pp.pct, 100)) / 100;
                // Pin de alerta en posición "hoy" relativa al inicio de la barra
                const todayInBar = todayOffset - barOffset;
                const pinTodayLeft = todayInBar >= 0 && todayInBar <= barDays
                  ? Math.min(todayInBar * dayW, barWidth - 18) : null;

                return (
                  <div key={"bar-"+pp.id} className="rg-gantt-bar"
                    onClick={e => openTooltip(pp, e)}
                    style={{
                      top: i * ROW_H + PAD_BARS,
                      left: barLeft,
                      width: barWidth,
                      height: ROW_H - PAD_BARS * 2,
                      background: c + "14",
                      borderColor: c + "66",
                      cursor: 'pointer'
                    }}>

                    {/* Fill: porcentaje ejercido */}
                    <div className="rg-gantt-bar-fill" style={{ width: fillW, background: c, opacity: 0.75 }}/>

                    {/* Marcadores de umbral: 70%, 80%, 90%, 100% del ancho de la barra */}
                    {THRESHOLDS.map(th => {
                      const tickLeft = (barWidth * th) / 100;
                      const crossed = pp.pct >= th;
                      return (
                        <React.Fragment key={th}>
                          <div style={{
                            position: "absolute", left: tickLeft, top: 0, bottom: 0,
                            width: crossed ? 2 : 1,
                            background: crossed ? c : "rgba(0,0,0,0.18)",
                            zIndex: 2, pointerEvents: "none"
                          }}/>
                          <span style={{
                            position: "absolute", left: tickLeft + 3, top: 2,
                            fontSize: 7.5, fontFamily: "var(--rg-font-mono)", fontWeight: 700,
                            color: crossed ? c : "rgba(0,0,0,0.28)",
                            zIndex: 3, pointerEvents: "none", whiteSpace: "nowrap",
                            lineHeight: 1
                          }}>{th}%</span>
                        </React.Fragment>
                      );
                    })}

                    {/* Etiqueta principal: % y montos */}
                    <div className="rg-gantt-bar-label">
                      <span className="pct" style={{ background: c + "30", color: c, fontWeight: 800, fontSize: 11 }}>
                        {pp.pct.toFixed(1)}%
                      </span>
                      <span className="amt">
                        ${fmtMoney(pp.gastado, { compact: true })} / ${fmtMoney(pp.monto, { compact: true })}
                      </span>
                    </div>

                    {/* Pin de alerta automática en posición "hoy" (si supera umbral) */}
                    {pp.severidad && pinTodayLeft !== null && (
                      <button className={"rg-gantt-pin " + pp.severidad}
                        title={`${pp.insumo_clave}: ${pp.pct.toFixed(1)}% del presupuesto (umbral ${pp.pct_umbral}%)`}
                        onClick={(e) => { e.stopPropagation(); onAlertClick && onAlertClick({ ...pp, titulo: pp.insumo_clave, tipo: 'budget' }); }}
                        style={{ left: pinTodayLeft - 9 }}>
                        <svg width="18" height="20" viewBox="0 0 18 20" fill="none">
                          <line x1="3" y1="2" x2="3" y2="18" stroke="#3a3530" strokeWidth="1.2"/>
                          <path d="M3 2 L 16 5.5 L 3 9 Z" fill={flagColor(pp.severidad)}/>
                          <circle cx="3" cy="18.5" r="1.4" fill="#3a3530"/>
                        </svg>
                      </button>
                    )}

                    {/* Alertas manuales asociadas a este insumo */}
                    {(alertas || []).filter(a => a.insumoid === pp.insumoid).map(a => {
                      const pinOffset = daysBetween(barStart, a.fecha);
                      const pinLeft = Math.max(0, Math.min(barWidth - 18, pinOffset * dayW));
                      return (
                        <button key={a.id} className={"rg-gantt-pin " + a.severidad}
                          title={a.titulo}
                          onClick={(e) => { e.stopPropagation(); onAlertClick && onAlertClick(a); }}
                          style={{ left: pinLeft - 9 }}>
                          <svg width="18" height="20" viewBox="0 0 18 20" fill="none">
                            <line x1="3" y1="2" x2="3" y2="18" stroke="#3a3530" strokeWidth="1.2"/>
                            <path d="M3 2 L 16 5.5 L 3 9 Z" fill={flagColor(a.severidad)}/>
                            <circle cx="3" cy="18.5" r="1.4" fill="#3a3530"/>
                          </svg>
                        </button>
                      );
                    })}
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      </div>

      <OcTooltip tooltip={tooltip} setTooltip={setTooltip} tooltipRef={tooltipRef}/>

      {/* Footer leyenda */}
      <div className="rg-gantt-foot">
        <div className="rg-row" style={{ gap: 12, flexWrap: "wrap" }}>
          <span style={{ fontSize: 10, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--rg-muted)", fontWeight: 600 }}>Familias</span>
          {Object.entries(GANTT_FAM_COLORS).map(([k, c]) => (
            <span key={k} className="rg-row" style={{ gap: 4, fontSize: 11, color: "var(--rg-ink-2)" }}>
              <span style={{ width: 8, height: 8, borderRadius: 2, background: c, display: "inline-block", flexShrink: 0 }}/>
              {k}
            </span>
          ))}
          <span className="rg-spacer"/>
          <span style={{ fontSize: 10, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--rg-muted)", fontWeight: 600 }}>Utilización</span>
          {[["#2d6a44","< 70%"], ["#f9a825","70%"], ["#f57c00","80%"], ["#e53935","90%"], ["#b71c1c","100%+"]].map(([c, lb]) => (
            <span key={lb} className="rg-row" style={{ gap: 5, fontSize: 11, color: "var(--rg-ink-2)" }}>
              <span style={{ width: 10, height: 10, borderRadius: 2, background: c, display: "inline-block", flexShrink: 0 }}/>
              {lb}
            </span>
          ))}
          <span className="rg-spacer"/>
          <span style={{ fontSize: 10, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--rg-muted)", fontWeight: 600 }}>Alertas</span>
          {[["over","Excedido"],["alert","Alerta"],["warn","Aviso"]].map(([lv,lb]) => (
            <span key={lv} className="rg-row" style={{ gap: 5, fontSize: 11, color: "var(--rg-ink-2)" }}>
              <svg width="10" height="12" viewBox="0 0 10 12"><path d="M2 1 L 9 3 L 2 5 Z" fill={flagColor(lv)}/><line x1="2" y1="1" x2="2" y2="11" stroke="#3a3530" strokeWidth="1"/></svg>
              {lb}
            </span>
          ))}
        </div>
      </div>
    </div>
  );
}

function OcTooltip({ tooltip, setTooltip, tooltipRef }) {
  if (!tooltip) return null;
  const pp = tooltip.pp;
  const c  = ganttBarColor(pp.pct);
  const left = Math.max(8, Math.min(tooltip.x, window.innerWidth - 334));
  const top  = Math.min(tooltip.y, window.innerHeight - 300);
  return ReactDOM.createPortal(
    <div ref={tooltipRef} style={{
      position: 'fixed', left, top, width: 320,
      background: 'var(--rg-surface)', border: '1px solid var(--rg-line)',
      borderRadius: 10, boxShadow: '0 8px 32px rgba(0,0,0,0.2)',
      zIndex: 2001, overflow: 'hidden', fontSize: 12,
      fontFamily: 'var(--rg-font)',
    }}>
      {/* Cabecera */}
      <div style={{ padding: '9px 12px 8px', background: 'var(--rg-cream)', borderBottom: '1px solid var(--rg-line)', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 8 }}>
        <div style={{ minWidth: 0 }}>
          <div style={{ fontWeight: 700, color: 'var(--rg-ink)', fontSize: 12.5, display: 'flex', alignItems: 'center', gap: 6 }}>
            <span style={{ fontFamily: 'var(--rg-font-mono)', fontSize: 11, background: c + '18', color: c, border: '1px solid ' + c + '55', borderRadius: 3, padding: '1px 5px' }}>{pp.insumo_clave}</span>
            <span style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', maxWidth: 160 }}>{pp.insumo_descripcion}</span>
          </div>
          <div style={{ fontSize: 10.5, color: 'var(--rg-muted)', marginTop: 3, display: 'flex', gap: 12 }}>
            <span>Ejercido: <strong style={{ color: c }}>${fmtMoney(pp.gastado)}</strong></span>
            <span>Ppto: <strong>${fmtMoney(pp.monto)}</strong></span>
            <span style={{ fontWeight: 700, color: c }}>{pp.pct.toFixed(1)}%</span>
          </div>
        </div>
        <button onClick={() => setTooltip(null)} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--rg-muted)', fontSize: 18, lineHeight: 1, padding: '0 2px', flexShrink: 0, marginTop: -1 }}>×</button>
      </div>
      {/* Lista OCs */}
      <div style={{ maxHeight: 248, overflowY: 'auto' }}>
        {tooltip.loading && (
          <div style={{ padding: 20, textAlign: 'center', color: 'var(--rg-muted)', fontSize: 11.5 }}>Cargando órdenes…</div>
        )}
        {!tooltip.loading && tooltip.ocs.length === 0 && (
          <div style={{ padding: 20, textAlign: 'center', color: 'var(--rg-muted)', fontSize: 11.5 }}>Sin órdenes de compra registradas</div>
        )}
        {!tooltip.loading && tooltip.ocs.length > 0 && (
          <div style={{ padding: '4px 0 0' }}>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr auto auto', gap: '0 10px', padding: '3px 12px 5px', borderBottom: '1px solid var(--rg-line-2)', fontSize: 9.5, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--rg-muted)', fontWeight: 600 }}>
              <span>1ª Partida</span><span style={{ textAlign: 'right' }}>Monto</span><span style={{ textAlign: 'right' }}>Fecha</span>
            </div>
            {tooltip.ocs.map((oc, i) => (
              <div key={oc.id || i} style={{ display: 'grid', gridTemplateColumns: '1fr auto auto', gap: '0 10px', padding: '7px 12px', borderBottom: '1px solid var(--rg-line-2)', alignItems: 'center' }}>
                <div style={{ minWidth: 0 }}>
                  <div style={{ fontFamily: 'var(--rg-font-mono)', fontSize: 9.5, color: 'var(--rg-muted)', fontWeight: 600 }}>{oc.folio}</div>
                  <div style={{ fontSize: 11.5, color: 'var(--rg-ink)', marginTop: 1, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }} title={oc.primera_partida}>{oc.primera_partida || '—'}</div>
                </div>
                <div style={{ fontFamily: 'var(--rg-font-mono)', fontWeight: 700, fontSize: 11.5, color: 'var(--rg-ink)', textAlign: 'right', whiteSpace: 'nowrap' }}>${fmtMoney(oc.monto)}</div>
                <div style={{ fontSize: 10, color: 'var(--rg-muted)', textAlign: 'right', whiteSpace: 'nowrap' }}>{oc.fecha ? shortDate(oc.fecha.slice(0,10)) : '—'}</div>
              </div>
            ))}
          </div>
        )}
      </div>
    </div>,
    document.body
  );
}

Object.assign(window, { GanttChart, GANTT_FAM_COLORS, daysBetween, addDaysISO });
