// Atlubni Docs — App shell, router, command palette, try-it drawer, tweaks
const { useState: useS, useEffect: useE, useRef: useR, useMemo: useMm, useCallback: useCb } = React;

// ============ COMMAND PALETTE ============
const CommandPalette = ({ open, onClose, t, lang, onGo }) => {
  const [q, setQ] = useS("");
  const [active, setActive] = useS(0);
  const [recent, setRecent] = useS(() => {
    try { return JSON.parse(localStorage.getItem("atl_docs_recent") || "[]"); } catch { return []; }
  });
  const inputRef = useR(null);

  useE(() => {
    if (open) { setTimeout(() => inputRef.current?.focus(), 30); setQ(""); setActive(0); }
  }, [open]);

  const idx = window.__DOCS_SEARCH;
  const filtered = useMm(() => {
    if (!q.trim()) return [];
    const ql = q.toLowerCase();
    return idx.filter(it => it.title.toLowerCase().includes(ql) || it.crumb.toLowerCase().includes(ql) || it.id.toLowerCase().includes(ql)).slice(0, 18);
  }, [q]);

  const grouped = useMm(() => {
    const groups = { page: [], endpoint: [], error: [], guide: [] };
    filtered.forEach(r => groups[r.kind]?.push(r));
    return groups;
  }, [filtered]);

  const flat = filtered.length ? filtered : recent;

  const select = (item) => {
    const newRecent = [item, ...recent.filter(r => r.id !== item.id)].slice(0, 6);
    setRecent(newRecent);
    try { localStorage.setItem("atl_docs_recent", JSON.stringify(newRecent)); } catch {}
    onGo(item.id.split("#")[0], item.id.includes("#") ? item.id.split("#")[1] : null);
    onClose();
  };

  useE(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === "Escape") { e.preventDefault(); onClose(); }
      else if (e.key === "ArrowDown") { e.preventDefault(); setActive(a => Math.min(a + 1, flat.length - 1)); }
      else if (e.key === "ArrowUp") { e.preventDefault(); setActive(a => Math.max(a - 1, 0)); }
      else if (e.key === "Enter" && flat[active]) { e.preventDefault(); select(flat[active]); }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open, flat, active]);

  if (!open) return null;

  const highlight = (text) => {
    if (!q.trim()) return text;
    const re = new RegExp(`(${q.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})`, "gi");
    const parts = text.split(re);
    return parts.map((p, i) => re.test(p) ? <mark key={i}>{p}</mark> : p);
  };

  const groupOrder = [["page", t.groupPages], ["endpoint", t.groupEndpoints], ["error", t.groupErrors], ["guide", t.groupGuides]];
  let runningIdx = 0;

  return (
    <div className="cp-backdrop" onClick={onClose}>
      <div className="cp-modal" onClick={e => e.stopPropagation()} role="dialog" aria-modal="true">
        <div className="cp-input-wrap">
          <DocIcon name="search" size={16} className="" />
          <input ref={inputRef} value={q} onChange={e => { setQ(e.target.value); setActive(0); }} placeholder={t.searchPh} dir={lang === "ar" ? "rtl" : "ltr"} />
          <span className="kbd">esc</span>
        </div>
        <div className="cp-results">
          {!q.trim() && recent.length === 0 && (
            <div className="cp-empty">
              <div>{lang === "ar" ? "ابدأ بالكتابة للبحث" : "Start typing to search"}</div>
              <div className="sub">{lang === "ar" ? "صفحات، نقاط، أخطاء، أدلّة" : "pages · endpoints · errors · guides"}</div>
            </div>
          )}
          {!q.trim() && recent.length > 0 && (
            <>
              <div className="cp-group-title">{t.cpRecent}</div>
              {recent.map((r, i) => {
                const ai = runningIdx++;
                return (
                  <div key={r.id} className={`cp-result ${ai === active ? "active" : ""}`} onClick={() => select(r)} onMouseEnter={() => setActive(ai)}>
                    <div className="ttl"><DocIcon name={r.kind === "endpoint" ? "code" : r.kind === "error" ? "alert-tri" : r.kind === "guide" ? "book" : "doc"} size={12}/> {r.title}</div>
                    <div className="crumb">{r.crumb}</div>
                  </div>
                );
              })}
            </>
          )}
          {q.trim() && filtered.length === 0 && (
            <div className="cp-empty">
              <div>{t.cpEmpty}</div>
              <div className="sub">{t.cpEmptySub}</div>
            </div>
          )}
          {q.trim() && groupOrder.map(([k, label]) => {
            const items = grouped[k];
            if (!items || items.length === 0) return null;
            return (
              <div key={k}>
                <div className="cp-group-title">{label}</div>
                {items.map(r => {
                  const ai = runningIdx++;
                  return (
                    <div key={r.id} className={`cp-result ${ai === active ? "active" : ""}`} onClick={() => select(r)} onMouseEnter={() => setActive(ai)}>
                      <div className="ttl"><DocIcon name={r.kind === "endpoint" ? "code" : r.kind === "error" ? "alert-tri" : r.kind === "guide" ? "book" : "doc"} size={12}/> {highlight(r.title)}</div>
                      <div className="crumb">{r.crumb}</div>
                    </div>
                  );
                })}
              </div>
            );
          })}
        </div>
        <div className="cp-foot">
          <span><span className="kbd">↑</span><span className="kbd">↓</span> {t.cpFoot[0].replace(/^[↑↓ ]+/, "")}</span>
          <span><span className="kbd">↵</span> {t.cpFoot[1].replace(/^↵ /, "")}</span>
          <span className="grow"/>
          <span><span className="kbd">esc</span> {t.cpFoot[2].replace(/^esc /, "")}</span>
        </div>
      </div>
    </div>
  );
};

// ============ TRY-IT DRAWER ============
const TryItDrawer = ({ open, onClose, endpoint, t, lang }) => {
  const [params, setParams] = useS({});
  const [loading, setLoading] = useS(false);
  const [resp, setResp] = useS(null);

  useE(() => {
    if (!open) return;
    setResp(null);
    // Default params per endpoint
    const defaults = {
      "geocode-search": { q: lang === "ar" ? "شارع الرشيد، بغداد" : "Al-Rasheed Street, Baghdad", country: "iq", lang: "auto" },
      "geocode-reverse": { lat: "33.3152", lon: "44.3661", lang: "auto" },
      "route": { from: "33.31,44.36", to: "33.34,44.41", profile: "driving-traffic" },
      "nearest": { lat: "33.31", lon: "44.36", limit: "5" },
      "places-search": { category: "pharmacy", near: "33.31,44.36", radius_m: "2000" },
    };
    setParams(defaults[endpoint] || {});
  }, [open, endpoint]);

  const meta = {
    "geocode-search": { method: "GET", path: "/v1/geocode/search", title: lang === "ar" ? "ترميز أمامي" : "Forward geocode" },
    "geocode-reverse": { method: "GET", path: "/v1/geocode/reverse", title: lang === "ar" ? "ترميز عكسي" : "Reverse geocode" },
    "route": { method: "GET", path: "/v1/route", title: lang === "ar" ? "حساب طريق" : "Calculate route" },
    "nearest": { method: "GET", path: "/v1/match/nearest", title: lang === "ar" ? "أقرب سائق" : "Nearest driver" },
    "places-search": { method: "GET", path: "/v1/places/search", title: lang === "ar" ? "بحث الأماكن" : "Places search" },
  }[endpoint] || { method: "GET", path: "/", title: "" };

  const mockResponse = (ep, p) => {
    if (ep === "geocode-search") return { results: [
      { place_id: "iq_bg_rashid_01", name_ar: "شارع الرشيد", name_en: "Al-Rasheed Street", lat: 33.3399, lon: 44.4078, confidence: 0.94, country: "iq" },
      { place_id: "iq_bg_rashid_02", name_ar: "محلة شارع الرشيد", name_en: "Al-Rasheed Quarter", lat: 33.3413, lon: 44.4061, confidence: 0.71, country: "iq" },
    ]};
    if (ep === "geocode-reverse") return { address: { name_ar: "الكرّادة", name_en: "Karrada", city: "Baghdad", country: "iq", postcode: "10001" } };
    if (ep === "route") return { distance_m: 5430, duration_s: 612, geometry: "polyline:_p~iF~ps|U_ulLnnqC...", legs: [{ summary: "شارع فلسطين", steps: 14 }] };
    if (ep === "nearest") return { drivers: [
      { id: "drv_4821", eta_s: 142, distance_m: 720, lat: 33.314, lon: 44.366 },
      { id: "drv_2901", eta_s: 198, distance_m: 940, lat: 33.302, lon: 44.351 },
    ]};
    if (ep === "places-search") return { places: [
      { id: "iq_bg_ph_142", name_ar: "صيدلية النور", name_en: "Al-Noor Pharmacy", category: "pharmacy", lat: 33.3098, lon: 44.3624 },
      { id: "iq_bg_ph_088", name_ar: "صيدلية الكندي", name_en: "Al-Kindi Pharmacy", category: "pharmacy", lat: 33.3121, lon: 44.3711 },
    ]};
    return {};
  };

  const send = () => {
    setLoading(true);
    setResp(null);
    setTimeout(() => {
      setResp({ status: 200, time_ms: 60 + Math.floor(Math.random() * 80), body: mockResponse(endpoint, params) });
      setLoading(false);
    }, 700);
  };

  if (!open) return null;
  return (
    <>
      <div className="drawer-backdrop" onClick={onClose}/>
      <div className="drawer fade-in" role="dialog" aria-modal="true">
        <div className="drawer-head">
          <span className={`method ${meta.method.toLowerCase()}`}>{meta.method}</span>
          <span style={{ fontFamily: "JetBrains Mono", fontSize: 13, color: "var(--ink)" }} dir="ltr">{meta.path}</span>
          <button className="close" onClick={onClose} aria-label={t.close}><DocIcon name="x" size={14}/></button>
        </div>
        <div className="drawer-body">
          <div style={{ color: "var(--ink-3)", fontSize: 13, marginBottom: 14 }}>{meta.title}</div>
          {Object.entries(params).map(([k, v]) => (
            <div className="drawer-section" key={k}>
              <span className="lbl">{k}</span>
              <input value={v} onChange={e => setParams({ ...params, [k]: e.target.value })} dir="ltr"/>
            </div>
          ))}

          {resp && (
            <div className="drawer-section" style={{ marginTop: 24 }}>
              <span className="lbl" style={{ display: "flex", gap: 8, alignItems: "center" }}>
                <span className={`status-pill s${resp.status < 300 ? "2xx" : resp.status < 500 ? "4xx" : "5xx"}`}>{resp.status}</span>
                <span style={{ color: "var(--ink-3)", textTransform: "none", letterSpacing: 0, fontFamily: "JetBrains Mono" }}>{resp.time_ms}ms</span>
              </span>
              <div className="code-block" style={{ marginTop: 6 }}>
                <pre className="code-pre" dir="ltr"><Highlight code={JSON.stringify(resp.body, null, 2)} lang="json"/></pre>
              </div>
            </div>
          )}
        </div>
        <div className="drawer-foot">
          <button className="btn btn-primary" onClick={send} disabled={loading}>
            {loading ? <><span style={{ display: "inline-block", width: 10, height: 10, border: "2px solid white", borderTopColor: "transparent", borderRadius: "50%", animation: "spin 0.8s linear infinite" }}/> {t.running}</> : <><DocIcon name="play" size={12}/> {t.run}</>}
          </button>
          <button className="btn btn-ghost" onClick={onClose}>{t.close}</button>
        </div>
      </div>
      <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>
    </>
  );
};

// ============ TWEAKS PANEL ============
const DocsTweaks = ({ theme, setTheme, lang, setLang, density, setDensity, fontScale, setFontScale }) => {
  const [open, setOpen] = useS(false);
  useE(() => {
    const onMsg = (e) => {
      if (e.data?.type === "__activate_edit_mode") setOpen(true);
      else if (e.data?.type === "__deactivate_edit_mode") setOpen(false);
    };
    window.addEventListener("message", onMsg);
    window.parent.postMessage({ type: "__edit_mode_available" }, "*");
    return () => window.removeEventListener("message", onMsg);
  }, []);
  const close = () => { setOpen(false); window.parent.postMessage({ type: "__edit_mode_dismissed" }, "*"); };
  if (!open) return null;
  return (
    <div style={{
      position: "fixed", bottom: 16, insetInlineEnd: 16, width: 280,
      background: "var(--bg-elev)", border: "1px solid var(--line-strong)",
      borderRadius: 12, boxShadow: "var(--shadow-lg)", zIndex: 60, overflow: "hidden",
    }}>
      <div style={{ padding: "12px 14px", borderBottom: "1px solid var(--line)", display: "flex", alignItems: "center" }}>
        <strong style={{ color: "var(--ink)", fontSize: 13 }}>Tweaks</strong>
        <button onClick={close} style={{ marginInlineStart: "auto", background: "transparent", border: 0, color: "var(--ink-3)", padding: 4 }}><DocIcon name="x" size={14}/></button>
      </div>
      <div style={{ padding: 14, display: "grid", gap: 14 }}>
        <Seg label="Theme" value={theme} onChange={setTheme} options={[["dark","Dark"],["light","Light"]]}/>
        <Seg label="Language" value={lang} onChange={setLang} options={[["en","EN"],["ar","العربية"]]}/>
        <Seg label="Density" value={density} onChange={setDensity} options={[["comfortable","Comfortable"],["compact","Compact"]]}/>
        <div>
          <div style={{ fontFamily: "JetBrains Mono", fontSize: 10, textTransform: "uppercase", letterSpacing: "0.08em", color: "var(--ink-4)", marginBottom: 6, display: "flex", justifyContent: "space-between" }}>
            <span>Font scale</span><span>{Math.round(fontScale * 100)}%</span>
          </div>
          <input type="range" min="0.85" max="1.2" step="0.05" value={fontScale} onChange={e => setFontScale(parseFloat(e.target.value))} style={{ width: "100%", accentColor: "var(--brand-500)" }}/>
        </div>
      </div>
    </div>
  );
};
const Seg = ({ label, value, onChange, options }) => (
  <div>
    <div style={{ fontFamily: "JetBrains Mono", fontSize: 10, textTransform: "uppercase", letterSpacing: "0.08em", color: "var(--ink-4)", marginBottom: 6 }}>{label}</div>
    <div style={{ display: "grid", gridTemplateColumns: `repeat(${options.length}, 1fr)`, background: "var(--bg)", border: "1px solid var(--line)", borderRadius: 6, padding: 2 }}>
      {options.map(([k, v]) => (
        <button key={k} onClick={() => onChange(k)} style={{
          padding: "5px 8px", borderRadius: 4, border: 0, fontSize: 12,
          background: value === k ? "var(--brand-500)" : "transparent",
          color: value === k ? "white" : "var(--ink-2)", fontFamily: "inherit", fontWeight: 500,
        }}>{v}</button>
      ))}
    </div>
  </div>
);

window.CommandPalette = CommandPalette;
window.TryItDrawer = TryItDrawer;
window.DocsTweaks = DocsTweaks;
