/* app.jsx — root: state, routing, header, footer, tweaks wiring
   (React hooks come from window globals set in shared.jsx) */

const LANG_KEY = "siam_lang";
const CART_KEY = "siam_cart";
const ADMIN_KEY = "siam_admin";
const MYORD_KEY = "siam_myorders";

const DEFAULT_TWEAKS = {
  theme: "navy",
  mode: "light",
  font: "sarabun",
  density: "comfortable",
  radius: 4,
};

const FONT_SETS = {
  sarabun: {
    display: '"TH Sarabun New", "TH SarabunPSK", "Sarabun", "Noto Sans Thai", system-ui, sans-serif',
    body: '"TH Sarabun New", "TH SarabunPSK", "Sarabun", "Noto Sans Thai", system-ui, sans-serif',
  },
  garamond: {
    display: '"Cormorant Garamond", "Noto Serif Thai", Georgia, serif',
    body: '"Sarabun", "Noto Sans Thai", system-ui, sans-serif',
  },
  playfair: {
    display: '"Playfair Display", "Noto Serif Thai", Georgia, serif',
    body: '"Sarabun", "Noto Sans Thai", system-ui, sans-serif',
  },
  spectral: {
    display: '"Spectral", "Noto Serif Thai", Georgia, serif',
    body: '"IBM Plex Sans Thai", "Noto Sans Thai", system-ui, sans-serif',
  },
  modern: {
    display: '"Fraunces", "Noto Serif Thai", Georgia, serif',
    body: '"Noto Sans Thai", system-ui, sans-serif',
  },
};

function App() {
  const [lang, setLang] = useState(() => localStorage.getItem(LANG_KEY) || "th");
  const [route, setRoute] = useState({ name: "home" });
  const [cart, setCart] = useState(() => { try { return JSON.parse(localStorage.getItem(CART_KEY)) || []; } catch { return []; } });
  const [dbState, setDbState] = useState(DB.getState());
  const [admin, setAdmin] = useState(() => !!DB.getToken());
  const [tweaks, setTweaks] = useState(DEFAULT_TWEAKS);
  const [toast, setToast] = useState(null);

  // subscribe to the data layer + hydrate from the API on mount
  useEffect(() => {
    const unsub = DB.subscribe(setDbState);
    setDbState(DB.getState());
    DB.refreshPublic().catch(() => {});
    // Validate any stored admin session; drop it if expired/invalid.
    DB.validateSession().then((ok) => {
      if (!ok) setAdmin(false);
      else DB.refreshOrders().catch(() => {});
    });
    return unsub;
  }, []);
  // persist
  useEffect(() => localStorage.setItem(LANG_KEY, lang), [lang]);
  useEffect(() => localStorage.setItem(CART_KEY, JSON.stringify(cart)), [cart]);

  // Wrap admin toggle: clear the session token on sign-out, load orders on sign-in.
  const handleSetAdmin = useCallback((v) => {
    if (!v) DB.adminLogout();
    else DB.refreshOrders().catch(() => {});
    setAdmin(v);
  }, []);

  // apply tweaks to <html>
  useEffect(() => {
    const r = document.documentElement;
    r.setAttribute("data-theme", tweaks.theme);
    r.setAttribute("data-mode", tweaks.mode);
    const f = FONT_SETS[tweaks.font] || FONT_SETS.garamond;
    r.style.setProperty("--font-display", f.display);
    r.style.setProperty("--font-body", f.body);
    r.style.setProperty("--radius", tweaks.radius + "px");
    const d = tweaks.density;
    r.style.setProperty("--pad-card", d === "compact" ? "15px" : d === "roomy" ? "28px" : "22px");
    r.style.setProperty("--gap-grid", d === "compact" ? "18px" : d === "roomy" ? "36px" : "28px");
  }, [tweaks]);

  const t = useCallback((k) => I18N.t(k, lang), [lang]);
  const L = useCallback((obj, key) => (lang === "th" ? obj[key + "_th"] || obj[key + "_en"] : obj[key + "_en"]), [lang]);

  const showToast = useCallback((msg) => {
    setToast(msg);
    clearTimeout(showToast._t);
    showToast._t = setTimeout(() => setToast(null), 2600);
  }, []);

  const nav = useCallback((name, params) => {
    setRoute({ name, ...(params || {}) });
    window.scrollTo({ top: 0, behavior: "instant" in window ? "instant" : "auto" });
  }, []);

  // ----- cart ops -----
  const addToCart = useCallback((product) => {
    setCart((c) => {
      const ex = c.find((x) => x.id === product.id);
      if (ex) return c.map((x) => x.id === product.id ? { ...x, qty: Math.min(x.qty + 1, product.qty) } : x);
      return [...c, { id: product.id, qty: 1 }];
    });
    showToast(lang === "th" ? "เพิ่มลงตะกร้าแล้ว" : "Added to cart");
  }, [lang, showToast]);
  const setCartQty = useCallback((id, qty) => setCart((c) => qty <= 0 ? c.filter((x) => x.id !== id) : c.map((x) => x.id === id ? { ...x, qty } : x)), []);
  const removeFromCart = useCallback((id) => setCart((c) => c.filter((x) => x.id !== id)), []);
  const clearCart = useCallback(() => setCart([]), []);

  const cartCount = cart.reduce((n, x) => n + x.qty, 0);

  const recordMyOrder = useCallback((number) => {
    try {
      const list = JSON.parse(localStorage.getItem(MYORD_KEY)) || [];
      if (!list.includes(number)) { list.unshift(number); localStorage.setItem(MYORD_KEY, JSON.stringify(list.slice(0, 12))); }
    } catch {}
  }, []);

  const ctx = {
    lang, setLang, t, L,
    route, nav,
    cart, setCart, addToCart, setCartQty, removeFromCart, clearCart, cartCount,
    db: dbState, DB,
    admin, setAdmin: handleSetAdmin,
    showToast, recordMyOrder,
    tweaks, setTweaks,
  };

  return (
    <AppCtx.Provider value={ctx}>
      <div className="app">
        {route.name.startsWith("admin") ? null : <Header />}
        <main style={{ flex: 1 }}>
          <Router />
        </main>
        {route.name.startsWith("admin") ? null : <Footer />}
        {toast && <div className="toast"><span className="dot"></span>{toast}</div>}
        <TweaksMount />
      </div>
    </AppCtx.Provider>
  );
}

function Router() {
  const { route } = useApp();
  switch (route.name) {
    case "home": return <Home />;
    case "shop": return <Shop catId={route.catId} q={route.q} />;
    case "product": return <ProductPage id={route.id} />;
    case "cart": return <CartPage />;
    case "checkout": return <CheckoutPage />;
    case "payment": return <PaymentPage orderId={route.orderId} />;
    case "track": return <TrackPage prefill={route.prefill} />;
    case "about": return <AboutPage />;
    case "admin": return <AdminApp />;
    default: return <Home />;
  }
}

/* ---------------- Header ---------------- */
function Header() {
  const { t, lang, setLang, nav, route, cartCount } = useApp();
  const items = [
    { k: "shop", label: t("nav_shop") },
    { k: "track", label: t("nav_orders") },
    { k: "about", label: t("nav_about") },
  ];
  return (
    <header className="hdr">
      <div className="wrap hdr-bar">
        <div className="brand" onClick={() => nav("home")}>
          <span className="brand-name">SIAM HERITAGE</span>
          <span className="brand-sub">{lang === "th" ? "ธนบัตรและเหรียญสะสม" : "Rare Notes & Coins · Bangkok"}</span>
        </div>
        <nav className="nav">
          {items.map((it) => (
            <a key={it.k} className={route.name === it.k ? "active" : ""} onClick={() => nav(it.k)}>{it.label}</a>
          ))}
          <a className={route.name.startsWith("admin") ? "active" : ""} onClick={() => nav("admin")}>{t("nav_admin")}</a>
        </nav>
        <div className="hdr-tools">
          <div className="lang-toggle">
            <button className={lang === "en" ? "on" : ""} onClick={() => setLang("en")}>EN</button>
            <button className={lang === "th" ? "on" : ""} onClick={() => setLang("th")}>ไทย</button>
          </div>
          <button className="cart-btn" onClick={() => nav("cart")} aria-label="Cart">
            <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M3 5h2l2.4 12.2a1 1 0 0 0 1 .8h8.7a1 1 0 0 0 1-.8L21 8H6"/><circle cx="9" cy="21" r="1.3"/><circle cx="18" cy="21" r="1.3"/></svg>
            {cartCount > 0 && <span className="cart-count">{cartCount}</span>}
          </button>
        </div>
      </div>
    </header>
  );
}

/* ---------------- Footer ---------------- */
function Footer() {
  const { lang, nav, db } = useApp();
  const s = db.settings;
  return (
    <footer className="ftr">
      <div className="wrap ftr-in">
        <div style={{ maxWidth: 320 }}>
          <div className="ftr-name">SIAM HERITAGE</div>
          <p style={{ color: "color-mix(in srgb, var(--on-navy) 64%, transparent)", fontSize: 13.5, marginTop: 14, lineHeight: 1.7 }}>
            {lang === "th"
              ? "ร้านสะสมธนบัตรและเหรียญหายาก ตรวจสอบแท้ทุกชิ้น จัดส่งมีประกันทั่วประเทศ"
              : "Authenticated rare Thai banknotes and coins. Every piece examined and insured in transit."}
          </p>
        </div>
        <div style={{ display: "flex", gap: 56, flexWrap: "wrap" }}>
          <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
            <div style={{ fontSize: 11, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--gold)", marginBottom: 4 }}>{lang === "th" ? "ร้านค้า" : "Shop"}</div>
            <a onClick={() => nav("shop")}>{lang === "th" ? "คอลเลกชัน" : "Collection"}</a>
            <a onClick={() => nav("track")}>{lang === "th" ? "ติดตามคำสั่งซื้อ" : "Track Order"}</a>
            <a onClick={() => nav("about")}>{lang === "th" ? "เกี่ยวกับเรา" : "About"}</a>
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
            <div style={{ fontSize: 11, letterSpacing: ".2em", textTransform: "uppercase", color: "var(--gold)", marginBottom: 4 }}>{lang === "th" ? "ติดต่อ" : "Contact"}</div>
            <span style={{ fontSize: 13, color: "color-mix(in srgb, var(--on-navy) 72%, transparent)" }}>{s.bank.promptpay}</span>
            <span style={{ fontSize: 13, color: "color-mix(in srgb, var(--on-navy) 72%, transparent)" }}>Bangkok, Thailand</span>
          </div>
        </div>
      </div>
      <div style={{ borderTop: "1px solid color-mix(in srgb, var(--on-navy) 14%, transparent)" }}>
        <div className="wrap" style={{ padding: "18px 0", fontSize: 12, color: "color-mix(in srgb, var(--on-navy) 50%, transparent)" }}>
          © {new Date().getFullYear()} Siam Heritage · {lang === "th" ? "ต้นแบบสำหรับสาธิต" : "Prototype demo"}
        </div>
      </div>
    </footer>
  );
}

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