/* ===== admin-shell.jsx — sidebar, topbar, primitives ===== */

const NAV = [
  { key: "dashboard", name: "Töölaud",     en: "Dashboard",    icon: "home",     sec: "PÕHIVAADE" },
  { key: "projects",  name: "Projektid",   en: "Projects",     icon: "folder",   sec: "PÕHIVAADE" },
  { key: "register",  name: "Puuraugud",   en: "Register",     icon: "table",    sec: "PÕHIVAADE" },
  { key: "analysis",  name: "Analüüs",     en: "Analysis",     icon: "activity", sec: "PÕHIVAADE" },
  { key: "request",   name: "Andmepäring", en: "Data request", icon: "target",   sec: "VÄLJAVÕTE" },
  { key: "progress",  name: "Edenemine",   en: "Progress",     icon: "sliders",  sec: "JÄLGIMINE" },
  { key: "process",   name: "Protsess",    en: "Process",      icon: "layers",   sec: "JÄLGIMINE" },
];

function Sidebar({ active, onNav, me, onPickUser }) {
  const secs = [];
  NAV.forEach((n) => {
    let s = secs.find((x) => x.cap === n.sec);
    if (!s) { s = { cap: n.sec, items: [] }; secs.push(s); }
    s.items.push(n);
  });
  return (
    <aside className="sidebar">
      <div className="side-logo">
        <RPLogo height={24} />
        <div className="side-wm"><b>RP Geolog</b><span>ADMIN</span></div>
      </div>
      <div className="side-sep" />
      <nav className="side-nav">
        {secs.map((s) => (
          <React.Fragment key={s.cap}>
            <div className="side-cap">{s.cap}</div>
            {s.items.map((n) => (
              <button key={n.key} className={"side-item" + (active === n.key ? " on" : "")} onClick={() => onNav(n.key)}>
                <Icon name={n.icon} size={18} />{n.name}
                {n.key === "register" && <span className="badge-n">{totalHoles()}</span>}
                {n.key === "projects" && <span className="badge-n">{PROJECTS.length}</span>}
              </button>
            ))}
          </React.Fragment>
        ))}
        {(RPStore.can(me, "console") || RPStore.can(me, "users")) && (
          <React.Fragment>
            <div className="side-cap">HALDUS</div>
            <button className={"side-item" + (active === "materials" ? " on" : "")} onClick={() => onNav("materials")}>
              <Icon name="droplet" size={18} />Materjalid
              <span className="badge-n">{(window.FIELD_MATERIALS || []).length}</span>
            </button>
            {RPStore.can(me, "users") && (
              <button className={"side-item" + (active === "users" ? " on" : "")} onClick={() => onNav("users")}>
                <Icon name="user" size={18} />Kasutajad
                <span className="badge-n">{(window.USERS || []).length}</span>
              </button>
            )}
          </React.Fragment>
        )}
        <div className="side-cap">ABI</div>
        <a className="side-item" href="toovoog.html" target="_blank" rel="noopener"
          style={{ textDecoration: "none" }}>
          <Icon name="map" size={18} />Töövoo juhend
        </a>
        <a className="side-item" href="m.html" target="_blank" rel="noopener"
          style={{ textDecoration: "none" }}>
          <Icon name="drill" size={18} />Välirakendus
        </a>
      </nav>
      <UserSwitch me={me} onPick={onPickUser} />
    </aside>
  );
}

function GlobalSearch({ onOpen }) {
  const [q, setQ] = useState("");
  const [focus, setFocus] = useState(false);
  const needle = q.trim().toLowerCase();
  const hits = needle
    ? BOREHOLE_ITEMS.filter((b) => b.id.toLowerCase().includes(needle) || b.projectCode.toLowerCase().includes(needle) || b.projectName.toLowerCase().includes(needle)).slice(0, 8)
    : [];
  return (
    <div className="topsearch" onBlur={() => setTimeout(() => setFocus(false), 150)}>
      <Icon name="search" size={17} />
      <input placeholder="Otsi puurauku, projekti või koodi…" value={q}
        onChange={(e) => setQ(e.target.value)} onFocus={() => setFocus(true)} />
      {focus && needle && (
        <div className="results">
          {hits.length === 0 && <div className="res-empty">Vastet ei leitud “{q}”.</div>}
          {hits.map((b, i) => {
            const st = STAGES[b.stage];
            return (
              <button key={i} className="res" onMouseDown={() => { onOpen(b); setQ(""); }}>
                <span className={"kindtag" + (b.type === "TP" ? " tp" : b.type === "CP" ? " cp" : "")}>{b.type}</span>
                <span style={{ flex: 1, minWidth: 0 }}>
                  <span className="mono" style={{ fontWeight: 600 }}>{b.id}</span>
                  <span className="cellsub">{b.projectCode}{b.projectShort ? "_" + b.projectShort : ""} · {b.projectName}</span>
                </span>
                <span className="badge" style={{ color: st.hex, background: "transparent", borderColor: "var(--border)" }}>
                  <span className="dot" style={{ background: st.hex }} />{st.short}
                </span>
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
}

function Topbar({ crumbs, actions, onSearchOpen, dark, onToggleTheme }) {
  return (
    <header className="topbar">
      <div className="crumbs">
        {crumbs.map((c, i) => (
          <React.Fragment key={i}>
            {i > 0 && <Icon name="chevron" size={14} />}
            {i === crumbs.length - 1 ? <b>{c}</b> : <span>{c}</span>}
          </React.Fragment>
        ))}
      </div>
      <GlobalSearch onOpen={onSearchOpen} />
      <button className="topbtn icon" title={dark ? "Hele režiim" : "Tume režiim"} onClick={onToggleTheme}>
        <Icon name={dark ? "sun" : "moon"} size={17} />
      </button>
      <button className="topbtn icon" title="Teavitused"><Icon name="bell" size={17} /></button>
      {actions}
    </header>
  );
}

/* ---- searchable project picker (built for hundreds of contracts) ----
   Teams know their contract number (GL + yy + nnn), so search is primary:
   typing "GL25…" narrows instantly. With no query: recently opened +
   contracts that actually have unassigned analysis work. */
function projUnassigned(pid) {
  let n = 0;
  (BOREHOLES[pid] || []).forEach((b) => {
    const l = SAMPLE_LOG[b.id];
    if (l && l.geos && l.geos.some((g) => !g.mat)) n += 1;
  });
  return n;
}

function readRecentProjects() {
  try { return JSON.parse(localStorage.getItem("rpAnaRecent") || "[]"); } catch (e) { return []; }
}

function writeRecentProject(id) {
  if (!id || id === "all") return;
  try {
    const r = [id].concat(readRecentProjects().filter((x) => x !== id)).slice(0, 6);
    localStorage.setItem("rpAnaRecent", JSON.stringify(r));
  } catch (e) { }
}

function ProjectPicker({ value, onChange }) {
  const [open, setOpen] = useState(false);
  const [q, setQ] = useState("");
  const inRef = useRef(null);
  const cur = PROJECTS.find((p) => p.id === value);

  useEffect(() => { if (open && inRef.current) inRef.current.focus(); }, [open]);

  const pick = (p) => {
    writeRecentProject(p.id);
    onChange(p.id); setOpen(false); setQ("");
  };

  const needle = q.trim().toLowerCase();
  let sections = [];
  if (needle) {
    const hits = PROJECTS.filter((p) =>
      (projLabel(p) + " " + p.name + " " + (p.location || "") + " " + (p.client || "")).toLowerCase().includes(needle)
    ).slice(0, 12);
    sections = [{ cap: hits.length ? hits.length + " vastet" : "Tulemused", items: hits }];
  } else {
    const rec = readRecentProjects().map((id) => PROJECTS.find((p) => p.id === id)).filter(Boolean).filter((p) => p.id !== value).slice(0, 4);
    const act = PROJECTS.filter((p) => projUnassigned(p.id) > 0 && p.id !== value && !rec.some((r) => r.id === p.id)).slice(0, 6);
    if (rec.length) sections.push({ cap: "Viimati avatud", items: rec });
    if (act.length) sections.push({ cap: "Analüüsi ootel", items: act });
    if (!sections.length) sections.push({ cap: "Projektid", items: PROJECTS.slice(0, 8) });
  }

  return (
    <div className="ppick">
      <button className="ppick-btn" onClick={() => setOpen(!open)} title={cur ? cur.name : ""}>
        <Icon name="search" size={15} />
        <span className="mono ppick-code">{cur ? projLabel(cur) : "Otsi / vali projekt"}</span>
        <span className={"ppick-chev" + (open ? " up" : "")}><Icon name="chevron" size={14} stroke={2.4} /></span>
      </button>
      {open && (
        <React.Fragment>
          <div className="ppick-scrim" onClick={() => setOpen(false)}></div>
          <div className="ppick-pop">
            <div className="ppick-search">
              <Icon name="search" size={15} />
              <input ref={inRef} placeholder="Otsi numbri järgi: GL26… või nime järgi" value={q}
                onChange={(e) => setQ(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === "Enter") { const f = sections[0] && sections[0].items[0]; if (f) pick(f); }
                  if (e.key === "Escape") setOpen(false);
                }} />
            </div>
            <div className="ppick-list">
              {sections.map((s) => (
                <div key={s.cap}>
                  <div className="ppick-cap">{s.cap}</div>
                  {s.items.map((p) => {
                    const n = projUnassigned(p.id);
                    return (
                      <button key={p.id} className={"ppick-row" + (p.id === value ? " on" : "")} onClick={() => pick(p)}>
                        <span className="mono ppick-rcode">{projLabel(p)}</span>
                        <span className="ppick-rname">{p.name}{p.location ? " · " + p.location : ""}</span>
                        {n > 0
                          ? <span className="badge amber" style={{ flex: "none" }}><span className="dot"></span>{n} PA</span>
                          : <StatusBadge status={p.status} />}
                      </button>
                    );
                  })}
                  {s.items.length === 0 && <div className="ppick-none">Vastet ei leitud “{q}”.</div>}
                </div>
              ))}
            </div>
          </div>
        </React.Fragment>
      )}
    </div>
  );
}

/* ---- primitives ---- */
function KPI({ icon, tone, n, label, sub }) {
  return (
    <div className="kpi">
      <div className="kpi-top">
        <div className={"kpi-ico" + (tone ? " " + tone : "")}><Icon name={icon} size={18} /></div>
      </div>
      <div className="kpi-n">{n}</div>
      <div className="kpi-label">{label}</div>
      {sub && <div className="kpi-sub">{sub}</div>}
    </div>
  );
}

function Panel({ title, sub, action, children, className, bodyFlush }) {
  return (
    <section className={"panel" + (className ? " " + className : "")}>
      {(title || action) && (
        <div className="panel-head">
          <div>{title && <h3>{title}</h3>}{sub && <div className="ph-sub">{sub}</div>}</div>
          {action}
        </div>
      )}
      <div className={"panel-body" + (bodyFlush ? " flush" : "")}>{children}</div>
    </section>
  );
}

/* stacked stage progress bar */
function StageBar({ projectId, width = 120, showPct = true }) {
  const t = stageTotals(projectId);
  const tot = t.reduce((a, b) => a + b, 0) || 1;
  const pct = Math.round(overallProgress(projectId) * 100);
  return (
    <div className="mini-prog">
      <div className="mini-track" style={{ width }}>
        {t.map((c, i) => c > 0 && <span key={i} className="mini-seg" style={{ width: (c / tot * 100) + "%", background: STAGES[i].hex }} title={STAGES[i].name + ": " + c} />)}
      </div>
      {showPct && <span className="mini-pct">{pct}%</span>}
    </div>
  );
}

/* right-side drawer */
function Drawer({ title, sub, onClose, children, foot }) {
  return (
    <div className="scrim" onClick={onClose}>
      <div className="drawer fade-in" onClick={(e) => e.stopPropagation()} style={{ animationName: "none" }}>
        <div className="drawer-head">
          <div><h2>{title}</h2>{sub && <p>{sub}</p>}</div>
          <button className="iconbtn" onClick={onClose} aria-label="Sulge"><Icon name="x" size={20} /></button>
        </div>
        <div className="drawer-body">{children}</div>
        {foot && <div className="drawer-foot">{foot}</div>}
      </div>
    </div>
  );
}

Object.assign(window, { NAV, Sidebar, Topbar, GlobalSearch, KPI, Panel, StageBar, Drawer, ProjectPicker, projUnassigned, readRecentProjects, writeRecentProject });
