// WBS / Gantt Tab — split-screen schedule planner.
// Left: hierarchical WBS table. Right: Gantt timeline. Toolbar on top.

const TYPE_LABELS = { phase: "Phase", scope: "Scope", wbs: "WBS", task: "Task" };
const TYPE_TONES = {
  phase: { bg: "rgb(38,40,52)", fg: "#fff" },
  scope: { bg: "rgb(232,233,246)", fg: "rgb(83,74,255)" },
  wbs:   { bg: "rgb(243,244,247)", fg: "rgb(65,69,82)" },
  task:  { bg: "transparent", fg: "rgb(106,115,131)" },
};
const PRIORITY_TONES = {
  High: "rgb(220,72,72)", Med: "rgb(245,166,35)", Low: "rgb(140,148,162)", "—": "rgb(213,219,225)",
};

const fmtShortDate = (s) => {
  const d = new Date(s + "T00:00:00");
  return d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
};
const durationDays = (s, e) => {
  const a = new Date(s + "T00:00:00"), b = new Date(e + "T00:00:00");
  return Math.round((b - a) / 86400000) + 1;
};

// Build flat visible list given expanded set
const buildVisibleRows = (data, expandedSet) => {
  const rows = [];
  const isAncestorCollapsed = (row) => {
    let p = row.parent;
    while (p) {
      if (!expandedSet.has(p)) return true;
      const parent = data.find(r => r.id === p);
      p = parent ? parent.parent : null;
    }
    return false;
  };
  data.forEach(r => {
    if (r.depth === 0 || !isAncestorCollapsed(r)) rows.push(r);
  });
  return rows;
};

// =============================================================================
// WBS TABLE ROW
// =============================================================================
const WBSRow = ({ row, idx, hasChildren, isExpanded, onToggle, selected, hovered, onSelect, onHover }) => {
  const tone = STATUS_TONES[row.status] || STATUS_TONES["Not Started"];
  const owner = OWNER_LOOKUP[row.owner];
  const dur = durationDays(row.start, row.end);
  const isPhase = row.type === "phase";
  const isScope = row.type === "scope";

  const bg = selected ? "rgb(232,233,246)"
    : hovered ? "rgb(247,248,250)"
    : isPhase ? "rgb(247,247,250)"
    : "#fff";

  return (
    <div
      onMouseEnter={() => onHover(row.id)}
      onMouseLeave={() => onHover(null)}
      onClick={() => onSelect(row.id)}
      style={{
        display: "grid",
        gridTemplateColumns: "minmax(260px, 1fr) 64px 88px 88px 84px 60px 110px 100px 36px",
        alignItems: "center",
        height: ROW_H,
        boxSizing: "border-box",
        background: bg,
        borderBottom: "1px solid rgb(247,248,250)",
        cursor: "pointer",
        fontSize: 12,
        color: "rgb(26,27,37)",
      }}
    >
      {/* Name + tree control */}
      <div style={{ display: "flex", alignItems: "center", gap: 4, paddingLeft: 8 + row.depth * 16, paddingRight: 8, minWidth: 0 }}>
        {hasChildren ? (
          <button onClick={(e) => { e.stopPropagation(); onToggle(row.id); }} style={{
            width: 16, height: 16, border: 0, background: "transparent", cursor: "pointer",
            display: "inline-flex", alignItems: "center", justifyContent: "center", color: "rgb(106,115,131)",
            transform: isExpanded ? "rotate(0deg)" : "rotate(-90deg)", transition: "transform 120ms",
          }}>
            <Icon name="expandDown" size={12}/>
          </button>
        ) : <div style={{ width: 16 }}/>}
        {/* type icon */}
        <div style={{ width: 16, display: "inline-flex", alignItems: "center", justifyContent: "center", color: tone.fg, opacity: 0.7 }}>
          <Icon name={isPhase ? "layers" : isScope ? "folder" : row.type === "wbs" ? "list" : "check"} size={12}/>
        </div>
        <span style={{
          fontSize: isPhase ? 12 : 12,
          fontWeight: isPhase ? 700 : isScope ? 600 : row.type === "wbs" ? 500 : 400,
          color: isPhase ? "rgb(26,27,37)" : "rgb(46,49,62)",
          whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", letterSpacing: isPhase ? 0.1 : 0,
        }}>{row.name}</span>
        {row.isCritical && (
          <span title="Critical path" style={{ marginLeft: 4, width: 6, height: 6, borderRadius: "50%", background: "rgb(220,72,72)", flexShrink: 0 }}/>
        )}
      </div>

      {/* Type chip */}
      <div style={{ paddingRight: 8 }}>
        <span style={{
          display: "inline-flex", alignItems: "center", height: 18, padding: "0 6px", borderRadius: 4,
          background: TYPE_TONES[row.type].bg, color: TYPE_TONES[row.type].fg,
          fontSize: 10, fontWeight: 600, letterSpacing: 0.2, textTransform: "uppercase",
          border: row.type === "task" ? "1px solid rgb(227,229,232)" : "0",
        }}>{TYPE_LABELS[row.type]}</span>
      </div>

      {/* Owner */}
      <div style={{ paddingRight: 8 }}>
        {row.type === "phase" ? (
          <span style={{ fontSize: 11, color: "rgb(106,115,131)" }}>—</span>
        ) : (
          <div style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
            <Avatar initials={row.owner} color={owner?.color || "#76ADFF"} size={20}/>
            <span style={{ fontSize: 11, color: "rgb(65,69,82)" }}>{owner?.name.split(" ")[0]}</span>
          </div>
        )}
      </div>

      {/* Start */}
      <div style={{ fontSize: 11, color: "rgb(65,69,82)", paddingRight: 8, fontVariantNumeric: "tabular-nums" }}>{fmtShortDate(row.start)}</div>
      {/* End */}
      <div style={{ fontSize: 11, color: "rgb(65,69,82)", paddingRight: 8, fontVariantNumeric: "tabular-nums" }}>{fmtShortDate(row.end)}</div>
      {/* Duration */}
      <div style={{ fontSize: 11, color: "rgb(106,115,131)", paddingRight: 8, fontVariantNumeric: "tabular-nums" }}>{dur}d</div>

      {/* % Complete with mini bar */}
      <div style={{ display: "flex", alignItems: "center", gap: 6, paddingRight: 8 }}>
        <div style={{ flex: 1, height: 5, background: "rgb(239,240,242)", borderRadius: 999, overflow: "hidden" }}>
          <div style={{ width: `${row.pct}%`, height: "100%", background: tone.bar, borderRadius: 999 }}/>
        </div>
        <span style={{ fontSize: 10, fontWeight: 600, color: "rgb(65,69,82)", fontVariantNumeric: "tabular-nums", minWidth: 26, textAlign: "right" }}>{row.pct}%</span>
      </div>

      {/* Status */}
      <div style={{ paddingRight: 8 }}>
        <Chip tone={tone.tone} dot>{row.status}</Chip>
      </div>

      {/* More */}
      <div style={{ display: "flex", alignItems: "center", justifyContent: "center", color: "rgb(140,148,162)" }}>
        <Icon name="more" size={14}/>
      </div>
    </div>
  );
};

// =============================================================================
// MAIN TAB
// =============================================================================
const WBSGanttTab = ({ p }) => {
  // initial expansion: phases and scopes open, wbs closed
  const initialExpanded = React.useMemo(() => {
    const set = new Set();
    WBS_DATA.forEach(r => { if (r.type === "phase" || r.type === "scope" || r.type === "wbs") set.add(r.id); });
    return set;
  }, []);
  const [expanded, setExpanded] = React.useState(initialExpanded);
  const [scale, setScale] = React.useState("Week");
  const [view, setView] = React.useState("Split"); // Split | WBS | Gantt
  const [search, setSearch] = React.useState("");
  const [statusFilter, setStatusFilter] = React.useState("All");
  const [ownerFilter, setOwnerFilter] = React.useState("All");
  const [criticalOnly, setCriticalOnly] = React.useState(false);
  const [showDeps, setShowDeps] = React.useState(true);
  const [selectedId, setSelectedId] = React.useState("T2.1.2.a");
  const [hoveredId, setHoveredId] = React.useState(null);

  const toggle = (id) => setExpanded(prev => {
    const next = new Set(prev);
    next.has(id) ? next.delete(id) : next.add(id);
    return next;
  });

  // Children lookup
  const childrenMap = React.useMemo(() => {
    const m = {};
    WBS_DATA.forEach(r => {
      if (r.parent) (m[r.parent] = m[r.parent] || []).push(r.id);
    });
    return m;
  }, []);

  // Apply filters: filter is on tasks; phases/scopes shown if any visible descendants
  const filteredIds = React.useMemo(() => {
    const q = search.trim().toLowerCase();
    const matches = (r) => {
      if (q && !r.name.toLowerCase().includes(q)) return false;
      if (statusFilter !== "All" && r.status !== statusFilter) return false;
      if (ownerFilter !== "All" && r.owner !== ownerFilter) return false;
      if (criticalOnly && !r.isCritical) return false;
      return true;
    };
    if (q === "" && statusFilter === "All" && ownerFilter === "All" && !criticalOnly) {
      return new Set(WBS_DATA.map(r => r.id));
    }
    const allowed = new Set();
    WBS_DATA.forEach(r => {
      if (matches(r)) {
        allowed.add(r.id);
        let p = r.parent;
        while (p) { allowed.add(p); const par = WBS_DATA.find(x => x.id === p); p = par ? par.parent : null; }
      }
    });
    return allowed;
  }, [search, statusFilter, ownerFilter, criticalOnly]);

  const visibleRows = React.useMemo(() => {
    return buildVisibleRows(WBS_DATA, expanded).filter(r => filteredIds.has(r.id));
  }, [expanded, filteredIds]);

  // Stats for the toolbar summary
  const stats = React.useMemo(() => {
    const tasks = WBS_DATA.filter(r => r.type === "task");
    return {
      total: tasks.length,
      complete: tasks.filter(t => t.status === "Complete").length,
      inProgress: tasks.filter(t => t.status === "In Progress").length,
      atRisk: tasks.filter(t => t.status === "At Risk").length,
      notStarted: tasks.filter(t => t.status === "Not Started").length,
      critical: WBS_DATA.filter(r => r.isCritical).length,
    };
  }, []);

  const showWBS = view !== "Gantt";
  const showGantt = view !== "WBS";

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>

      {/* TOOLBAR ============================================================== */}
      <Toolbar
        view={view} setView={setView}
        scale={scale} setScale={setScale}
        search={search} setSearch={setSearch}
        statusFilter={statusFilter} setStatusFilter={setStatusFilter}
        ownerFilter={ownerFilter} setOwnerFilter={setOwnerFilter}
        criticalOnly={criticalOnly} setCriticalOnly={setCriticalOnly}
        showDeps={showDeps} setShowDeps={setShowDeps}
        stats={stats}
      />

      {/* AI ASSIST RIBBON ===================================================== */}
      <AIRibbon/>

      {/* SPLIT WORKSPACE ====================================================== */}
      <div style={{
        display: "flex", border: "1px solid rgb(227,229,232)", borderRadius: 12,
        background: "#fff", overflow: "hidden",
      }}>
        {showWBS && <WBSPanel
          rows={visibleRows} childrenMap={childrenMap} expanded={expanded} onToggle={toggle}
          selectedId={selectedId} onSelect={setSelectedId}
          hoveredId={hoveredId} onHover={setHoveredId}
          fullWidth={view === "WBS"}
        />}
        {showWBS && showGantt && <div style={{ width: 1, background: "rgb(227,229,232)" }}/>}
        {showGantt && <GanttPanel
          rows={visibleRows} scale={scale}
          selectedId={selectedId} onSelect={setSelectedId}
          hoveredId={hoveredId} onHover={setHoveredId}
          criticalOnly={criticalOnly} showDeps={showDeps}
        />}
      </div>

      {/* LEGEND =============================================================== */}
      <Legend/>
    </div>
  );
};

// =============================================================================
// TOOLBAR
// =============================================================================
const Toolbar = ({ view, setView, scale, setScale, search, setSearch,
  statusFilter, setStatusFilter, ownerFilter, setOwnerFilter,
  criticalOnly, setCriticalOnly, showDeps, setShowDeps, stats }) => {

  const segBtn = (label, active, onClick, icon) => (
    <button key={label} onClick={onClick} style={{
      height: 28, padding: "0 10px", border: 0, cursor: "pointer",
      background: active ? "#fff" : "transparent",
      color: active ? "rgb(26,27,37)" : "rgb(106,115,131)",
      fontSize: 12, fontWeight: 600, borderRadius: 6,
      display: "inline-flex", alignItems: "center", gap: 5,
      boxShadow: active ? "0 1px 3px rgba(0,0,0,0.06), 0 0 0 1px rgb(227,229,232)" : "none",
    }}>{icon && <Icon name={icon} size={12}/>}{label}</button>
  );

  const Sel = ({ value, onChange, options, label }) => (
    <div style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
      <span style={{ fontSize: 11, color: "rgb(106,115,131)", fontWeight: 500 }}>{label}</span>
      <select value={value} onChange={e => onChange(e.target.value)} style={{
        height: 28, padding: "0 8px", border: "1px solid rgb(213,219,225)", borderRadius: 6,
        background: "#fff", fontSize: 12, color: "rgb(26,27,37)", fontWeight: 500, cursor: "pointer",
      }}>
        {options.map(o => <option key={o.v} value={o.v}>{o.l}</option>)}
      </select>
    </div>
  );

  return (
    <div style={{
      background: "#fff", border: "1px solid rgb(227,229,232)", borderRadius: 12,
      padding: "10px 12px", display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap",
    }}>
      {/* Stats summary */}
      <div style={{ display: "flex", alignItems: "center", gap: 14, paddingRight: 8, borderRight: "1px solid rgb(239,240,242)", marginRight: 4 }}>
        <Stat label="Tasks" value={stats.total}/>
        <Stat label="Complete" value={stats.complete} tone="info"/>
        <Stat label="In Progress" value={stats.inProgress} tone="success"/>
        <Stat label="At Risk" value={stats.atRisk} tone="warning"/>
        <Stat label="Not Started" value={stats.notStarted} tone="neutral"/>
        <Stat label="Critical" value={stats.critical} tone="danger"/>
      </div>

      {/* View toggle */}
      <div style={{ display: "inline-flex", background: "rgb(243,244,247)", padding: 2, borderRadius: 8, gap: 0 }}>
        {segBtn("WBS", view === "WBS", () => setView("WBS"), "list")}
        {segBtn("Split", view === "Split", () => setView("Split"), "grid")}
        {segBtn("Gantt", view === "Gantt", () => setView("Gantt"), "chart")}
      </div>

      {/* Scale */}
      <div style={{ display: "inline-flex", background: "rgb(243,244,247)", padding: 2, borderRadius: 8 }}>
        {["Day", "Week", "Month"].map(s => segBtn(s, scale === s, () => setScale(s)))}
      </div>

      {/* Search */}
      <div style={{ position: "relative" }}>
        <Icon name="search" size={13} color="rgb(140,148,162)" style={{ position: "absolute", left: 9, top: "50%", transform: "translateY(-50%)" }}/>
        <input value={search} onChange={e => setSearch(e.target.value)} placeholder="Search tasks…" style={{
          height: 28, padding: "0 10px 0 28px", border: "1px solid rgb(213,219,225)", borderRadius: 6,
          background: "#fff", fontSize: 12, width: 180, outline: "none",
        }}/>
      </div>

      {/* Filters */}
      <Sel label="Status" value={statusFilter} onChange={setStatusFilter}
        options={[{v:"All",l:"All"},{v:"Not Started",l:"Not Started"},{v:"In Progress",l:"In Progress"},{v:"At Risk",l:"At Risk"},{v:"Complete",l:"Complete"}]}/>
      <Sel label="Owner" value={ownerFilter} onChange={setOwnerFilter}
        options={[{v:"All",l:"All"},...Object.entries(OWNER_LOOKUP).map(([k,v])=>({v:k,l:v.name}))]}/>

      {/* Toggles */}
      <button onClick={() => setCriticalOnly(!criticalOnly)} style={{
        height: 28, padding: "0 10px", borderRadius: 6, cursor: "pointer", fontSize: 12, fontWeight: 600,
        border: `1px solid ${criticalOnly ? "rgb(220,72,72)" : "rgb(213,219,225)"}`,
        background: criticalOnly ? "rgb(253,222,222)" : "#fff",
        color: criticalOnly ? "rgb(196,52,52)" : "rgb(65,69,82)",
        display: "inline-flex", alignItems: "center", gap: 5,
      }}>
        <span style={{ width: 6, height: 6, borderRadius: "50%", background: "rgb(220,72,72)" }}/>
        Critical path
      </button>
      <button onClick={() => setShowDeps(!showDeps)} style={{
        height: 28, padding: "0 10px", borderRadius: 6, cursor: "pointer", fontSize: 12, fontWeight: 600,
        border: "1px solid rgb(213,219,225)",
        background: showDeps ? "rgb(232,233,246)" : "#fff",
        color: showDeps ? "rgb(83,74,255)" : "rgb(65,69,82)",
        display: "inline-flex", alignItems: "center", gap: 5,
      }}>
        <Icon name="layers" size={12}/>
        Dependencies
      </button>

      <div style={{ flex: 1 }}/>

      {/* Add actions */}
      <Button kind="secondary" size="sm" icon="plus">Add Phase</Button>
      <Button kind="primary" size="sm" icon="plus">Add Task</Button>
    </div>
  );
};

const Stat = ({ label, value, tone = "neutral" }) => {
  const toneFg = TONES[tone]?.fg || "rgb(106,115,131)";
  return (
    <div style={{ display: "inline-flex", flexDirection: "column", lineHeight: 1.1 }}>
      <span style={{ fontSize: 16, fontWeight: 700, color: toneFg, fontVariantNumeric: "tabular-nums" }}>{value}</span>
      <span style={{ fontSize: 10, color: "rgb(106,115,131)", fontWeight: 500, textTransform: "uppercase", letterSpacing: 0.4 }}>{label}</span>
    </div>
  );
};

// =============================================================================
// AI ASSIST RIBBON
// =============================================================================
const AIRibbon = () => (
  <div style={{
    background: "linear-gradient(90deg, rgba(83,74,255,0.05) 0%, rgba(255,255,255,0) 60%)",
    border: "1px solid rgb(227,229,232)", borderRadius: 12, padding: "10px 14px",
    display: "flex", alignItems: "center", gap: 14, flexWrap: "wrap",
  }}>
    <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
      <div style={{
        width: 24, height: 24, borderRadius: 6,
        background: "linear-gradient(135deg, rgb(83,74,255), rgb(178,121,255))",
        display: "inline-flex", alignItems: "center", justifyContent: "center", color: "#fff",
      }}><Icon name="zap" size={13}/></div>
      <span style={{ fontSize: 12, fontWeight: 600, color: "rgb(46,49,62)" }}>Mindworks AI</span>
    </div>

    <div style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 12, color: "rgb(46,49,62)" }}>
      <Icon name="alert" size={13} color="rgb(245,166,35)"/>
      <span><b>Torque tube install</b> trending 6 days late — racking phase finish at risk.</span>
    </div>

    <div style={{ width: 1, height: 18, background: "rgb(227,229,232)" }}/>

    <div style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 12, color: "rgb(46,49,62)" }}>
      <Icon name="alertCircle" size={13} color="rgb(220,72,72)"/>
      <span><b>Dependency conflict:</b> Module install can't start until purlins finish.</span>
    </div>

    <div style={{ flex: 1 }}/>

    <Button kind="ghost" size="sm" icon="layers">Generate WBS from Scopes</Button>
    <Button kind="ghost" size="sm" icon="zap">Suggest Task Breakdown</Button>
    <Button kind="primary" size="sm" icon="zap">Resolve all (3)</Button>
  </div>
);

// =============================================================================
// WBS PANEL (left)
// =============================================================================
const WBSPanel = ({ rows, childrenMap, expanded, onToggle, selectedId, onSelect, hoveredId, onHover, fullWidth }) => {
  return (
    <div style={{ width: fullWidth ? "100%" : "min(640px, 50%)", flexShrink: 0, display: "flex", flexDirection: "column", borderRight: 0 }}>
      {/* Header */}
      <div style={{
        display: "grid",
        gridTemplateColumns: "minmax(260px, 1fr) 64px 88px 88px 84px 60px 110px 100px 36px",
        height: 57, alignItems: "end", padding: "0 0 8px 0", boxSizing: "border-box",
        borderBottom: "1px solid rgb(227,229,232)", background: "#fff",
      }}>
        {[
          { l: "Name / WBS Element", pl: 8 + 16 + 16 + 4 },
          { l: "Type" },
          { l: "Owner" },
          { l: "Start" },
          { l: "End" },
          { l: "Dur." },
          { l: "% Complete" },
          { l: "Status" },
          { l: "" },
        ].map((h, i) => (
          <div key={i} style={{
            fontSize: 10, fontWeight: 600, color: "rgb(106,115,131)",
            textTransform: "uppercase", letterSpacing: 0.6, paddingLeft: h.pl || 0, paddingRight: 8,
          }}>{h.l}</div>
        ))}
      </div>
      {/* Body */}
      <div>
        {rows.map((row, idx) => (
          <WBSRow key={row.id} row={row} idx={idx}
            hasChildren={!!(childrenMap[row.id] && childrenMap[row.id].length)}
            isExpanded={expanded.has(row.id)}
            onToggle={onToggle}
            selected={selectedId === row.id}
            hovered={hoveredId === row.id}
            onSelect={onSelect}
            onHover={onHover}
          />
        ))}
        {/* + Add task row */}
        <button style={{
          display: "flex", alignItems: "center", gap: 6, padding: "10px 16px",
          width: "100%", border: 0, background: "transparent", cursor: "pointer",
          color: "rgb(106,115,131)", fontSize: 12, fontWeight: 500,
        }}>
          <Icon name="plus" size={12}/> Add task
        </button>
      </div>
    </div>
  );
};

// =============================================================================
// GANTT PANEL (right)
// =============================================================================
const GanttPanel = ({ rows, scale, selectedId, onSelect, hoveredId, onHover, criticalOnly, showDeps }) => {
  return (
    <div style={{ flex: 1, display: "flex", flexDirection: "column", minWidth: 0 }}>
      <GanttChart
        rows={rows}
        projectStart="2026-01-12"
        projectEnd="2026-11-30"
        scale={scale}
        selectedId={selectedId} onSelect={onSelect}
        hoveredId={hoveredId} onHover={onHover}
        criticalOnly={criticalOnly} showDeps={showDeps}
      />
    </div>
  );
};

// =============================================================================
// LEGEND
// =============================================================================
const Legend = () => (
  <div style={{
    background: "#fff", border: "1px solid rgb(227,229,232)", borderRadius: 12,
    padding: "10px 14px", display: "flex", alignItems: "center", gap: 18, flexWrap: "wrap",
    fontSize: 11, color: "rgb(65,69,82)",
  }}>
    <span style={{ fontSize: 10, fontWeight: 600, color: "rgb(106,115,131)", textTransform: "uppercase", letterSpacing: 0.5 }}>Legend</span>
    <LegendBar color="rgb(38,40,52)" label="Phase" shape="phase"/>
    <LegendBar color="rgb(108,99,255)" label="Scope" shape="scope"/>
    <LegendBar color="rgb(52,168,83)" label="On track"/>
    <LegendBar color="rgb(245,166,35)" label="At risk"/>
    <LegendBar color="rgb(220,72,72)" label="Delayed"/>
    <LegendBar color="rgb(176,184,196)" label="Not started"/>
    <div style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
      <span style={{ width: 14, height: 14, background: "rgb(34,134,58)", transform: "rotate(45deg)", display: "inline-block" }}/>
      <span>Milestone</span>
    </div>
    <div style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
      <span style={{ width: 18, height: 2, background: "rgb(220,72,72)", display: "inline-block" }}/>
      <span>Critical path</span>
    </div>
    <div style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
      <svg width="22" height="10"><path d="M0,5 L18,5" stroke="rgb(140,148,162)" strokeDasharray="3,2" fill="none" markerEnd="url(#legendArrow)"/>
        <defs><marker id="legendArrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="5" markerHeight="5" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="rgb(140,148,162)"/></marker></defs>
      </svg>
      <span>Dependency</span>
    </div>
    <div style={{ flex: 1 }}/>
    <span style={{ fontSize: 11, color: "rgb(106,115,131)" }}>Drag bar edges to resize · drag bars to move · click row for details</span>
  </div>
);

const LegendBar = ({ color, label, shape = "task" }) => (
  <div style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
    <span style={{
      width: 22, height: shape === "phase" ? 8 : 6, background: color,
      borderRadius: shape === "phase" ? 2 : 3, display: "inline-block",
    }}/>
    <span>{label}</span>
  </div>
);

Object.assign(window, { WBSGanttTab });
