// Main App: router, shell, tweaks, lang
const { useState: uS, useEffect: uE, useRef: uR, useMemo: uM } = React;
const { Button: BtnE, Info: InfoE, Ic: IcE } = window.UI;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent":   "#0E2A47",
  "agency":   "Dugongo",
  "density":  "regular",
  "dark":     false,
  "guide":    "balanced",
  "fontPair": "geist-instrument"
}/*EDITMODE-END*/;

const ACCENT_OPTS = ["#0E2A47", "#1F4FA5", "#1F7A4D", "#B23A3A", "#0E1116"];

function applyTweaks(tw) {
  const root = document.documentElement;
  root.dataset.theme = tw.dark ? "dark" : "light";
  const d = tw.density;
  root.style.setProperty("--pad-y", d === "compact" ? "22px" : d === "comfy" ? "44px" : "32px");
  if (tw.accent) {
    root.style.setProperty("--accent", tw.accent);
    root.style.setProperty("--accent-2", shade(tw.accent, 14));
    root.style.setProperty("--accent-soft", tinted(tw.accent, 0.08));
  }
}

function shade(hex, pct) {
  const num = parseInt(hex.slice(1), 16);
  const r = Math.min(255, ((num >> 16) & 255) + pct);
  const g = Math.min(255, ((num >> 8) & 255) + pct);
  const b = Math.min(255, (num & 255) + pct);
  return "#" + ((r << 16) | (g << 8) | b).toString(16).padStart(6, "0");
}
function tinted(hex, a) {
  const num = parseInt(hex.slice(1), 16);
  const r = (num >> 16) & 255, g = (num >> 8) & 255, b = num & 255;
  const m = (c) => Math.round(c * a + 255 * (1 - a));
  return `rgb(${m(r)}, ${m(g)}, ${m(b)})`;
}

function isAdminTokenValid() {
  const token = localStorage.getItem("bt_admin_token");
  if (!token) return false;
  try {
    const payload = JSON.parse(atob(token.split(".")[1]));
    return payload.role === "admin" && payload.exp * 1000 > Date.now();
  } catch { return false; }
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  uE(() => applyTweaks(t), [t]);

  const [lang, setLang] = uS(() => localStorage.getItem("bt_lang") || "en");
  uE(() => localStorage.setItem("bt_lang", lang), [lang]);

  const [route, setRoute] = uS(() => {
    // Visiting /admin directly shows the admin panel
    if (location.pathname.startsWith('/admin')) {
      return isAdminTokenValid() ? 'admin' : 'adminLogin';
    }
    const saved = localStorage.getItem("bt_route") || "login";
    if (saved === "admin") return isAdminTokenValid() ? "admin" : "adminLogin";
    return saved;
  });
  const [folderId, setFolderId] = uS(null);
  const [search, setSearch]     = uS("");
  uE(() => { if (route !== "folder") localStorage.setItem("bt_route", route); }, [route]);

  // Sync navigation con browser history (back/forward)
  uE(() => {
    history.replaceState({ route, folderId }, "");
    const onPop = (e) => {
      if (e.state?.route) {
        setRoute(e.state.route);
        setFolderId(e.state.folderId || null);
      }
    };
    window.addEventListener("popstate", onPop);
    return () => window.removeEventListener("popstate", onPop);
  }, []);

  const go = (r, fid = null) => {
    if (["dashboard", "folder", "help", "profile"].includes(r)) {
      history.pushState({ route: r, folderId: fid }, "");
    }
    setFolderId(fid);
    setRoute(r);
    setSearch("");
  };

  const [modal, setModal] = uS(null);
  const [chatOpen, setChatOpen] = uS(false);
  const [tourOpen, setTourOpen] = uS(false);
  const [dashRefresh, setDashRefresh]     = uS(null);
  const [folderRefresh, setFolderRefresh] = uS(null);

  const dict = window.I18N[lang];

  const tourSteps = uM(() => dict.tour.map((s, i) => ({
    t: s.t,
    d: s.d,
    getEl: () => document.querySelector(`[data-tour="${["create","upload","search","help"][i]}"]`),
    place: ["bottom", "bottom", "bottom", "bottom"][i],
    enter: () => go("dashboard"),
  })), [dict]);

  const startTour = () => {
    if (route !== "dashboard") go("dashboard");
    setTimeout(() => setTourOpen(true), 50);
  };

  const refreshDash    = () => { if (dashRefresh)    dashRefresh(); };
  const refreshFolder  = () => { if (folderRefresh)  folderRefresh(); };
  const refreshAll     = () => { refreshDash(); if (folderRefresh) folderRefresh(); };

  const upload = window.useUploadState(refreshAll);

  /* ---------- ADMIN ---------- */
  if (route === "adminLogin") {
    return (
      <>
        <AdminLoginScreen lang={lang} onLogin={() => { localStorage.setItem("bt_route", "admin"); setRoute("admin"); }} />
        <AppTweaks t={t} setTweak={setTweak} lang={lang} />
      </>
    );
  }
  if (route === "admin") {
    if (!isAdminTokenValid()) { setRoute("adminLogin"); return null; }
    return (
      <>
        <AdminScreen lang={lang} onLogout={() => {
          fetch('/api/auth/logout', {
            method: 'POST',
            headers: { 'Authorization': 'Bearer ' + localStorage.getItem('bt_admin_token'), 'Content-Type': 'application/json' },
          }).catch(() => {});
          localStorage.removeItem("bt_admin_token");
          localStorage.setItem("bt_route", "adminLogin");
          setRoute("adminLogin");
        }} />
        <AppTweaks t={t} setTweak={setTweak} lang={lang} />
      </>
    );
  }

  /* ---------- LOGIN ---------- */
  if (route === "login") {
    return (
      <>
        <LoginScreen t={dict} lang={lang} setLang={setLang} onLogin={() => setRoute("welcome")} />
        <AppTweaks t={t} setTweak={setTweak} lang={lang} />
      </>
    );
  }

  /* ---------- WELCOME ---------- */
  if (route === "welcome") {
    return (
      <div className="app">
        <Topbar dict={dict} lang={lang} setLang={setLang} search={search} setSearch={setSearch}
          onNavigate={() => {}}
          onHelp={() => setRoute("help")} onProfile={() => setRoute("profile")}
          onChat={() => setChatOpen(true)} hideSearch />
        <WelcomeScreen t={dict} lang={lang} setLang={setLang}
          onContinue={() => setRoute("dashboard")}
          onTour={() => { setRoute("dashboard"); setTimeout(() => setTourOpen(true), 80); }} />
        <ChatWidget t={dict} lang={lang} open={chatOpen} setOpen={setChatOpen} />
        <AppTweaks t={t} setTweak={setTweak} lang={lang} />
      </div>
    );
  }

  /* ---------- APP SHELL ---------- */

  return (
    <div className="app">
      <Topbar dict={dict} lang={lang} setLang={setLang} search={search} setSearch={setSearch}
        onNavigate={(folderId) => go("folder", folderId)}
        onHelp={() => go("help")} onProfile={() => go("profile")}
        onChat={() => setChatOpen(true)} />

      <div className="layout">
        <aside className="sidebar">
          <div className="side-section">
            <button className="side-link" data-active={route === "dashboard"} onClick={() => go("dashboard")}>
              <IcE.folder /> {dict.nav.dashboard}
            </button>
          </div>
          <hr className="hr" />
          <div className="side-section">
            <div className="side-label">{lang === "it" ? "Account" : "Account"}</div>
            <button className="side-link" data-active={route === "help"} onClick={() => go("help")}>
              <IcE.help /> {dict.nav.help}
            </button>
            <button className="side-link" data-active={route === "profile"} onClick={() => go("profile")}>
              <IcE.user /> {dict.nav.profile}
            </button>
          </div>
          <div className="side-cta">
            <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
              <IcE.sparkle />
              <span className="t">{dict.side_cta.t}</span>
            </div>
            <div className="d">{dict.side_cta.d}</div>
            <BtnE size="sm" variant="ghost" onClick={() => go("help")}
              style={{ alignSelf: "flex-start", padding: "0 8px", color: "var(--accent)" }}>
              {dict.side_cta.btn} →
            </BtnE>
          </div>
        </aside>

        {route === "dashboard" && (
          <DashboardScreen t={dict} lang={lang} search={search}
            onOpenFolder={(id) => go("folder", id)}
            onNewFolder={() => setModal("createFolder")}
            onUpload={() => setModal("upload")}
            onHelp={() => go("help")}
            onRefreshNeeded={(fn) => setDashRefresh(() => fn)} />
        )}
        {route === "folder" && folderId && (
          <FolderScreen t={dict} lang={lang} folderId={folderId} search={search}
            onBack={() => go("dashboard")}
            onOpenFolder={(id) => go("folder", id)}
            onUpload={() => setModal("upload")}
            onNewSubfolder={() => setModal("createFolder")}
            onRefreshNeeded={(fn) => setFolderRefresh(() => fn)} />
        )}
        {route === "help" && (
          <HelpScreen t={dict} lang={lang} onChat={() => setChatOpen(true)} onTour={startTour} />
        )}
        {route === "profile" && (
          <ProfileScreen t={dict} lang={lang} onLogout={() => {
            fetch('/api/auth/logout', {
              method: 'POST',
              headers: { 'Authorization': 'Bearer ' + localStorage.getItem('bt_token'), 'Content-Type': 'application/json' },
            }).catch(() => {});
            setRoute("login"); localStorage.removeItem("bt_token"); localStorage.setItem("bt_route", "login");
          }} />
        )}
      </div>

      <UploadModal t={dict} lang={lang} open={modal === "upload"} onClose={() => setModal(null)}
        defaultFolderId={folderId} upload={upload} />
      <CreateFolderModal t={dict} lang={lang} open={modal === "createFolder"} onClose={() => setModal(null)}
        onCreated={() => { refreshDash(); if (folderRefresh) folderRefresh(); }} defaultParentId={folderId} />

      <UploadToast t={dict} lang={lang} upload={upload} onOpenModal={() => setModal("upload")} />

      <ChatWidget t={dict} lang={lang} open={chatOpen} setOpen={setChatOpen} />
      <GuidedTour open={tourOpen} onClose={() => setTourOpen(false)} steps={tourSteps} lang={lang}
        labels={{ skip: dict.tour_skip, back: dict.tour_back, next: dict.tour_next, done: dict.tour_done }} />

      <AppTweaks t={t} setTweak={setTweak} lang={lang} />
    </div>
  );
}

/* ---------- Top bar ---------- */
function Topbar({ dict, lang, setLang, search, setSearch, onHelp, onProfile, onChat, hideSearch, onNavigate }) {
  const [results, setResults] = uS(null);
  const [trigger, setTrigger] = uS(0);
  const timerRef = uR(null);
  const inputRef  = uR(null);
  const resultsRef = uR(null);

  uE(() => {
    if (timerRef.current) clearTimeout(timerRef.current);
    if (!search || search.length < 2) { setResults(null); return; }
    timerRef.current = setTimeout(async () => {
      try {
        const data = await window.API_CLIENT.apiGet("/search?q=" + encodeURIComponent(search));
        const has = (data?.folders?.length || 0) + (data?.files?.length || 0) > 0;
        setResults(data && has ? data : null);
      } catch { setResults(null); }
    }, 250);
    return () => { clearTimeout(timerRef.current); };
  }, [search, trigger]);

  // Close on Escape or outside click (but not on clicks inside search area)
  uE(() => {
    if (!results) return;
    const close = (e) => {
      if (e.key === "Escape") { setSearch(""); setResults(null); return; }
      if (!e.key && !inputRef.current?.parentElement?.contains(e.target)) {
        setResults(null);
      }
    };
    document.addEventListener("mousedown", close);
    document.addEventListener("keydown", close);
    return () => {
      document.removeEventListener("mousedown", close);
      document.removeEventListener("keydown", close);
    };
  }, [results, setSearch]);

  const handleFocus = () => { if (search && search.length >= 2) setTrigger((t) => t + 1); };

  const pick = (folderId) => { setSearch(""); setResults(null); if (onNavigate) onNavigate(folderId); };

  return (
    <header className="topbar">
      <div className="brand">
        <img src="Logo%20Bolton.svg" alt="Bolton" style={{ height: 28, width: 28, display: "block" }} />
        <div>
          <div style={{ lineHeight: 1.1 }}>Bolton <span className="serif-it" style={{ color: "var(--ink-soft)" }}>transfer</span></div>
        </div>
        <div className="brand-sub">{dict.brand_sub}</div>
      </div>

      {!hideSearch && (
        <div className="topbar-search" data-tour="search">
          <IcE.search />
          <input ref={inputRef} placeholder={dict.topbar.search} value={search}
            onChange={(e) => setSearch(e.target.value)}
            onFocus={handleFocus} />
          {results && (
            <div className="search-results" ref={resultsRef} onMouseDown={(e) => e.preventDefault()}>
              {results.folders?.length > 0 && (
                <div className="search-section">
                  <div className="search-section-title">{lang === "it" ? "Cartelle" : "Folders"}</div>
                  {results.folders.map((f) => (
                    <button key={'f'+f.id} className="search-item" onClick={() => pick(f.id)}>
                      <IcE.folder style={{ width: 15, height: 15, flexShrink: 0, opacity: 0.6 }} />
                      <span>{f.name}</span>
                    </button>
                  ))}
                </div>
              )}
              {results.files?.length > 0 && (
                <div className="search-section">
                  <div className="search-section-title">{lang === "it" ? "File" : "Files"}</div>
                  {results.files.map((f) => (
                    <button key={'e'+f.id} className="search-item" onClick={() => pick(f.folder_id)} style={{ gap: 6 }}>
                      <span className="search-badge">{f.folder_name || "—"}</span>
                      <span style={{ overflow: "hidden", textOverflow: "ellipsis" }}>{f.name}</span>
                    </button>
                  ))}
                </div>
              )}
            </div>
          )}
        </div>
      )}

      <div className="topbar-actions">
        <LangToggle lang={lang} setLang={setLang} />
        <button className="iconbtn" onClick={onHelp} aria-label={dict.topbar.help} title={dict.topbar.help} data-tour="help">
          <IcE.help />
        </button>
<button className="avatar" onClick={onProfile} aria-label="Profile" style={{ background: "var(--surface-soft)", color: "var(--ink-2)", border: "1px solid var(--border)" }}>
          <IcE.user />
        </button>
      </div>
    </header>
  );
}

/* ---------- Tweaks ---------- */
function AppTweaks({ t, setTweak, lang }) {
  return (
    <TweaksPanel>
      <TweakSection label={lang === "it" ? "Marca" : "Brand"} />
      <TweakText label={lang === "it" ? "Nome agenzia" : "Agency name"} value={t.agency}
        onChange={(v) => setTweak("agency", v)} />
      <TweakColor label={lang === "it" ? "Colore accento" : "Accent color"} value={t.accent}
        options={ACCENT_OPTS}
        onChange={(v) => setTweak("accent", v)} />

      <TweakSection label={lang === "it" ? "Aspetto" : "Look & feel"} />
      <TweakToggle label={lang === "it" ? "Modalità scura" : "Dark mode"} value={t.dark}
        onChange={(v) => setTweak("dark", v)} />
      <TweakRadio label={lang === "it" ? "Densità" : "Density"} value={t.density}
        options={["compact", "regular", "comfy"]}
        onChange={(v) => setTweak("density", v)} />

      <TweakSection label={lang === "it" ? "Aiuti" : "Guidance"} />
      <TweakRadio label={lang === "it" ? "Livello guida" : "Guide level"} value={t.guide}
        options={["minimal", "balanced", "verbose"]}
        onChange={(v) => setTweak("guide", v)} />
    </TweaksPanel>
  );
}

const root = ReactDOM.createRoot(document.getElementById("app"));
root.render(<App />);
