/* ============================================================
   Shared UI primitives — exported to window for all pages.
   Built on the Molly Maid design system tokens.
   ============================================================ */
const { useState, useRef, useEffect, useLayoutEffect } = React;

/* ---------- Info tooltip: a small "i" that explains a metric ----------
   Keyboard + hover + tap accessible. Plain-language help everywhere
   so the dashboard reads the same for a 30- or 70-year-old. */
function InfoDot({ text, label }) {
  const [open, setOpen] = useState(false);
  const [pos, setPos] = useState(null);
  const ref = useRef(null);
  const btnRef = useRef(null);
  useEffect(() => {
    function onDoc(e) {if (ref.current && !ref.current.contains(e.target)) setOpen(false);}
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, []);
  // Position the tooltip with fixed coordinates so it escapes any card's
  // overflow:hidden and stays fully on-screen at every size. Flips below
  // the dot when there isn't room above.
  useLayoutEffect(() => {
    if (!open || !btnRef.current) return;
    function place() {
      const r = btnRef.current.getBoundingClientRect();
      const vw = window.innerWidth;
      const below = r.top < 170;
      const cx = Math.max(160, Math.min(vw - 160, r.left + r.width / 2));
      setPos({ left: cx, top: below ? r.bottom + 9 : r.top - 9, below });
    }
    place();
    window.addEventListener("scroll", place, true);
    window.addEventListener("resize", place);
    return () => {
      window.removeEventListener("scroll", place, true);
      window.removeEventListener("resize", place);
    };
  }, [open]);
  return (
    <span className="infodot" ref={ref}
    onMouseEnter={() => setOpen(true)} onMouseLeave={() => setOpen(false)}>
      <button type="button" ref={btnRef} className="infodot-btn" aria-label={label || "More information"}
      aria-expanded={open} onClick={() => setOpen((v) => !v)}
      onFocus={() => setOpen(true)} onBlur={() => setOpen(false)}>i</button>
      {open && pos &&
      <span className={"infodot-pop fixed" + (pos.below ? " below" : "")} role="tooltip"
      style={{ left: pos.left + "px", top: pos.top + "px" }}>{text}</span>
      }
    </span>);

}

/* ---------- Card shell ---------- */
function Card({ title, eyebrow, sub, info, right, children, className, pad = true, style }) {
  return (
    <section className={"card" + (className ? " " + className : "")} style={style}>
      {(title || eyebrow || right) &&
      <header className="card-head">
          <div className="card-head-text">
            {eyebrow && <div className="eyebrow">{eyebrow}</div>}
            {title &&
          <h3 className="card-title">{title}{info && <InfoDot text={info} />}</h3>
          }
            {sub && <p className="card-sub">{sub}</p>}
          </div>
          {right && <div className="card-head-right">{right}</div>}
        </header>
      }
      <div className={pad ? "card-body" : "card-body nopad"}>{children}</div>
    </section>);

}

/* ---------- Segmented control (metric switch, etc.) ---------- */
function Segmented({ options, value, onChange, size }) {
  return (
    <div className={"seg" + (size === "sm" ? " seg-sm" : "")} role="group">
      {options.map((o) =>
      <button key={o.value} type="button"
      aria-pressed={value === o.value}
      className="seg-btn"
      onClick={() => onChange(o.value)}>
          {o.icon && <span className="seg-ic">{o.icon}</span>}{o.label}
        </button>
      )}
    </div>);

}

/* ---------- FBC multi-select filter ---------- */
function FbcFilter({ fbcs, selected, onChange, disabled, note }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  useEffect(() => {
    function onDoc(e) {if (ref.current && !ref.current.contains(e.target)) setOpen(false);}
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, []);
  const all = selected.length === 0 || selected.length === fbcs.length;
  function toggle(id) {
    let next;
    if (selected.indexOf(id) >= 0) next = selected.filter((x) => x !== id);else
    next = selected.concat(id);
    if (next.length === fbcs.length) next = [];
    onChange(next);
  }
  const label = all ? "All FBCs (whole system)" :
  selected.length === 1 ? fbcs.find((f) => f.id === selected[0]).name :
  selected.length + " FBCs selected";
  return (
    <div className={"fbcfilter" + (disabled ? " is-disabled" : "")} ref={ref}>
      <button type="button" className="fbcfilter-btn" onClick={() => !disabled && setOpen((v) => !v)}
      aria-expanded={open} disabled={disabled} data-comment-anchor="a40a96159c-button-88-7">
        <span className="fbcfilter-ic" aria-hidden="true">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M22 21v-2a4 4 0 0 0-3-3.87" /><path d="M16 3.13a4 4 0 0 1 0 7.75" /><circle cx="9" cy="7" r="4" /><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /></svg>
        </span>
        <span className="fbcfilter-label">{label}</span>
        <span className="chev" aria-hidden="true">▾</span>
      </button>
      {note && <span className="fbcfilter-note">{note}</span>}
      {open && !disabled &&
      <div className="fbcfilter-menu" role="menu">
          <button type="button" className={"fbcfilter-opt" + (all ? " on" : "")}
        onClick={() => onChange([])}>
            <span className="fbcfilter-check">{all ? "✓" : ""}</span>
            <span className="fbcdot" style={{ background: "var(--mly-navy)" }}></span>
            All FBCs — whole system
          </button>
          <div className="fbcfilter-div"></div>
          {fbcs.map((f) => {
          const on = !all && selected.indexOf(f.id) >= 0;
          return (
            <button key={f.id} type="button" className={"fbcfilter-opt" + (on ? " on" : "")}
            onClick={() => toggle(f.id)} role="menuitemcheckbox" aria-checked={on}>
                <span className="fbcfilter-check">{on ? "✓" : ""}</span>
                <span className="fbcdot" style={{ background: f.color }}></span>
                {f.name}<span className="fbcfilter-region">{f.region}</span>
              </button>);

        })}
        </div>
      }
    </div>);

}

/* ---------- KPI stat block ---------- */
function Stat({ label, value, delta, deltaTone, sub, info }) {
  return (
    <div className="stat">
      <div className="stat-label">{label}{info && <InfoDot text={info} />}</div>
      <div className="stat-value">{value}</div>
      {(delta || sub) &&
      <div className="stat-meta">
          {delta && <span className={"stat-delta tone-" + (deltaTone || "neutral")}>{delta}</span>}
          {sub && <span className="stat-sub">{sub}</span>}
        </div>
      }
    </div>);

}

/* ---------- Progress bar with target marker ---------- */
function Progress({ value, max, tone = "info", marker, markerLabel, height = 10 }) {
  const pct = Math.max(0, Math.min(100, value / max * 100));
  return (
    <div className="prog" style={{ height }}>
      <div className={"prog-fill grad-" + tone} style={{ width: pct + "%" }}></div>
      {marker != null &&
      <div className="prog-marker" style={{ left: Math.min(100, marker / max * 100) + "%" }}
      tabIndex={0} title={markerLabel || "Target / pace"}>
        {markerLabel && <span className="ref-tip">{markerLabel}</span>}
      </div>
      }
    </div>);

}

/* ---------- Status pill ---------- */
function Pill({ tone = "neutral", children, soft }) {
  return <span className={"pill tone-" + tone + (soft ? " soft" : "")} data-comment-anchor="ff75668e28-span-155-10">{children}</span>;
}

/* ---------- A clearly-marked placeholder for data we don't have yet ---------- */
function Placeholder({ children }) {
  return (
    <span className="ph" title="Placeholder — will be populated from live data">
      <span className="ph-dot" aria-hidden="true"></span>{children}
    </span>);

}

/* ---------- tiny FBC dot+name tag ---------- */
function FbcTag({ id }) {
  const f = MM.fbcs.find((x) => x.id === id);
  if (!f) return null;
  return <span className="fbctag"><span className="fbcdot" style={{ background: f.color }}></span>{f.name}</span>;
}

Object.assign(window, { InfoDot, Card, Segmented, FbcFilter, Stat, Progress, Pill, Placeholder, FbcTag });