/* eslint-disable */
// Reporting 2.0 — shared report-page components: TopBar, SideNav, FilterBar,
// WeekPicker, DataTable, state shells, OnboardingBadge.

(function () {
const { useState, useMemo, useRef, useEffect } = React;
const { Icon, Button, Badge, fmtCell, fmtDate, JOB_OPTIONS, LOCATION_OPTIONS, PERIOD_OPTIONS } = window;

// =============================================================================
// TOP BAR
// =============================================================================
function TopBar() {
  return (
    <div style={{
      display: "flex", alignItems: "center", gap: 24, padding: "0 24px", height: 56,
      background: "var(--neutral-100)", color: "var(--neutral-10)",
      borderBottom: "2px solid var(--neutral-100)", flexShrink: 0,
    }}>
      <img src="assets/logos/logo-primary-light.svg" alt="HireArt" style={{ height: 22 }} onError={e => e.currentTarget.style.display = "none"} />
      <span style={{ fontFamily: "var(--font-headline)", fontSize: 20, fontWeight: 700, letterSpacing: "0.01em" }}>HireArt</span>
      <div style={{ flex: 1, maxWidth: 480, position: "relative" }}>
        <Icon name="search" size={16} style={{ position: "absolute", left: 12, top: "50%", transform: "translateY(-50%)", color: "var(--neutral-50)" }} />
        <input placeholder="Search for a person or job"
          style={{
            width: "100%", height: 34, padding: "0 12px 0 36px",
            border: "1px solid var(--neutral-80)", borderRadius: 6,
            background: "var(--neutral-90)", color: "var(--neutral-30)",
            fontSize: 14, fontFamily: "var(--font-body)", outline: "none",
          }} />
      </div>
      <Icon name="bell" size={20} style={{ color: "var(--neutral-30)" }} />
      <span style={{
        width: 32, height: 32, borderRadius: 999,
        background: "var(--purple-60)", color: "var(--neutral-10)",
        display: "inline-flex", alignItems: "center", justifyContent: "center",
        fontWeight: 700, fontSize: 12, border: "2px solid var(--neutral-10)",
      }}>WH</span>
    </div>
  );
}

// =============================================================================
// SIDE NAV
// =============================================================================
function SideNav({ activeKey = "reports", onNavigate }) {
  const NAV = [
    { kind: "item", key: "dashboard", label: "Dashboard", icon: "dashboard" },
    { kind: "section", label: "Hiring" },
    { kind: "item", key: "jobs", label: "Jobs", icon: "briefcase" },
    { kind: "item", key: "interviews", label: "Interviews", icon: "calendar" },
    { kind: "section", label: "People" },
    { kind: "item", key: "personnel", label: "Personnel", icon: "user" },
    { kind: "item", key: "payments", label: "One-time payments", icon: "dollar-sign" },
    { kind: "item", key: "time", label: "Time & attendance", icon: "clock" },
    { kind: "item", key: "pto", label: "Paid time off", icon: "umbrella" },
    { kind: "item", key: "documents", label: "Documents", icon: "document" },
    { kind: "item", key: "expenses", label: "Expenses", icon: "credit-card" },
    { kind: "item", key: "reports", label: "Reports", icon: "chart-bar-1" },
  ];
  return (
    <aside style={{
      width: 220, flexShrink: 0,
      background: "var(--neutral-10)",
      borderRight: "1px solid var(--neutral-20)",
      padding: "16px 12px", display: "flex", flexDirection: "column", gap: 4,
      overflowY: "auto",
    }}>
      {NAV.map((item, i) => {
        if (item.kind === "section") {
          return <div key={i} style={{
            fontSize: 11, fontWeight: 700, letterSpacing: "0.1em", textTransform: "uppercase",
            color: "var(--neutral-60)", padding: "16px 10px 6px",
          }}>{item.label}</div>;
        }
        const active = activeKey === item.key;
        return (
          <button key={item.key} onClick={() => onNavigate?.(item.key)} style={{
            display: "flex", alignItems: "center", gap: 10, padding: "8px 10px",
            background: active ? "var(--purple-20)" : "transparent",
            color: active ? "var(--purple-80)" : "var(--neutral-80)",
            border: 0, borderRadius: 6, fontWeight: active ? 600 : 400,
            fontSize: 14, fontFamily: "var(--font-body)", cursor: "pointer",
            textAlign: "left", transition: "background 0.1s",
          }}
          onMouseEnter={e => { if (!active) e.currentTarget.style.background = "var(--neutral-20)"; }}
          onMouseLeave={e => { if (!active) e.currentTarget.style.background = "transparent"; }}>
            <Icon name={item.icon} size={18} />
            <span>{item.label}</span>
          </button>
        );
      })}
    </aside>
  );
}

// =============================================================================
// SHELL
// =============================================================================
function PageShell({ children }) {
  function navigate(key) {
    if (key === "reports") window.location.hash = "#/reports";
    // other nav items are stubs
  }
  return (
    <div style={{
      display: "flex", flexDirection: "column", height: "100vh",
      background: "var(--bg-2)",
    }}>
      <TopBar />
      <div style={{ display: "flex", flex: 1, overflow: "hidden" }}>
        <SideNav activeKey="reports" onNavigate={navigate} />
        <main style={{ flex: 1, overflow: "auto", padding: 32 }}>
          {children}
        </main>
      </div>
    </div>
  );
}

// =============================================================================
// BREADCRUMB
// =============================================================================
function Breadcrumb({ items }) {
  return (
    <nav style={{
      display: "flex", alignItems: "center", gap: 8, marginBottom: 16,
      fontSize: 14, color: "var(--neutral-60)", fontFamily: "var(--font-body)",
    }}>
      {items.map((it, i) => (
        <React.Fragment key={i}>
          {i > 0 && <span style={{ color: "var(--neutral-40)" }}>/</span>}
          {it.href != null ? (
            <a onClick={() => window.location.hash = it.href}
              style={{ color: "var(--neutral-80)", cursor: "pointer", textDecoration: "none" }}>
              {it.label}
            </a>
          ) : (
            <span>{it.label}</span>
          )}
        </React.Fragment>
      ))}
    </nav>
  );
}

// =============================================================================
// FILTER LABEL — uppercase tag above the input
// =============================================================================
function FilterLabel({ children }) {
  return (
    <div style={{
      fontSize: 11, fontWeight: 700, letterSpacing: "0.1em",
      textTransform: "uppercase", color: "var(--neutral-70)", marginBottom: 6,
    }}>{children}</div>
  );
}

// =============================================================================
// SELECT — opens a dropdown panel (always uses popover, never native)
// =============================================================================
function Select({ value, onChange, options, width = 180, renderTrigger }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  useEffect(() => {
    function onClick(e) { if (ref.current && !ref.current.contains(e.target)) setOpen(false); }
    document.addEventListener("mousedown", onClick);
    return () => document.removeEventListener("mousedown", onClick);
  }, []);

  const display = options.find(o => (o.value ?? o) === value)?.label ?? options.find(o => (o.value ?? o) === value) ?? value;

  return (
    <div ref={ref} style={{ position: "relative", width }}>
      <button type="button" onClick={() => setOpen(o => !o)} style={{
        width: "100%", height: 38, padding: "0 36px 0 12px",
        background: "var(--neutral-10)",
        border: "2px solid var(--neutral-100)", borderRadius: 6,
        boxShadow: "var(--shadow-btn-sm)",
        fontFamily: "var(--font-body)", fontSize: 14, fontWeight: 500,
        color: "var(--neutral-100)", textAlign: "left", cursor: "pointer",
        display: "flex", alignItems: "center", whiteSpace: "nowrap",
        overflow: "hidden", textOverflow: "ellipsis",
      }}>
        <span style={{ flex: 1, overflow: "hidden", textOverflow: "ellipsis" }}>{display}</span>
        <Icon name="chevron-down" size={14} style={{ position: "absolute", right: 12, top: "50%", transform: "translateY(-50%)" }} />
      </button>
      {open && (
        <div style={{
          position: "absolute", top: "calc(100% + 6px)", left: 0, minWidth: "100%",
          background: "var(--neutral-10)",
          border: "2px solid var(--neutral-100)", borderRadius: 8,
          boxShadow: "var(--shadow-md)", padding: 4, zIndex: 50,
        }}>
          {options.map((o, i) => {
            const v = o.value ?? o; const l = o.label ?? o;
            const sel = v === value;
            return (
              <div key={i} onClick={() => { onChange?.(v); setOpen(false); }}
                style={{
                  padding: "8px 10px", borderRadius: 4, cursor: "pointer",
                  fontSize: 14, fontWeight: sel ? 600 : 400,
                  color: sel ? "var(--purple-80)" : "var(--neutral-100)",
                  background: sel ? "var(--purple-20)" : "transparent",
                }}
                onMouseEnter={e => { if (!sel) e.currentTarget.style.background = "var(--neutral-20)"; }}
                onMouseLeave={e => { if (!sel) e.currentTarget.style.background = "transparent"; }}>
                {l}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

// =============================================================================
// SEARCHABLE SELECT
// =============================================================================
function SearchSelect({ value, onChange, options, width = 200 }) {
  const [open, setOpen] = useState(false);
  const [q, setQ] = useState("");
  const ref = useRef(null);
  useEffect(() => {
    function onClick(e) { if (ref.current && !ref.current.contains(e.target)) setOpen(false); }
    document.addEventListener("mousedown", onClick);
    return () => document.removeEventListener("mousedown", onClick);
  }, []);
  const filtered = options.filter(o => o.toLowerCase().includes(q.toLowerCase()));
  return (
    <div ref={ref} style={{ position: "relative", width }}>
      <button type="button" onClick={() => setOpen(o => !o)} style={{
        width: "100%", height: 38, padding: "0 36px 0 12px",
        background: "var(--neutral-10)",
        border: "2px solid var(--neutral-100)", borderRadius: 6,
        boxShadow: "var(--shadow-btn-sm)",
        fontFamily: "var(--font-body)", fontSize: 14, fontWeight: 500,
        color: "var(--neutral-100)", textAlign: "left", cursor: "pointer",
        display: "flex", alignItems: "center", whiteSpace: "nowrap",
        overflow: "hidden", textOverflow: "ellipsis",
      }}>
        <span style={{ flex: 1, overflow: "hidden", textOverflow: "ellipsis" }}>{value}</span>
        <Icon name="chevron-down" size={14} style={{ position: "absolute", right: 12, top: "50%", transform: "translateY(-50%)" }} />
      </button>
      {open && (
        <div style={{
          position: "absolute", top: "calc(100% + 6px)", left: 0, width: 280,
          background: "var(--neutral-10)",
          border: "2px solid var(--neutral-100)", borderRadius: 8,
          boxShadow: "var(--shadow-md)", zIndex: 50, overflow: "hidden",
        }}>
          <div style={{ padding: 8, borderBottom: "1px solid var(--neutral-20)", position: "relative" }}>
            <Icon name="search" size={14} style={{ position: "absolute", left: 18, top: "50%", transform: "translateY(-50%)", color: "var(--neutral-50)" }} />
            <input autoFocus value={q} onChange={e => setQ(e.target.value)} placeholder="Search jobs…"
              style={{
                width: "100%", height: 32, padding: "0 8px 0 28px",
                border: "1px solid var(--neutral-30)", borderRadius: 4,
                fontFamily: "var(--font-body)", fontSize: 13, outline: "none",
              }} />
          </div>
          <div style={{ maxHeight: 220, overflowY: "auto", padding: 4 }}>
            {filtered.length === 0 && (
              <div style={{ padding: "10px 12px", fontSize: 13, color: "var(--neutral-60)" }}>No matches</div>
            )}
            {filtered.map((o, i) => {
              const sel = o === value;
              return (
                <div key={i} onClick={() => { onChange?.(o); setOpen(false); setQ(""); }}
                  style={{
                    padding: "8px 10px", borderRadius: 4, cursor: "pointer",
                    fontSize: 14, fontWeight: sel ? 600 : 400,
                    color: sel ? "var(--purple-80)" : "var(--neutral-100)",
                    background: sel ? "var(--purple-20)" : "transparent",
                  }}
                  onMouseEnter={e => { if (!sel) e.currentTarget.style.background = "var(--neutral-20)"; }}
                  onMouseLeave={e => { if (!sel) e.currentTarget.style.background = "transparent"; }}>
                  {o}
                </div>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
}

// =============================================================================
// SEGMENTED TOGGLE — Filter By: Work week / Paycheck date
// =============================================================================
function Segmented({ value, onChange, options }) {
  return (
    <div style={{
      display: "inline-flex", padding: 3, gap: 2,
      border: "2px solid var(--neutral-100)", borderRadius: 6,
      background: "var(--neutral-20)", boxShadow: "var(--shadow-btn-sm)",
    }}>
      {options.map(o => {
        const sel = (o.value ?? o) === value;
        return (
          <button key={o.value ?? o} onClick={() => onChange?.(o.value ?? o)} style={{
            padding: "5px 14px", borderRadius: 4, border: 0, cursor: "pointer",
            background: sel ? "var(--neutral-10)" : "transparent",
            color: sel ? "var(--neutral-100)" : "var(--neutral-70)",
            fontFamily: "var(--font-body)", fontSize: 13, fontWeight: sel ? 700 : 500,
            boxShadow: sel ? "0 1px 0 0 var(--neutral-100)" : "none",
          }}>{o.label ?? o}</button>
        );
      })}
    </div>
  );
}

// =============================================================================
// WEEK PICKER — range-style multi-select
// =============================================================================
function startOfWeek(d) {
  // Monday-start
  const x = new Date(d.getFullYear(), d.getMonth(), d.getDate());
  const day = (x.getDay() + 6) % 7;
  x.setDate(x.getDate() - day);
  return x;
}
function addDays(d, n) { const x = new Date(d); x.setDate(x.getDate() + n); return x; }
function sameDay(a, b) { return a && b && a.getTime() === b.getTime(); }
function fmtWeekLabel(monday) {
  const sun = addDays(monday, 6);
  const M = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
  const sameMonth = monday.getMonth() === sun.getMonth();
  return sameMonth
    ? `${M[monday.getMonth()]} ${monday.getDate()}–${sun.getDate()}, ${sun.getFullYear()}`
    : `${M[monday.getMonth()]} ${monday.getDate()} – ${M[sun.getMonth()]} ${sun.getDate()}, ${sun.getFullYear()}`;
}

function WeekPicker({ value = [], onChange, mode = "range", minDate, maxDate, label }) {
  // value is array of Monday Date objects (sorted)
  const [open, setOpen] = useState(false);
  const [viewMonth, setViewMonth] = useState(() => {
    const d = value[0] || new Date(2026, 2, 1);
    return new Date(d.getFullYear(), d.getMonth(), 1);
  });
  const [pendingStart, setPendingStart] = useState(null); // single-click in range mode
  const ref = useRef(null);

  useEffect(() => {
    function onClick(e) {
      if (ref.current && !ref.current.contains(e.target)) {
        // commit pending single-week selection on close
        if (pendingStart && (!value.length || value[0].getTime() !== pendingStart.getTime() || value.length !== 1)) {
          onChange?.([pendingStart]);
        }
        setPendingStart(null);
        setOpen(false);
      }
    }
    document.addEventListener("mousedown", onClick);
    return () => document.removeEventListener("mousedown", onClick);
  });

  function selectWeek(monday) {
    if (mode === "single") {
      onChange?.([monday]);
      setOpen(false);
      return;
    }
    if (!pendingStart) {
      setPendingStart(monday);
      onChange?.([monday]);
    } else {
      // pendingStart already set → make a range
      const a = pendingStart < monday ? pendingStart : monday;
      const b = pendingStart < monday ? monday : pendingStart;
      const weeks = [];
      for (let m = new Date(a); m.getTime() <= b.getTime(); m = addDays(m, 7)) {
        weeks.push(new Date(m));
      }
      onChange?.(weeks);
      setPendingStart(null);
    }
  }

  function clear() {
    onChange?.([]);
    setPendingStart(null);
  }

  // build calendar grid
  const monthStart = new Date(viewMonth.getFullYear(), viewMonth.getMonth(), 1);
  const gridStart = startOfWeek(monthStart);
  const cells = [];
  for (let i = 0; i < 42; i++) cells.push(addDays(gridStart, i));
  const M = ["January","February","March","April","May","June","July","August","September","October","November","December"];

  const selectedSet = new Set(value.map(d => d.getTime()));

  // Display label
  let triggerText = "Select weeks…";
  if (value.length === 1) triggerText = fmtWeekLabel(value[0]);
  else if (value.length > 1) triggerText = `${fmtWeekLabel(value[0])}  +${value.length - 1} more`;

  return (
    <div ref={ref} style={{ position: "relative", width: 280 }}>
      <button type="button" onClick={() => setOpen(o => !o)} style={{
        width: "100%", height: 38, padding: "0 12px",
        background: "var(--neutral-10)",
        border: "2px solid var(--neutral-100)", borderRadius: 6,
        boxShadow: "var(--shadow-btn-sm)",
        display: "flex", alignItems: "center", gap: 8,
        fontFamily: "var(--font-body)", fontSize: 14, fontWeight: 500,
        color: value.length ? "var(--neutral-100)" : "var(--neutral-60)",
        textAlign: "left", cursor: "pointer",
      }}>
        <Icon name="calendar" size={16} style={{ color: "var(--neutral-80)" }} />
        <span style={{ flex: 1, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{triggerText}</span>
        <Icon name="chevron-down" size={14} />
      </button>
      {open && (
        <div style={{
          position: "absolute", top: "calc(100% + 6px)", left: 0, width: 320,
          background: "var(--neutral-10)",
          border: "2px solid var(--neutral-100)", borderRadius: 8,
          boxShadow: "var(--shadow-md)", padding: 12, zIndex: 60,
        }}>
          {/* header */}
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 8 }}>
            <button type="button" onClick={() => setViewMonth(new Date(viewMonth.getFullYear(), viewMonth.getMonth() - 1, 1))}
              style={{ background: "var(--neutral-10)", border: "1px solid var(--neutral-30)", borderRadius: 4, width: 28, height: 28, cursor: "pointer", display: "inline-flex", alignItems: "center", justifyContent: "center" }}>
              <Icon name="chevron-left" size={14} />
            </button>
            <div style={{ fontFamily: "var(--font-body)", fontSize: 14, fontWeight: 700, color: "var(--neutral-100)" }}>
              {M[viewMonth.getMonth()]} {viewMonth.getFullYear()}
            </div>
            <button type="button" onClick={() => setViewMonth(new Date(viewMonth.getFullYear(), viewMonth.getMonth() + 1, 1))}
              style={{ background: "var(--neutral-10)", border: "1px solid var(--neutral-30)", borderRadius: 4, width: 28, height: 28, cursor: "pointer", display: "inline-flex", alignItems: "center", justifyContent: "center" }}>
              <Icon name="chevron-right" size={14} />
            </button>
          </div>
          {/* day labels */}
          <div style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 0, marginBottom: 4 }}>
            {["M","T","W","T","F","S","S"].map((d, i) => (
              <div key={i} style={{ textAlign: "center", fontSize: 11, fontWeight: 700, color: "var(--neutral-60)", textTransform: "uppercase", letterSpacing: "0.06em", padding: "4px 0" }}>{d}</div>
            ))}
          </div>
          {/* grid (rendered as rows so we can highlight whole weeks) */}
          <div>
            {Array.from({ length: 6 }, (_, w) => {
              const weekStart = cells[w * 7];
              const isSelected = selectedSet.has(weekStart.getTime());
              const isPending = pendingStart && pendingStart.getTime() === weekStart.getTime();
              return (
                <div key={w} onClick={() => {
                    if (minDate && weekStart < minDate) return;
                    if (maxDate && weekStart > maxDate) return;
                    selectWeek(weekStart);
                  }}
                  style={{
                    display: "grid", gridTemplateColumns: "repeat(7, 1fr)",
                    cursor: "pointer", borderRadius: 4, marginBottom: 2,
                    background: isSelected ? "var(--purple-20)" : "transparent",
                    border: isPending && !isSelected ? "1px dashed var(--purple-60)" : "1px solid transparent",
                  }}
                  onMouseEnter={e => { if (!isSelected) e.currentTarget.style.background = "var(--neutral-20)"; }}
                  onMouseLeave={e => { if (!isSelected) e.currentTarget.style.background = "transparent"; }}>
                  {Array.from({ length: 7 }, (_, dIdx) => {
                    const d = cells[w * 7 + dIdx];
                    const inMonth = d.getMonth() === viewMonth.getMonth();
                    const disabled = (minDate && d < minDate) || (maxDate && d > maxDate);
                    return (
                      <div key={dIdx} style={{
                        textAlign: "center", padding: "6px 0", fontSize: 13,
                        fontFamily: "var(--font-body)",
                        color: disabled ? "var(--neutral-30)" :
                               isSelected ? "var(--purple-80)" :
                               inMonth ? "var(--neutral-100)" : "var(--neutral-50)",
                        fontWeight: isSelected ? 700 : 400,
                      }}>
                        {d.getDate()}
                      </div>
                    );
                  })}
                </div>
              );
            })}
          </div>
          {/* footer */}
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: 10, paddingTop: 10, borderTop: "1px solid var(--neutral-20)" }}>
            <span style={{ fontSize: 12, color: "var(--neutral-60)" }}>
              {value.length === 0 ? "No weeks selected" :
               value.length === 1 ? "1 week selected" :
               `${value.length} weeks selected`}
            </span>
            <button type="button" onClick={clear} style={{
              background: "transparent", border: 0, color: "var(--purple-60)",
              fontSize: 13, fontWeight: 600, cursor: "pointer", padding: "4px 8px",
              fontFamily: "var(--font-body)",
            }}>Clear</button>
          </div>
        </div>
      )}
    </div>
  );
}

// =============================================================================
// FILTER BAR
// =============================================================================
function FilterBar({ report, filters, setFilters }) {
  const showWeekPicker = filters.period === "custom";
  return (
    <div style={{
      display: "flex", gap: 16, alignItems: "flex-end", flexWrap: "wrap",
      padding: "20px 24px", borderBottom: "1px solid var(--neutral-20)",
      background: "var(--neutral-10)",
    }}>
      <div>
        <FilterLabel>Period</FilterLabel>
        <Select value={filters.period} onChange={v => setFilters({ ...filters, period: v })}
          options={PERIOD_OPTIONS} width={170} />
      </div>

      {showWeekPicker && (
        <div>
          <FilterLabel>Weeks</FilterLabel>
          <WeekPicker
            value={filters.weeks || []}
            onChange={v => setFilters({ ...filters, weeks: v })}
            mode={report.weekPickerMode || "range"}
            minDate={new Date(2024, 7, 12)}
            maxDate={new Date(2026, 3, 19)}
          />
        </div>
      )}

      {report.hasFilterByToggle && (
        <div>
          <FilterLabel>Filter by</FilterLabel>
          <Segmented value={filters.filterBy || "work_week"}
            onChange={v => setFilters({ ...filters, filterBy: v })}
            options={[{ value: "work_week", label: "Work week" }, { value: "paycheck_date", label: "Paycheck date" }]} />
        </div>
      )}

      {report.hasJob && (
        <div>
          <FilterLabel>Job title</FilterLabel>
          <SearchSelect value={filters.job || "All jobs"}
            onChange={v => setFilters({ ...filters, job: v })}
            options={JOB_OPTIONS} width={220} />
        </div>
      )}

      {report.hasLocation && (
        <div>
          <FilterLabel>Location</FilterLabel>
          <Select value={filters.location || "All locations"}
            onChange={v => setFilters({ ...filters, location: v })}
            options={LOCATION_OPTIONS} width={200} />
        </div>
      )}

      <div style={{ flex: 1 }} />
      <Button color="secondary" size="md" iconStart="download-1">Download</Button>
    </div>
  );
}

// =============================================================================
// ONBOARDING STATUS BADGE
// =============================================================================
function OnboardingBadge({ status }) {
  const map = {
    complete:    { label: "Complete",    bg: "var(--green-20)",   fg: "var(--green-100)",   border: "var(--green-80)" },
    in_progress: { label: "In progress", bg: "var(--blue-20)",    fg: "var(--blue-100)",    border: "var(--blue-80)" },
    pending:     { label: "Pending",     bg: "var(--yellow-20)",  fg: "var(--yellow-100)",  border: "var(--yellow-80)" },
    not_started: { label: "Not started", bg: "var(--neutral-20)", fg: "var(--neutral-80)",  border: "var(--neutral-60)" },
    n_a:         { label: "N/A",         bg: "transparent",       fg: "var(--neutral-50)",  border: "var(--neutral-30)" },
  };
  const c = map[status] || map.not_started;
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", padding: "1px 8px",
      borderRadius: 100, border: `1.5px solid ${c.border}`,
      background: c.bg, color: c.fg,
      fontSize: 11, fontWeight: 700, letterSpacing: "0.04em",
      textTransform: "uppercase", whiteSpace: "nowrap",
      fontFamily: "var(--font-body)",
    }}>{c.label}</span>
  );
}

// =============================================================================
// DATA TABLE — handles native types via Formatter, sortable, hover, sticky head
// =============================================================================
function DataTable({ columns, rows, sortKey, sortDir, onSort, masking = false, isOnboarding = false }) {
  return (
    <div style={{ overflowX: "auto", background: "var(--neutral-10)" }}>
      <table style={{ width: "100%", borderCollapse: "collapse", fontFamily: "var(--font-body)" }}>
        <thead>
          <tr style={{ background: "var(--neutral-10)" }}>
            {columns.map((c, i) => {
              const isSorted = c.sortable && sortKey === c.name;
              return (
                <th key={i} onClick={() => c.sortable && onSort?.(c.name)}
                  style={{
                    textAlign: c.align === "right" ? "right" : "left",
                    padding: "10px 16px",
                    fontSize: 11, fontWeight: 700, letterSpacing: "0.08em",
                    textTransform: "uppercase", color: "var(--neutral-70)",
                    background: "var(--bg-2)",
                    borderBottom: "2px solid var(--neutral-100)",
                    whiteSpace: "nowrap", position: "sticky", top: 0, zIndex: 1,
                    cursor: c.sortable ? "pointer" : "default",
                    userSelect: "none",
                  }}>
                  <span style={{ display: "inline-flex", alignItems: "center", gap: 4 }}>
                    {c.name}
                    {c.sortable && (
                      <span style={{ opacity: isSorted ? 1 : 0.3, color: isSorted ? "var(--purple-80)" : "currentColor", fontSize: 10 }}>
                        {isSorted ? (sortDir === "desc" ? "↓" : "↑") : "↕"}
                      </span>
                    )}
                  </span>
                </th>
              );
            })}
          </tr>
        </thead>
        <tbody>
          {rows.map((row, ri) => (
            <tr key={ri}
              style={{ borderBottom: "1px solid var(--neutral-20)" }}
              onMouseEnter={e => e.currentTarget.style.background = "color-mix(in srgb, var(--purple-20) 35%, transparent)"}
              onMouseLeave={e => e.currentTarget.style.background = "transparent"}>
              {columns.map((c, ci) => {
                const v = row[ci];
                const isMasked = masking && c.sensitive;
                const numeric = c.type === "numeric" || c.type === "integer";
                const tabular = numeric || c.type === "date" || c.type === "timestamp";
                const isFirst = ci === 0;

                let content;
                if (isOnboarding && c.type === "status") {
                  content = <OnboardingBadge status={v} />;
                } else {
                  const r = fmtCell(v, c.name, c.type, isMasked);
                  if (r.masked) {
                    content = <span title="Hidden — you don't have permission to view this value." style={{ color: "var(--neutral-50)", borderBottom: "1.5px dotted var(--neutral-40)", paddingBottom: 1, cursor: "help" }}>—</span>;
                  } else {
                    content = r.display;
                  }
                }

                return (
                  <td key={ci} style={{
                    padding: "12px 16px",
                    textAlign: c.align === "right" ? "right" : "left",
                    fontSize: 14, color: "var(--neutral-100)",
                    fontWeight: isFirst ? 600 : 400,
                    fontVariantNumeric: tabular ? "tabular-nums lining-nums" : "normal",
                    whiteSpace: "nowrap",
                  }}>{content}</td>
                );
              })}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

// =============================================================================
// LOADING / EMPTY / ERROR STATES
// =============================================================================
function LoadingTable({ columns }) {
  const rows = 5;
  return (
    <div style={{ overflowX: "auto", background: "var(--neutral-10)" }}>
      <table style={{ width: "100%", borderCollapse: "collapse" }}>
        <thead>
          <tr>
            {columns.map((c, i) => (
              <th key={i} style={{
                textAlign: c.align === "right" ? "right" : "left",
                padding: "10px 16px", fontSize: 11, fontWeight: 700,
                letterSpacing: "0.08em", textTransform: "uppercase",
                color: "var(--neutral-70)", background: "var(--bg-2)",
                borderBottom: "2px solid var(--neutral-100)",
                whiteSpace: "nowrap",
              }}>{c.name}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {Array.from({ length: rows }).map((_, ri) => (
            <tr key={ri} style={{ borderBottom: "1px solid var(--neutral-20)" }}>
              {columns.map((c, ci) => (
                <td key={ci} style={{ padding: "14px 16px", textAlign: c.align === "right" ? "right" : "left" }}>
                  <span className="skeleton-shimmer" style={{
                    display: "inline-block",
                    width: c.align === "right" ? 60 : (ci === 0 ? 140 : 90),
                    height: 12, borderRadius: 3,
                    background: "linear-gradient(90deg, var(--neutral-20) 0%, var(--neutral-30) 50%, var(--neutral-20) 100%)",
                    backgroundSize: "200% 100%",
                    animation: "shimmer 1.4s ease-in-out infinite",
                  }} />
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function EmptyTableBody({ columns, title, subtitle }) {
  return (
    <div style={{ background: "var(--neutral-10)" }}>
      <table style={{ width: "100%", borderCollapse: "collapse" }}>
        <thead>
          <tr>
            {columns.map((c, i) => (
              <th key={i} style={{
                textAlign: c.align === "right" ? "right" : "left",
                padding: "10px 16px", fontSize: 11, fontWeight: 700,
                letterSpacing: "0.08em", textTransform: "uppercase",
                color: "var(--neutral-70)", background: "var(--bg-2)",
                borderBottom: "2px solid var(--neutral-100)",
                whiteSpace: "nowrap",
              }}>{c.name}</th>
            ))}
          </tr>
        </thead>
      </table>
      <div style={{
        padding: "64px 24px", textAlign: "center",
        fontFamily: "var(--font-body)",
      }}>
        <div style={{ fontFamily: "var(--font-headline)", fontSize: 18, fontWeight: 700, color: "var(--neutral-100)", marginBottom: 4 }}>
          {title}
        </div>
        <div style={{ fontSize: 14, color: "var(--neutral-70)" }}>{subtitle}</div>
      </div>
    </div>
  );
}

Object.assign(window, {
  PageShell, Breadcrumb, FilterBar, FilterLabel, Select, SearchSelect,
  Segmented, WeekPicker, DataTable, OnboardingBadge,
  LoadingTable, EmptyTableBody, fmtWeekLabel,
});
})();
