// app.jsx — root: routing, cart/state, language + theme, tweaks. Mounts the app.
const {
  TopBar, AnnouncementBar, Footer, Storefront, SavedItemsPage, ProductDetail,
  CartDrawer, Checkout, OrderSuccess, MyOrdersPage, AdminApp, LoginPage, SupportPage, STRINGS, PRODUCTS, Icon: RootIcon,
  useTweaks, TweaksPanel, TweakSection, TweakToggle, TweakRadio,
} = window;

const AUTH_KEY = "megatech_auth_v1";
function loadAuth() {
  // A non-persistent ("don't keep me signed in") session lives in sessionStorage;
  // a persistent one in localStorage. Prefer the session copy when both exist.
  try {
    const s = sessionStorage.getItem(AUTH_KEY);
    if (s) return JSON.parse(s);
    return JSON.parse(localStorage.getItem(AUTH_KEY) || "null");
  } catch (e) { return null; }
}

const FAVS_KEY = "megatech_favs_v1";
function loadFavs() {
  try { return JSON.parse(localStorage.getItem(FAVS_KEY) || "[]"); } catch (e) { return []; }
}

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "dark": false,
  "cardStyle": "standard",
  "heroVariant": "split",
  "adminLayout": "modal"
}/*EDITMODE-END*/;

function Toasts({ toasts }) {
  return (
    <div className="toaststack">
      {toasts.map((tt) => (
        <div className="toast" key={tt.id}>
          <span className="ic"><RootIcon name="check-circle" size={20} /></span>
          <span className="t">{tt.msg}</span>
        </div>
      ))}
    </div>
  );
}

function App() {
  const [tw, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [lang, setLang] = React.useState("ar");
  // Deep-link support: a product page is shareable via ?p=<id>. Read it once on
  // load so opening a shared link lands directly on that product.
  const initialPid = (() => {
    try { return new URLSearchParams(window.location.search).get("p") || null; } catch (e) { return null; }
  })();
  const [view, setView] = React.useState(initialPid ? "detail" : "storefront"); // storefront | detail | checkout | success | admin
  const [pid, setPid] = React.useState(initialPid);
  const [cart, setCart] = React.useState([]);
  const [cartOpen, setCartOpen] = React.useState(false);
  const [favs, setFavs] = React.useState(loadFavs);
  const [query, setQuery] = React.useState("");
  const [activeCat, setActiveCat] = React.useState("all");
  const [sort, setSort] = React.useState("featured");
  const [adminProducts, setAdminProducts] = React.useState(() => PRODUCTS.map((p) => ({ ...p, status: "active" })));
  const [categories, setCategories] = React.useState(() => window.CATEGORIES.slice());
  const [settings, setSettings] = React.useState({});
  const [orderNo, setOrderNo] = React.useState("");
  const [toasts, setToasts] = React.useState([]);
  const [auth, setAuth] = React.useState(loadAuth);
  const [authMode, setAuthMode] = React.useState("signin"); // signin | create
  const [authIntent, setAuthIntent] = React.useState(null); // 'admin' when gated
  const [prevView, setPrevView] = React.useState("storefront");
  const catalogRef = React.useRef(null);
  const t = STRINGS[lang];

  React.useEffect(() => {
    try {
      if (auth) {
        const raw = JSON.stringify(auth);
        // "Keep me signed in" (auth.remember !== false) → persist in localStorage.
        // Otherwise keep it only for this browser session. Always clear the other
        // store so a stale copy can't resurrect the session.
        if (auth.remember === false) {
          sessionStorage.setItem(AUTH_KEY, raw);
          localStorage.removeItem(AUTH_KEY);
        } else {
          localStorage.setItem(AUTH_KEY, raw);
          sessionStorage.removeItem(AUTH_KEY);
        }
      } else {
        localStorage.removeItem(AUTH_KEY);
        sessionStorage.removeItem(AUTH_KEY);
      }
    } catch (e) {}
  }, [auth]);

  // Token rejected by the server (expired/invalid) → sign out and prompt re-login
  // instead of leaving a broken session that silently 401s on every admin call.
  React.useEffect(() => {
    function onUnauthorized() {
      if (!auth) return;
      setAuth(null);
      toast(t.sessionExpired || t.signedOutToast);
      setAuthMode("signin");
      setView("login");
      window.scrollTo(0, 0);
    }
    window.addEventListener("megatech:unauthorized", onUnauthorized);
    return () => window.removeEventListener("megatech:unauthorized", onUnauthorized);
  }, [auth, t]);

  // Load the catalog from the backend on mount. Falls back to the bundled
  // sample data (already in state) if the API is unreachable.
  React.useEffect(() => {
    (async () => {
      try {
        const [prods, cats, sett] = await Promise.all([
          window.api.listProducts(),
          window.api.listCategories(),
          window.api.getSettings().catch(() => ({})),
        ]);
        // Use the server's data as the source of truth — even when empty — so the admin only
        // edits products that actually exist in the database (avoids 404s on phantom sample rows).
        window.CATEGORIES = cats || [];
        setCategories(cats || []);
        setAdminProducts(prods || []);
        if (sett) setSettings(sett);
      } catch (e) {
        // Backend unreachable → keep the bundled sample data already in state.
        toast(lang === "en" ? "Backend offline — showing sample data" : "الخادم غير متصل — عرض بيانات تجريبية");
      }
    })();
  }, []);

  // Record one page-view for analytics (fire-and-forget, once per load).
  React.useEffect(() => {
    try { window.api.track(window.location.pathname); } catch (e) {}
  }, []);

  React.useEffect(() => {
    document.documentElement.lang = lang;
    document.documentElement.dir = t.dir;
  }, [lang]);
  React.useEffect(() => {
    document.documentElement.dataset.theme = tw.dark ? "dark" : "light";
  }, [tw.dark]);

  // Persist favorites so they survive a page refresh.
  React.useEffect(() => {
    try { localStorage.setItem(FAVS_KEY, JSON.stringify(favs)); } catch (e) {}
  }, [favs]);

  // Make the browser/phone Back button return to the storefront instead of
  // leaving the site. This app switches "pages" via React state (view), so the
  // browser has no history of those transitions on its own. Each time we enter a
  // sub-view (detail, checkout, etc.) we push a history entry; pressing Back pops
  // it and we render the storefront again.
  React.useEffect(() => {
    const path = window.location.pathname;
    if (view === "storefront") {
      // Returning to the storefront: strip any ?p= so the URL is clean again.
      if (window.location.search) {
        try { window.history.replaceState({ mtView: "storefront" }, "", path); } catch (e) {}
      }
      return;
    }
    // Detail pages carry the product id in the URL so they can be shared/bookmarked.
    // Other sub-views just get a plain history entry so Back returns to the store.
    const target = view === "detail" && pid ? path + "?p=" + encodeURIComponent(pid) : path;
    const current = path + window.location.search;
    if (view === "detail") {
      if (current !== target) { try { window.history.pushState({ mtView: view, pid }, "", target); } catch (e) {} }
    } else {
      try { window.history.pushState({ mtView: view }, "", target); } catch (e) {}
    }
    function onPop() {
      let sp = null;
      try { sp = new URLSearchParams(window.location.search).get("p"); } catch (e) {}
      if (sp) { setPid(sp); setView("detail"); } else { setView("storefront"); }
      window.scrollTo(0, 0);
    }
    window.addEventListener("popstate", onPop);
    return () => window.removeEventListener("popstate", onPop);
  }, [view, pid]);

  function toast(msg) {
    const id = Date.now() + Math.random();
    setToasts((ts) => [...ts, { id, msg }]);
    setTimeout(() => setToasts((ts) => ts.filter((x) => x.id !== id)), 2600);
  }

  function addToCart(product, qty = 1) {
    setCart((prev) => {
      const ex = prev.find((it) => it.product.id === product.id);
      if (ex) return prev.map((it) => it.product.id === product.id ? { ...it, qty: Math.min(product.stock || 99, it.qty + qty) } : it);
      return [...prev, { product, qty }];
    });
    toast(t.added + " · " + product.name[lang]);
  }
  const setQtyItem = (id, v) => setCart((prev) => prev.map((it) => it.product.id === id ? { ...it, qty: v } : it));
  const removeItem = (id) => setCart((prev) => prev.filter((it) => it.product.id !== id));
  const cartCount = cart.reduce((s, it) => s + it.qty, 0);

  const toggleFav = (id) => setFavs((f) => f.includes(id) ? f.filter((x) => x !== id) : [...f, id]);

  async function addCategory(cat) {
    let img = null;
    if (cat.imgFile) {
      try { img = (await window.api.uploadFile(cat.imgFile)).url; }
      catch (e) { toast(e.message); return; }
    }
    let saved;
    try { saved = await window.api.addCategory({ ...cat, img }); }
    catch (e) { toast(e.message); return; }
    const next = [...categories, saved];
    window.CATEGORIES = next;
    setCategories(next);
    return saved;
  }
  async function deleteCategory(id) {
    try { await window.api.deleteCategory(id); }
    catch (e) { toast(e.message); return; }
    const next = categories.filter((c) => c.id !== id);
    window.CATEGORIES = next;
    setCategories(next);
    return true;
  }

  function openProduct(id) { setPid(id); setView("detail"); window.scrollTo(0, 0); }
  function goCheckout() { setCartOpen(false); setView("checkout"); window.scrollTo(0, 0); }
  function onPlaced(no) { setOrderNo(no); setCart([]); setView("success"); window.scrollTo(0, 0); }
  function backToStore() { setView("storefront"); window.scrollTo(0, 0); }

  function scrollToCatalog(catId) {
    if (view !== "storefront") { setView("storefront"); }
    if (catId) setActiveCat(catId);
    const tryScroll = (n) => {
      const el = catalogRef.current;
      if (el) { window.scrollTo({ top: Math.max(0, el.offsetTop - 80), behavior: "smooth" }); }
      else if (n < 20) { requestAnimationFrame(() => tryScroll(n + 1)); }
    };
    requestAnimationFrame(() => tryScroll(0));
  }
  function onQuery(v) {
    // Did this keystroke *start* a search? (was empty, or we're on another page)
    const starting = !!v.trim() && (!query.trim() || (view !== "storefront" && view !== "admin"));
    setQuery(v);
    if (view !== "storefront" && view !== "admin") setView("storefront");
    // Jump to the results grid so the filtered products are actually visible
    // (otherwise the grid filters below the fold and search looks like it does nothing).
    if (starting) scrollToCatalog();
  }
  function onNav(target) {
    setView(target);
    window.scrollTo(0, 0);
  }
  function setViewMode(m) {
    setView(m);
    window.scrollTo(0, 0);
  }

  function goLogin(intent) {
    setPrevView(view === "login" ? prevView : view);
    setAuthIntent(intent || null);
    setAuthMode("signin");
    setView("login");
    window.scrollTo(0, 0);
  }
  function onAuthed(profile, remember) {
    // Tag the session with the "Keep me signed in" choice (default: keep).
    const next = Object.assign({}, profile, { remember: remember !== false });
    setAuth(next);
    toast(t.signedInToast + " \u00b7 " + (profile.name[lang] || profile.name.en));
    if (authIntent === "admin" || profile.role === "admin") setView("admin");
    else setView(prevView === "login" || prevView === "admin" ? "storefront" : prevView);
    setAuthIntent(null);
    window.scrollTo(0, 0);
  }
  function signOut() {
    setAuth(null);
    toast(t.signedOutToast);
    setView("storefront");
    window.scrollTo(0, 0);
  }
  function openAdmin() {
    if (auth && auth.role === "admin") { setView("admin"); window.scrollTo(0, 0); }
    else goLogin("admin");
  }

  const detailSource = adminProducts;

  // Hero slideshow images: prefer the new `heroImages` JSON list, fall back to the
  // legacy single `heroImageUrl` so older saved settings keep working.
  const heroImages = React.useMemo(() => {
    try {
      const arr = settings.heroImages ? JSON.parse(settings.heroImages) : null;
      if (Array.isArray(arr) && arr.filter(Boolean).length) return arr.filter(Boolean);
    } catch (e) {}
    return settings.heroImageUrl ? [settings.heroImageUrl] : [];
  }, [settings.heroImages, settings.heroImageUrl]);

  return (
    <>
      {view !== "admin" && view !== "login" && (
        <TopBar t={t} lang={lang} onToggleLang={() => setLang(lang === "en" ? "ar" : "en")}
          view={view} onSetView={setViewMode} cartCount={cartCount}
          onOpenCart={() => setCartOpen(true)} onLogo={backToStore} query={query} onQuery={onQuery}
          auth={auth} onSignIn={() => goLogin(null)} onSignOut={signOut} onAdmin={openAdmin} onNav={onNav} onProducts={() => scrollToCatalog("all")} onSolutions={() => scrollToCatalog("software")}
          onMyOrders={() => { setView("myorders"); window.scrollTo(0, 0); }}
          onSavedItems={() => { setView("saved"); window.scrollTo(0, 0); }}
          onAction={(label) => toast(label + " \u00b7 " + (lang === "en" ? "coming soon in this prototype" : "\u0642\u0631\u064a\u0628\u0627\u064b \u0641\u064a \u0647\u0630\u0627 \u0627\u0644\u0646\u0645\u0648\u0630\u062c")) } />
      )}

      {view === "login" && (
        <LoginPage lang={lang} t={t} mode={authMode} onModeChange={setAuthMode}
          onAuthed={onAuthed} onBackToStore={backToStore} intent={authIntent} toast={toast}
          onToggleLang={() => setLang(lang === "en" ? "ar" : "en")} />
      )}

      {view === "storefront" && (
        <Storefront t={t} lang={lang} heroVariant={tw.heroVariant} cardStyle={tw.cardStyle}
          activeCat={activeCat} setActiveCat={setActiveCat} sort={sort} setSort={setSort} query={query}
          onAdd={(p) => addToCart(p, 1)} onView={openProduct} favs={favs} onFav={toggleFav}
          catalogRef={catalogRef} onBrowse={scrollToCatalog} products={adminProducts} categories={categories} heroImages={heroImages} onSales={() => onNav("support")} />
      )}
      {view === "detail" && (
        <ProductDetail productId={pid} lang={lang} t={t} onBack={backToStore}
          onAdd={addToCart} onView={openProduct} favs={favs} onFav={toggleFav}
          onOpenCart={() => setCartOpen(true)} products={detailSource} />
      )}
      {view === "checkout" && (
        <Checkout items={cart} lang={lang} t={t} onBack={() => { setView("storefront"); setCartOpen(true); }} onPlaced={onPlaced} />
      )}
      {view === "success" && <OrderSuccess orderNo={orderNo} lang={lang} t={t} onBack={backToStore} />}

      {view === "myorders" && <MyOrdersPage lang={lang} t={t} onBack={backToStore} onBrowse={scrollToCatalog} />}

      {view === "saved" && (
        <SavedItemsPage lang={lang} t={t} cardStyle={tw.cardStyle} products={adminProducts}
          favs={favs} onFav={toggleFav} onAdd={(p) => addToCart(p, 1)} onView={openProduct}
          onBack={backToStore} onBrowse={scrollToCatalog} />
      )}

      {view === "support" && <SupportPage lang={lang} t={t} onBackToStore={backToStore} />}

      {view === "admin" && auth && auth.role === "admin" && (
        <AdminApp lang={lang} t={t} onToggleLang={() => setLang(lang === "en" ? "ar" : "en")}
          onExitAdmin={backToStore} products={adminProducts} setProducts={setAdminProducts}
          categories={categories} onAddCategory={addCategory} onDeleteCategory={deleteCategory}
          adminLayout={tw.adminLayout} toast={toast} auth={auth} onSignOut={signOut}
          settings={settings} onSettingsChange={setSettings} />
      )}

      {(view === "storefront" || view === "detail" || view === "support" || view === "myorders" || view === "saved") && <Footer t={t} lang={lang} />}

      {view !== "admin" && view !== "login" && (
        <CartDrawer open={cartOpen} onClose={() => setCartOpen(false)} items={cart} lang={lang} t={t}
          onQty={setQtyItem} onRemove={removeItem} onCheckout={goCheckout} onBrowse={scrollToCatalog}
          onView={(id) => { setCartOpen(false); openProduct(id); }} />
      )}

      <Toasts toasts={toasts} />

      <TweaksPanel title="Tweaks">
        <TweakSection label={lang === "en" ? "Theme" : "السمة"} />
        <TweakToggle label={lang === "en" ? "Dark mode" : "الوضع الداكن"} value={tw.dark} onChange={(v) => setTweak("dark", v)} />
        <TweakSection label={lang === "en" ? "Product card" : "بطاقة المنتج"} />
        <TweakRadio label={lang === "en" ? "Card style" : "النمط"} value={tw.cardStyle}
          options={[{ value: "standard", label: "Standard" }, { value: "minimal", label: "Minimal" }, { value: "spec", label: "Spec" }]}
          onChange={(v) => setTweak("cardStyle", v)} />
        <TweakSection label={lang === "en" ? "Storefront" : "المتجر"} />
        <TweakRadio label={lang === "en" ? "Hero layout" : "تصميم الواجهة"} value={tw.heroVariant}
          options={[{ value: "split", label: "Split" }, { value: "bold", label: "Bold" }, { value: "center", label: "Center" }]}
          onChange={(v) => setTweak("heroVariant", v)} />
        <TweakSection label={lang === "en" ? "Admin" : "الإدارة"} />
        <TweakRadio label={lang === "en" ? "Add-product form" : "نموذج الإضافة"} value={tw.adminLayout}
          options={[{ value: "modal", label: t.layoutModal }, { value: "page", label: t.layoutPage }]}
          onChange={(v) => setTweak("adminLayout", v)} />
      </TweaksPanel>
    </>
  );
}

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