/* X-REAL Stock System v5 — Main App (Supabase edition) */
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ─── Tweak defaults ───────────────────────────────────────────────────
const TWEAKS_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accentColor": "#f59e0b",
  "theme": "light",
  "density": "comfortable"
}/*EDITMODE-END*/;

const ACCENT_PRESETS = {
  "#f59e0b": { hover: "#d97706", subtle: "#fef3c7", subtle2: "#fffbeb", border: "#fde68a", name: "Amber" },
  "#3b82f6": { hover: "#2563eb", subtle: "#dbeafe", subtle2: "#eff6ff", border: "#bfdbfe", name: "Blue" },
  "#10b981": { hover: "#059669", subtle: "#d1fae5", subtle2: "#ecfdf5", border: "#a7f3d0", name: "Green" },
  "#8b5cf6": { hover: "#7c3aed", subtle: "#ede9fe", subtle2: "#f5f3ff", border: "#ddd6fe", name: "Purple" },
  "#ef4444": { hover: "#dc2626", subtle: "#fee2e2", subtle2: "#fef2f2", border: "#fecaca", name: "Red" },
  "#18181b": { hover: "#27272a", subtle: "#f4f4f5", subtle2: "#fafafa", border: "#e4e4e7", name: "Mono" },
};
const DENSITY_VALUES = { compact: 0.85, comfortable: 1, spacious: 1.18 };

function App() {
  // ─── Auth state ──────────────────────────────────────────────────
  const [authLoading, setAuthLoading] = useState(true);   // checking session
  const [dbLoading,   setDbLoading]   = useState(false);  // loading data from DB
  const [loggedIn,    setLoggedIn]    = useState(false);
  const [username,    setUsername]    = useState("");

  const [tweaksOpen, setTweaksOpen] = useState(false);
  const [tweaks, setTweak] = useTweaks(TWEAKS_DEFAULTS);

  // Apply tweaks to CSS vars
  useEffect(() => {
    const root = document.documentElement;
    root.setAttribute("data-theme", tweaks.theme || "light");
    root.style.setProperty("--density", DENSITY_VALUES[tweaks.density || "comfortable"]);
    const preset = ACCENT_PRESETS[tweaks.accentColor] || ACCENT_PRESETS["#f59e0b"];
    root.style.setProperty("--accent", tweaks.accentColor);
    root.style.setProperty("--accent-hover", preset.hover);
    if (tweaks.theme !== "dark") {
      root.style.setProperty("--accent-subtle", preset.subtle);
      root.style.setProperty("--accent-subtle-2", preset.subtle2);
      root.style.setProperty("--accent-border", preset.border);
    }
  }, [tweaks]);

  // ─── Data state ──────────────────────────────────────────────────
  const [cats,         setCats]         = useState([]);
  const [products,     setProducts]     = useState([]);
  const [locations,    setLocations]    = useState([]);
  const [repackRules,  setRepackRules]  = useState([]);
  const [stores,       setStores]       = useState([]);
  const [stocks,       setStocks]       = useState([]);
  const [history,      setHistory]      = useState([]);
  const [reservations, setReservations] = useState([]);
  const [consLedger,   setConsLedger]   = useState([]);

  // Track prev stocks for diff-based Supabase delete
  const stocksRef = useRef([]);

  // Suppress realtime echo for N ms after a local write
  const lastWriteRef = useRef(0);
  const ECHO_MS = 2500;

  // ─── UI state ────────────────────────────────────────────────────
  const [tab,         setTabRaw]    = useState("dashboard");
  const [tabPayload,  setTabPayload] = useState(null);
  const [toast,       setToast]     = useState(null);
  const [histFilter,  setHistFilter] = useState("ทั้งหมด");
  const [confirmDlg,  setConfirmDlg] = useState(null);
  const [mobileMore,  setMobileMore] = useState(false);
  const scanStreamRef = useRef(null);

  // ─── Load data from Supabase ─────────────────────────────────────
  const loadData = useCallback(async () => {
    setDbLoading(true);
    try {
      await DB.seedIfEmpty();
      const data = await DB.loadAll();
      setCats(data.cats);
      setProducts(data.products);
      setLocations(data.locations);
      setRepackRules(data.repackRules);
      setStores(data.stores);
      setStocks(data.stocks);
      stocksRef.current = data.stocks;
      setHistory(data.history);
      setReservations(data.reservations);
      setConsLedger(data.consLedger);
    } catch (e) {
      console.error('[App] loadData error:', e);
      showToastImmediate("โหลดข้อมูลไม่สำเร็จ — ตรวจ Supabase config", "err");
    } finally {
      setDbLoading(false);
    }
  }, []);

  const [recoveryMode, setRecoveryMode] = useState(false);

  // ─── Auth: restore session on page load ─────────────────────────
  useEffect(() => {
    DB.getSession().then(session => {
      if (session) {
        setUsername(DB.getDisplayName(session));
        setLoggedIn(true);
      }
      setAuthLoading(false);
    });

    const { data: { subscription } } = DB.onAuthStateChange((event, session) => {
      if (event === 'PASSWORD_RECOVERY') {
        // User clicked reset link — show set-new-password form instead of app
        setRecoveryMode(true);
        setLoggedIn(false);
      } else if (event === 'SIGNED_IN' && session && !recoveryMode) {
        setUsername(DB.getDisplayName(session));
        setLoggedIn(true);
      } else if (event === 'SIGNED_OUT') {
        setRecoveryMode(false);
        setLoggedIn(false);
        setUsername('');
        setCats([]); setProducts([]); setLocations([]); setRepackRules([]);
        setStores([]); setStocks([]); setHistory([]); setReservations([]); setConsLedger([]);
      }
    });
    return () => subscription.unsubscribe();
  }, []);

  // ─── Load data after login ────────────────────────────────────────
  useEffect(() => {
    if (loggedIn) loadData();
  }, [loggedIn, loadData]);

  // ─── Realtime subscriptions (cross-user sync) ─────────────────────
  useEffect(() => {
    if (!loggedIn) return;

    const unsub = DB.subscribeToChanges({
      onStocksChange: async () => {
        if (Date.now() - lastWriteRef.current < ECHO_MS) return;
        const fresh = await DB.reloadStocks();
        if (fresh) { setStocks(fresh); stocksRef.current = fresh; }
      },
      onHistoryChange: async () => {
        if (Date.now() - lastWriteRef.current < ECHO_MS) return;
        const fresh = await DB.reloadHistory();
        if (fresh) setHistory(fresh);
      },
      onReservationsChange: async () => {
        if (Date.now() - lastWriteRef.current < ECHO_MS) return;
        const fresh = await DB.reloadReservations();
        if (fresh) setReservations(fresh);
      },
    });

    return unsub;
  }, [loggedIn]);

  // ─── Async save helpers ───────────────────────────────────────────
  const saveCats    = useCallback(v => { setCats(v);        DB.saveCategories(v);  }, []);
  const saveProds   = useCallback(v => { setProducts(v);    DB.saveProducts(v);    }, []);
  const saveLocs    = useCallback(v => { setLocations(v);   DB.saveLocations(v);   }, []);
  const saveRepack  = useCallback(v => { setRepackRules(v); DB.saveRepackRules(v); }, []);
  const saveStores  = useCallback(v => { setStores(v);      DB.saveStores(v);      }, []);
  const saveConsLedger = useCallback(v => { setConsLedger(v); DB.saveConsLedger(v); }, []);

  // ─── Consignment helpers ─────────────────────────────────────────
  // SEND stock from บ้าน → branch (one-step; deducts home stock + increments branch sentQty for current month)
  const doConsignmentSend = useCallback((storeId, branchId, items, note) => {
    const baan = locations.find(l => l.name === "บ้าน") || locations.find(l => l.isStorage);
    if (!baan) { showToast("ไม่พบคลังบ้าน", "err"); return false; }
    const store = stores.find(s => s.id === storeId);
    const branch = store?.branches.find(b => b.id === branchId);
    if (!branch) { showToast("กรุณาเลือกสาขา", "err"); return false; }

    let ns = [...stocks];
    for (const item of items) {
      const avail = ns.filter(s => s.skuId === item.skuId && s.locId === baan.id).reduce((a, b) => a + b.qty, 0);
      const p = products.find(x => x.id === item.skuId);
      if (avail < item.qty) { showToast(`${p?.sku} ในบ้านมีแค่ ${avail}`, "err"); return false; }
    }
    const logParts = [];
    for (const item of items) {
      const result = fifoDeduct(item.skuId, baan.id, item.qty, ns);
      if (!result) return false;
      ns = result;
      const p = products.find(x => x.id === item.skuId);
      logParts.push(`${p?.sku}×${item.qty}`);
    }
    saveStocks(ns);

    const yr = THIS_YEAR, mo = THIS_MONTH;
    let updated = [...consLedger];
    for (const item of items) {
      const idx = updated.findIndex(e => e.branchId === branchId && e.skuId === item.skuId && e.year === yr && e.month === mo);
      if (idx >= 0) updated[idx] = { ...updated[idx], sentQty: (updated[idx].sentQty || 0) + item.qty };
      else updated.push({ id: uid(), skuId: item.skuId, storeId, branchId, year: yr, month: mo, sentQty: item.qty, soldQty: 0, returnQty: 0, adjQty: 0 });
    }
    setConsLedger(updated);
    lastWriteRef.current = Date.now();
    DB.saveConsLedger(updated);

    addLog("ฝาก Consignment", `${store?.name} / ${branch?.name} | ${logParts.join(", ")}${note ? " | " + note : ""}`);
    showToast(`✓ ฝาก ${items.length} รายการ → ${branch?.name}`);
    return true;
  }, [stocks, locations, products, stores, consLedger, addLog, saveStocks, showToast]);

  // REPORT sales from a branch (deducts branch balance via soldQty, no effect on main stock)
  const doConsignmentReport = useCallback((storeId, branchId, items, note) => {
    const getBranchBal = (skuId) => consLedger
      .filter(e => e.branchId === branchId && e.skuId === skuId)
      .reduce((a, e) => a + (e.sentQty || 0) - (e.soldQty || 0) - (e.returnQty || 0) + (e.adjQty || 0), 0);

    for (const item of items) {
      const bal = getBranchBal(item.skuId);
      const p = products.find(x => x.id === item.skuId);
      if (bal < item.qty) { showToast(`${p?.sku} ในสาขามีแค่ ${bal}`, "err"); return false; }
    }

    const yr = THIS_YEAR, mo = THIS_MONTH;
    let updated = [...consLedger];
    const logParts = [];
    for (const item of items) {
      const idx = updated.findIndex(e => e.branchId === branchId && e.skuId === item.skuId && e.year === yr && e.month === mo);
      if (idx >= 0) updated[idx] = { ...updated[idx], soldQty: (updated[idx].soldQty || 0) + item.qty };
      else updated.push({ id: uid(), skuId: item.skuId, storeId, branchId, year: yr, month: mo, sentQty: 0, soldQty: item.qty, returnQty: 0, adjQty: 0 });
      const p = products.find(x => x.id === item.skuId);
      logParts.push(`${p?.sku}×${item.qty}`);
    }
    setConsLedger(updated);
    lastWriteRef.current = Date.now();
    DB.saveConsLedger(updated);

    const store = stores.find(s => s.id === storeId);
    const branch = store?.branches.find(b => b.id === branchId);
    addLog("ตัดยอดขาย Consignment", `${store?.name} / ${branch?.name} | ${logParts.join(", ")}${note ? " | " + note : ""}`);
    showToast(`✓ บันทึกยอดขาย ${items.length} รายการ`);
    return true;
  }, [consLedger, products, stores, addLog, showToast]);

  // Audit a consignment branch: compare actual count vs ledger balance, adjust adjQty for current month
  const doAuditConsignment = useCallback((storeId, branchId, entries, note) => {
    const store = stores.find(s => s.id === storeId);
    const branch = store?.branches.find(b => b.id === branchId);
    if (!branch) { showToast("ไม่พบสาขา", "err"); return false; }

    const yr = THIS_YEAR, mo = THIS_MONTH;
    let updated = [...consLedger];
    const newHistEntries = [];

    for (const e of entries) {
      const curBal = consLedger
        .filter(x => x.branchId === branchId && x.skuId === e.skuId)
        .reduce((a, x) => a + (x.sentQty || 0) - (x.soldQty || 0) - (x.returnQty || 0) + (x.adjQty || 0), 0);
      const diff = e.actual - curBal;
      if (diff === 0) continue;

      const idx = updated.findIndex(x => x.branchId === branchId && x.skuId === e.skuId && x.year === yr && x.month === mo);
      if (idx >= 0) updated[idx] = { ...updated[idx], adjQty: (updated[idx].adjQty || 0) + diff };
      else updated.push({ id: uid(), skuId: e.skuId, storeId, branchId, year: yr, month: mo, sentQty: 0, soldQty: 0, returnQty: 0, adjQty: diff });

      const p = products.find(x => x.id === e.skuId);
      newHistEntries.push({
        id: uid(), ts: new Date().toISOString(), user: username,
        action: "ปรับ Audit Consignment",
        detail: `${p?.sku}@${store?.name}/${branch?.name} ระบบ:${curBal}→จริง:${e.actual}(${diff > 0 ? "+" : ""}${diff})${note ? " | " + note : ""}`,
      });
    }

    if (!newHistEntries.length) { showToast("ไม่มีรายการที่เปลี่ยน"); return false; }

    setConsLedger(updated);
    lastWriteRef.current = Date.now();
    DB.saveConsLedger(updated);
    setHistory(prev => [...newHistEntries, ...prev].slice(0, 3000));
    DB.batchAddHistory(newHistEntries);
    showToast(`✓ Audit ${newHistEntries.length} รายการ`);
    return true;
  }, [consLedger, products, stores, username, showToast]);

  // Set initial/opening balance for a branch+sku (uses adjQty of current month with history note)
  const doConsignmentInitial = useCallback((storeId, branchId, items, note) => {
    const yr = THIS_YEAR, mo = THIS_MONTH;
    let updated = [...consLedger];
    const logParts = [];
    for (const item of items) {
      const q = parseInt(item.qty) || 0;
      if (q <= 0) continue;
      const idx = updated.findIndex(e => e.branchId === branchId && e.skuId === item.skuId && e.year === yr && e.month === mo);
      if (idx >= 0) updated[idx] = { ...updated[idx], adjQty: (updated[idx].adjQty || 0) + q };
      else updated.push({ id: uid(), skuId: item.skuId, storeId, branchId, year: yr, month: mo, sentQty: 0, soldQty: 0, returnQty: 0, adjQty: q });
      const p = products.find(x => x.id === item.skuId);
      logParts.push(`${p?.sku}×${q}`);
    }
    setConsLedger(updated);
    lastWriteRef.current = Date.now();
    DB.saveConsLedger(updated);

    const store = stores.find(s => s.id === storeId);
    const branch = store?.branches.find(b => b.id === branchId);
    addLog("ยอดตั้งต้น Consignment", `${store?.name} / ${branch?.name} | ${logParts.join(", ")}${note ? " | " + note : ""}`);
    showToast(`✓ บันทึกยอดตั้งต้น ${logParts.length} รายการ`);
    return true;
  }, [consLedger, products, stores, addLog, showToast]);

  const saveReservations = useCallback(v => {
    setReservations(v);
    lastWriteRef.current = Date.now();
    DB.saveReservations(v);
  }, []);

  const saveStocks = useCallback(v => {
    const prev = stocksRef.current;
    setStocks(v);
    stocksRef.current = v;
    lastWriteRef.current = Date.now();
    DB.saveStocks(v, prev);
  }, []);

  const addLog = useCallback((action, detail) => {
    const entry = { id: uid(), ts: new Date().toISOString(), user: username, action, detail };
    setHistory(prev => [entry, ...prev].slice(0, 3000));
    lastWriteRef.current = Date.now();
    DB.addHistory(entry);
    return entry;
  }, [username]);

  // ─── Toast (needs to work before loggedIn too) ────────────────────
  const showToastImmediate = (msg, type = "ok") => {
    setToast({ msg, type });
    setTimeout(() => setToast(null), 2800);
  };
  const showToast = useCallback((msg, type = "ok") => showToastImmediate(msg, type), []);
  const askConfirm = useCallback((msg, sub, onOk) => setConfirmDlg({ msg, sub, onOk }), []);

  const catMap = useMemo(() => Object.fromEntries(cats.map(c => [c.id, c])), [cats]);

  // ─── Stock helpers ────────────────────────────────────────────────
  const getQty    = useCallback((skuId, locId) => stocks.filter(s => s.skuId === skuId && s.locId === locId).reduce((a, b) => a + b.qty, 0), [stocks]);
  const getTot    = useCallback((skuId)         => stocks.filter(s => s.skuId === skuId).reduce((a, b) => a + b.qty, 0), [stocks]);
  const getLocTot = useCallback((locId)         => stocks.filter(s => s.locId === locId).reduce((a, b) => a + b.qty, 0), [stocks]);
  const stockCount = useCallback((pid)          => stocks.filter(s => s.skuId === pid).reduce((a, b) => a + b.qty, 0), [stocks]);

  const stopScan = useCallback(() => {
    if (scanStreamRef.current) { scanStreamRef.current.getTracks().forEach(t => t.stop()); scanStreamRef.current = null; }
  }, []);

  // ─── Operations ───────────────────────────────────────────────────
  const doBatchIn = useCallback((locId, items, note) => {
    const loc = locations.find(x => x.id === locId);
    const ns = [...stocks];
    const logParts = [];
    items.forEach(({ skuId, qty, exp, lot }) => {
      const p = products.find(x => x.id === skuId); if (!p) return;
      const ex = ns.find(s => s.skuId === skuId && s.locId === locId && s.lot === lot && s.expDate === exp);
      if (ex) ex.qty += qty;
      else ns.push({ id: uid(), skuId, locId, qty, expDate: exp, lot, ts: new Date().toISOString() });
      logParts.push(`${p.sku}×${qty}`);
    });
    saveStocks(ns);
    addLog("นำเข้า", `→${loc.name} | ${logParts.join(", ")}${note ? " | " + note : ""}`);
    showToast(`✓ นำเข้า ${items.length} รายการสำเร็จ`);
  }, [locations, products, stocks, addLog, saveStocks, showToast]);

  const doBatchOut = useCallback((locId, items, reason, note) => {
    const loc = locations.find(x => x.id === locId);
    let ns = [...stocks];
    const logParts = []; let ok = true;
    for (const { skuId, qty } of items) {
      const p = products.find(x => x.id === skuId); if (!p) continue;
      const result = fifoDeduct(skuId, locId, qty, ns);
      if (!result) { showToast(`สต็อค ${p.sku} ไม่พอ (ต้องการ ${qty})`, "err"); ok = false; break; }
      ns = result; logParts.push(`${p.sku}×${qty}`);
    }
    if (!ok) return false;
    saveStocks(ns);
    addLog("นำออก", `จาก${loc.name} | ${logParts.join(", ")} | ${reason}${note ? " | " + note : ""}`);
    showToast(`✓ นำออก ${items.length} รายการสำเร็จ`);
    return true;
  }, [locations, products, stocks, addLog, saveStocks, showToast]);

  const doBatchTransfer = useCallback((fromId, toId, items, note) => {
    const fl = locations.find(x => x.id === fromId), tl = locations.find(x => x.id === toId);
    let ns = [...stocks];
    const logParts = [];
    for (const { skuId, qty } of items) {
      const p = products.find(x => x.id === skuId); if (!p) continue;
      const bs = ns.filter(s => s.skuId === skuId && s.locId === fromId).sort((a, b) => {
        if (!a.expDate && !b.expDate) return new Date(a.ts) - new Date(b.ts);
        if (!a.expDate) return 1; if (!b.expDate) return -1;
        return new Date(a.expDate) - new Date(b.expDate);
      });
      if (bs.reduce((a, b) => a + b.qty, 0) < qty) { showToast(`${p.sku} ในต้นทางไม่พอ`, "err"); return false; }
      let rem = qty; const moved = [];
      for (const b of bs) { if (rem <= 0) break; const t = Math.min(b.qty, rem); b.qty -= t; rem -= t; moved.push({ expDate: b.expDate, lot: b.lot, qty: t, ts: b.ts }); }
      ns = ns.filter(s => s.qty > 0);
      for (const m of moved) {
        const ex = ns.find(s => s.skuId === skuId && s.locId === toId && s.lot === m.lot && s.expDate === m.expDate);
        if (ex) ex.qty += m.qty;
        else ns.push({ id: uid(), skuId, locId: toId, qty: m.qty, expDate: m.expDate, lot: m.lot, ts: m.ts });
      }
      logParts.push(`${p.sku}×${qty}`);
    }
    saveStocks(ns);
    addLog("โอนย้าย", `${fl?.name}→${tl?.name} | ${logParts.join(", ")}${note ? " | " + note : ""}`);
    showToast(`✓ โอน ${items.length} รายการ → ${tl?.name}`);
    return true;
  }, [products, locations, stocks, addLog, saveStocks, showToast]);

  const doTransfer = useCallback((skuId, fromId, toId, qty, note) => {
    const p = products.find(x => x.id === skuId);
    const fl = locations.find(x => x.id === fromId), tl = locations.find(x => x.id === toId);
    let ns = [...stocks];
    const bs = ns.filter(s => s.skuId === skuId && s.locId === fromId).sort((a, b) => {
      if (!a.expDate && !b.expDate) return new Date(a.ts) - new Date(b.ts);
      if (!a.expDate) return 1; if (!b.expDate) return -1;
      return new Date(a.expDate) - new Date(b.expDate);
    });
    if (bs.reduce((a, b) => a + b.qty, 0) < qty) { showToast("สต็อคไม่พอ", "err"); return false; }
    let rem = qty; const moved = [];
    for (const b of bs) { if (rem <= 0) break; const t = Math.min(b.qty, rem); b.qty -= t; rem -= t; moved.push({ expDate: b.expDate, lot: b.lot, qty: t, ts: b.ts }); }
    ns = ns.filter(s => s.qty > 0);
    for (const m of moved) {
      const ex = ns.find(s => s.skuId === skuId && s.locId === toId && s.lot === m.lot && s.expDate === m.expDate);
      if (ex) ex.qty += m.qty;
      else ns.push({ id: uid(), skuId, locId: toId, qty: m.qty, expDate: m.expDate, lot: m.lot, ts: m.ts });
    }
    saveStocks(ns);
    addLog("โอนย้าย", `${p.sku} ${qty}${p.unit} | ${fl.name}→${tl.name}${note ? " | " + note : ""}`);
    showToast(`✓ โอน ${qty} ${p.unit} → ${tl.name}`);
    return true;
  }, [products, locations, stocks, addLog, saveStocks, showToast]);

  const doRepack = useCallback((parentId, childId, qtyParent, locId, note) => {
    const pp = products.find(x => x.id === parentId), cp = products.find(x => x.id === childId);
    const rule = repackRules.find(r => r.parentSku === pp?.sku && r.childSku === cp?.sku);
    const childQty = qtyParent * (rule?.ratio || 1);
    let ns = [...stocks];
    const result = fifoDeduct(parentId, locId, qtyParent, ns);
    if (!result) { showToast(`สต็อค ${pp?.sku} ไม่พอ`, "err"); return false; }
    ns = result;
    const ex = ns.find(s => s.skuId === childId && s.locId === locId && !s.expDate && !s.lot);
    if (ex) ex.qty += childQty;
    else ns.push({ id: uid(), skuId: childId, locId, qty: childQty, expDate: "", lot: "", ts: new Date().toISOString() });
    saveStocks(ns);
    addLog("Re-pack", `${pp.sku}×${qtyParent}→${cp.sku}×${childQty}${note ? " | " + note : ""}`);
    showToast(`✓ Re-pack → ${childQty} ${cp.unit}`);
    return true;
  }, [products, repackRules, stocks, addLog, saveStocks, showToast]);

  // Edit lot/exp/qty of a single stock batch (with audit log)
  const doEditBatch = useCallback((stockId, updates) => {
    const cur = stocksRef.current.find(s => s.id === stockId);
    if (!cur) return false;
    const p = products.find(x => x.id === cur.skuId);
    const loc = locations.find(x => x.id === cur.locId);
    const changes = [];
    if ("lot" in updates && updates.lot !== cur.lot) changes.push(`lot: "${cur.lot || "—"}" → "${updates.lot || "—"}"`);
    if ("expDate" in updates && updates.expDate !== cur.expDate) changes.push(`exp: ${cur.expDate || "—"} → ${updates.expDate || "—"}`);
    if ("qty" in updates && updates.qty !== cur.qty) changes.push(`qty: ${cur.qty} → ${updates.qty}`);
    if (!changes.length) return false;

    let ns = stocksRef.current.map(s => s.id === stockId ? { ...s, ...updates, ts: new Date().toISOString() } : s);
    if ((updates.qty || 0) <= 0) ns = ns.filter(s => s.id !== stockId);
    saveStocks(ns);
    addLog("แก้ไข Batch", `${p?.sku}@${loc?.name} | ${changes.join(", ")}`);
    showToast("✓ บันทึกการแก้ไข batch");
    return true;
  }, [products, locations, saveStocks, addLog, showToast]);

  const doAudit = useCallback((entries, note) => {
    let ns = [...stocks];
    const newEntries = [];
    entries.forEach(e => {
      const p = products.find(x => x.id === e.skuId), l = locations.find(x => x.id === e.locId);
      const sys = ns.filter(s => s.skuId === e.skuId && s.locId === e.locId).reduce((a, b) => a + b.qty, 0);
      const diff = e.actual - sys;
      if (diff === 0) return;
      if (diff > 0) {
        const ex = ns.find(s => s.skuId === e.skuId && s.locId === e.locId && !s.expDate && !s.lot);
        if (ex) ex.qty += diff;
        else ns.push({ id: uid(), skuId: e.skuId, locId: e.locId, qty: diff, expDate: "", lot: "", ts: new Date().toISOString() });
      } else {
        let rem = Math.abs(diff);
        const bs = ns.filter(s => s.skuId === e.skuId && s.locId === e.locId).sort((a, b) => new Date(a.ts) - new Date(b.ts));
        for (const b of bs) { if (rem <= 0) break; const t = Math.min(b.qty, rem); b.qty -= t; rem -= t; }
        ns = ns.filter(s => s.qty > 0);
      }
      const entry = { id: uid(), ts: new Date().toISOString(), user: username, action: "ปรับ Audit",
        detail: `${p.sku}@${l.name} ระบบ:${sys}→จริง:${e.actual}(${diff > 0 ? "+" : ""}${diff})${note ? " | " + note : ""}` };
      newEntries.push(entry);
    });
    saveStocks(ns);
    if (newEntries.length) {
      setHistory(prev => [...newEntries, ...prev].slice(0, 3000));
      lastWriteRef.current = Date.now();
      DB.batchAddHistory(newEntries);
    }
    showToast("✓ บันทึก Audit สำเร็จ");
  }, [products, locations, stocks, username, saveStocks, showToast]);

  const doFulfillReservation = useCallback((resId) => {
    const res = reservations.find(r => r.id === resId);
    if (!res || res.status !== "pending") return;
    const baan = locations.find(l => l.name === "บ้าน") || locations.find(l => l.isStorage);
    if (!baan) { showToast("ไม่พบคลังบ้าน", "err"); return false; }
    let ns = [...stocks];
    for (const item of res.items) {
      const avail = ns.filter(s => s.skuId === item.skuId && s.locId === baan.id).reduce((a, b) => a + b.qty, 0);
      const p = products.find(x => x.id === item.skuId);
      if (avail < item.qty) { showToast(`${p?.sku} ในบ้านมีแค่ ${avail}`, "err"); return false; }
    }
    const logParts = [];
    for (const item of res.items) {
      const result = fifoDeduct(item.skuId, baan.id, item.qty, ns);
      if (!result) { showToast("สต็อคไม่พอ", "err"); return false; }
      ns = result;
      const p = products.find(x => x.id === item.skuId);
      logParts.push(`${p?.sku}×${item.qty}`);
    }
    saveStocks(ns);
    saveReservations(reservations.map(r => r.id === resId ? { ...r, status: "fulfilled", fulfilledAt: new Date().toISOString() } : r));
    addLog("Reservation Fulfilled", `[${res.type}] ${res.title} | ${logParts.join(", ")} | จากบ้าน`);
    showToast(`✓ Fulfill "${res.title}" สำเร็จ`);
    return true;
  }, [reservations, locations, stocks, products, addLog, saveStocks, saveReservations, showToast]);

  const onScanIn = useCallback((skuId, locId, qty) => {
    const p = products.find(x => x.id === skuId); if (!p) return;
    const ns = [...stocks];
    const ex = ns.find(s => s.skuId === skuId && s.locId === locId && !s.expDate && !s.lot);
    if (ex) ex.qty += qty;
    else ns.push({ id: uid(), skuId, locId, qty, expDate: "", lot: "", ts: new Date().toISOString() });
    saveStocks(ns);
    addLog("นำเข้า", `→${locations.find(l => l.id === locId)?.name} | ${p.sku}×${qty} | quick scan`);
    showToast(`✓ +${qty} ${p.unit}`);
  }, [products, stocks, locations, addLog, saveStocks, showToast]);

  const onScanOut = useCallback((skuId, locId, qty) => {
    const p = products.find(x => x.id === skuId); if (!p) return;
    let ns = [...stocks];
    const result = fifoDeduct(skuId, locId, qty, ns);
    if (!result) { showToast(`สต็อค ${p.sku} ไม่พอ`, "err"); return; }
    saveStocks(result);
    addLog("นำออก", `จาก${locations.find(l => l.id === locId)?.name} | ${p.sku}×${qty} | quick scan`);
    showToast(`✓ -${qty} ${p.unit}`);
  }, [products, stocks, locations, addLog, saveStocks, showToast]);

  const exportCSV = useCallback(() => {
    let c = "﻿ประเภท,วันที่เวลา,ผู้ใช้,รายละเอียด\n";
    history.forEach(h => { c += `"${h.action}","${fmtDT(h.ts)}","${h.user}","${h.detail}"\n`; });
    c += "\n\nสรุปสต็อค\nSKU,ชื่อ,หมวด,คลัง,จำนวน\n";
    products.forEach(p => {
      const cat = catMap[p.catId];
      locations.forEach(l => { const q = getQty(p.id, l.id); if (q > 0) c += `"${p.sku}","${p.name}","${cat?.name || ""}","${l.name}",${q}\n`; });
    });
    const b = new Blob([c], { type: "text/csv;charset=utf-8" });
    const a = document.createElement("a");
    a.href = URL.createObjectURL(b);
    a.download = `XREAL_${new Date().toISOString().slice(0, 10)}.csv`;
    a.click();
    showToast("✓ Export แล้ว");
  }, [history, products, locations, catMap, getQty, showToast]);

  const goTab = useCallback((id, payload) => {
    stopScan();
    setTabRaw(id);
    setTabPayload(payload || null);
    setHistFilter("ทั้งหมด");
  }, [stopScan]);

  const handleLogout = useCallback(() => {
    stopScan();
    DB.signOut();
  }, [stopScan]);

  // ─── Render gates ─────────────────────────────────────────────────
  if (authLoading) return <SplashScreen msg="กำลังตรวจสอบ session…"/>;
  if (recoveryMode) return <SetNewPasswordScreen onDone={() => { setRecoveryMode(false); DB.signOut(); }}/>;
  if (!loggedIn)   return <LoginScreen onLogin={setLoggedIn} onSetUser={setUsername}/>;
  if (dbLoading)   return <SplashScreen msg="กำลังโหลดข้อมูลจาก Supabase…"/>;

  const expiring = stocks.filter(s => ["warn", "expired"].includes(expStatus(s.expDate))).length;
  const pending  = reservations.filter(r => r.status === "pending").length;

  return (
    <div style={{ display: "flex", minHeight: "100vh", background: "var(--bg)" }}>
      <Sidebar tab={tab} setTab={goTab} username={username}
        onLogout={handleLogout}
        stocks={stocks} products={products} locations={locations} reservations={reservations}
        onTweaks={() => setTweaksOpen(true)}/>

      <main style={{ flex: 1, display: "flex", flexDirection: "column", minWidth: 0, paddingBottom: "var(--mobile-nav-h)" }} className="xr-main">
        <Topbar
          title={PAGE_TITLES[tab]} sub={PAGE_SUBS[tab]}
          expiringCount={expiring} pendingCount={pending}
          tab={tab} setTab={goTab}
          theme={tweaks.theme}
          onToggleTheme={() => setTweak("theme", tweaks.theme === "dark" ? "light" : "dark")}/>

        <section style={{ flex: 1, padding: "20px 22px", overflow: "auto" }} className="xr-content">
          {tab === "dashboard"  && <Dashboard products={products} locations={locations} stocks={stocks} cats={cats} catMap={catMap} getQty={getQty} getTot={getTot} getLocTot={getLocTot} history={history} reservations={reservations} setTab={goTab}/>}
          {tab === "quick"      && <QuickScanPage products={products} cats={cats} locations={locations} stocks={stocks} getQty={getQty} getTot={getTot} onScanIn={onScanIn} onScanOut={onScanOut} onAudit={doAudit} showToast={showToast} scanStreamRef={scanStreamRef} setTab={goTab}/>}
          {tab === "in"         && <BatchInForm products={products} cats={cats} locations={locations} onSubmit={doBatchIn} showToast={showToast} scanStreamRef={scanStreamRef} prefill={tabPayload?.prefill}/>}
          {tab === "out"        && <BatchOutForm products={products} cats={cats} locations={locations} stocks={stocks} stores={stores} consLedger={consLedger} getQty={getQty} getTot={getTot} onSubmit={doBatchOut} onConsSend={doConsignmentSend} onConsReport={doConsignmentReport} showToast={showToast} scanStreamRef={scanStreamRef} prefill={tabPayload?.prefill}/>}
          {tab === "tr"         && <TransferForm products={products} cats={cats} locations={locations} stocks={stocks} getTot={getTot} getQty={getQty} onSubmit={doTransfer} onBatchSubmit={doBatchTransfer} showToast={showToast} scanStreamRef={scanStreamRef} prefill={tabPayload?.prefill}/>}
          {tab === "repack"     && <RepackForm products={products} cats={cats} locations={locations} stocks={stocks} repackRules={repackRules} getQty={getQty} onSubmit={doRepack} showToast={showToast} onSaveRules={saveRepack} askConfirm={askConfirm}/>}
          {tab === "reserve"    && <ReservationPage products={products} cats={cats} catMap={catMap} locations={locations} stocks={stocks} reservations={reservations} getTot={getTot} getQty={getQty} onSave={saveReservations} onFulfill={doFulfillReservation} showToast={showToast} askConfirm={askConfirm}/>}
          {tab === "cons"       && <ConsignmentModule products={products} cats={cats} stores={stores} consLedger={consLedger} onSaveStores={saveStores} onSaveLedger={saveConsLedger} onSetInitial={doConsignmentInitial} showToast={showToast} askConfirm={askConfirm}/>}
          {tab === "forecast"   && <ForecastPage products={products} cats={cats} catMap={catMap} stocks={stocks} locations={locations} history={history} getTot={getTot} getQty={getQty} consLedger={consLedger} stores={stores} reservations={reservations}/>}
          {tab === "audit"      && <AuditPage products={products} locations={locations} stocks={stocks} stores={stores} consLedger={consLedger} getQty={getQty} onSubmit={doAudit} onEditBatch={doEditBatch} onAuditCons={doAuditConsignment} prefill={tabPayload?.prefill}/>}
          {tab === "hist"       && <HistoryPage history={history} filter={histFilter} setFilter={setHistFilter} onExport={exportCSV}/>}
          {tab === "settings"   && <SettingsPage cats={cats} products={products} locations={locations} repackRules={repackRules} stocks={stocks} stockCount={stockCount} onSaveCats={saveCats} onSaveProds={saveProds} onSaveLocs={saveLocs} onSaveRepack={saveRepack} showToast={showToast} askConfirm={askConfirm}/>}
        </section>
      </main>

      <MobileNav tab={tab} setTab={goTab} onMore={() => setMobileMore(true)}/>
      <MobileMoreSheet open={mobileMore} onClose={() => setMobileMore(false)} tab={tab} setTab={goTab}
        onTweaks={() => setTweaksOpen(true)} onLogout={handleLogout} username={username}/>

      {toast     && <Toast msg={toast.msg} type={toast.type}/>}
      {confirmDlg && <ConfirmModal msg={confirmDlg.msg} sub={confirmDlg.sub}
        onOk={() => { confirmDlg.onOk(); setConfirmDlg(null); }}
        onCancel={() => setConfirmDlg(null)}/>}

      {tweaksOpen && (
        <TweaksPanel open={tweaksOpen} onClose={() => setTweaksOpen(false)} title="ปรับธีม / Tweaks">
          <TweakSection title="Theme">
            <TweakRadio label="Mode" options={[{ label:"Light",value:"light" },{ label:"Dark",value:"dark" }]} value={tweaks.theme} onChange={v => setTweak("theme", v)}/>
          </TweakSection>
          <TweakSection title="Accent color">
            <TweakColor label="Accent" value={tweaks.accentColor} onChange={v => setTweak("accentColor", v)} options={Object.keys(ACCENT_PRESETS)}/>
          </TweakSection>
          <TweakSection title="Density">
            <TweakRadio label="Spacing" options={[{ label:"Compact",value:"compact" },{ label:"Normal",value:"comfortable" },{ label:"Spacious",value:"spacious" }]} value={tweaks.density} onChange={v => setTweak("density", v)}/>
          </TweakSection>
        </TweaksPanel>
      )}
    </div>
  );
}

// ─── Splash / Loading screen ──────────────────────────────────────────
function SplashScreen({ msg }) {
  return (
    <div style={{ display:"flex", flexDirection:"column", alignItems:"center", justifyContent:"center", minHeight:"100vh", background:"var(--bg)", gap:16 }}>
      <XRealLogoMark size={48}/>
      <div style={{ fontSize:13, color:"var(--text-2)" }}>{msg || "กำลังโหลด…"}</div>
    </div>
  );
}

// ─── Set New Password screen (after reset link) ──────────────────────
function SetNewPasswordScreen({ onDone }) {
  const [pw,      setPw]      = useState("");
  const [pw2,     setPw2]     = useState("");
  const [loading, setLoading] = useState(false);
  const [msg,     setMsg]     = useState("");

  const submit = async () => {
    setMsg("");
    if (!pw.trim()) { setMsg("กรุณากรอกรหัสผ่านใหม่"); return; }
    if (pw.length < 6) { setMsg("รหัสผ่านต้องมีอย่างน้อย 6 ตัวอักษร"); return; }
    if (pw !== pw2) { setMsg("รหัสผ่านทั้งสองช่องไม่ตรงกัน"); return; }
    setLoading(true);
    try {
      await DB.updatePassword(pw);
      setMsg("✓ เปลี่ยนรหัสผ่านสำเร็จ! กำลังกลับหน้า Login…");
      setTimeout(onDone, 1800);
    } catch (e) {
      setMsg(e.message || "เกิดข้อผิดพลาด");
    } finally {
      setLoading(false);
    }
  };

  return (
    <div style={{ display:"flex",alignItems:"center",justifyContent:"center",minHeight:"100vh",background:"var(--bg)",padding:20 }}>
      <div className="xr-card" style={{ width:"100%",maxWidth:400,padding:36,textAlign:"center" }}>
        <div style={{ display:"flex",justifyContent:"center",marginBottom:16 }}>
          <XRealLogoMark size={48}/>
        </div>
        <div style={{ fontSize:20,fontWeight:800,marginBottom:4 }}>ตั้งรหัสผ่านใหม่</div>
        <div style={{ fontSize:13,color:"var(--text-3)",marginBottom:24 }}>กรอกรหัสผ่านใหม่ที่ต้องการ</div>
        <div style={{ display:"flex",flexDirection:"column",gap:12,marginBottom:16,textAlign:"left" }}>
          <FG label="รหัสผ่านใหม่">
            <input className="xr-input" type="password" placeholder="อย่างน้อย 6 ตัวอักษร" value={pw}
              onChange={e => setPw(e.target.value)}
              onKeyDown={e => e.key === "Enter" && submit()}
              autoCapitalize="none" autoCorrect="off" autoComplete="new-password" autoFocus/>
          </FG>
          <FG label="ยืนยันรหัสผ่านใหม่">
            <input className="xr-input" type="password" placeholder="กรอกซ้ำอีกครั้ง" value={pw2}
              onChange={e => setPw2(e.target.value)}
              onKeyDown={e => e.key === "Enter" && submit()}
              autoCapitalize="none" autoCorrect="off" autoComplete="new-password"/>
          </FG>
        </div>
        {msg && (
          <div style={{ fontSize:12, color: msg.startsWith("✓") ? "var(--ok)" : "var(--err)",
            background: msg.startsWith("✓") ? "var(--ok-bg)" : "var(--err-bg)",
            border:`1px solid ${msg.startsWith("✓") ? "var(--ok-border)" : "var(--err-border)"}`,
            borderRadius:8,padding:"8px 12px",marginBottom:12,textAlign:"left" }}>
            {msg}
          </div>
        )}
        <Btn variant="accent" size="lg" icon="check" onClick={submit} full disabled={loading}>
          {loading ? "กำลังบันทึก…" : "บันทึกรหัสผ่านใหม่"}
        </Btn>
      </div>
    </div>
  );
}

// ─── Login / Sign-up screen ───────────────────────────────────────────
function LoginScreen({ onLogin, onSetUser }) {
  const [mode,     setMode]     = useState("login");  // "login" | "signup" | "forgot"
  const [ident,    setIdent]    = useState("");        // username or email (login)
  const [email,    setEmail]    = useState("");        // email (signup / forgot)
  const [username, setUsername] = useState("");        // username (signup)
  const [pw,       setPw]       = useState("");
  const [name,     setName]     = useState("");
  const [loading,  setLoading]  = useState(false);
  const [errMsg,   setErrMsg]   = useState("");

  const switchMode = m => { setMode(m); setErrMsg(""); };

  const submit = async () => {
    setErrMsg("");
    if (mode === "login") {
      if (!ident.trim() || !pw.trim()) { setErrMsg("กรุณากรอก Username/Email และ Password"); return; }
    } else if (mode === "signup") {
      if (!username.trim() || !email.trim() || !pw.trim()) { setErrMsg("กรุณากรอก Username, Email และ Password"); return; }
      if (username.includes('@')) { setErrMsg("Username ไม่ควรมี @ ใช้ตัวอักษรและตัวเลขเท่านั้น"); return; }
    } else {
      if (!email.trim()) { setErrMsg("กรุณากรอก Email ที่ใช้สมัคร"); return; }
    }
    setLoading(true);
    try {
      if (mode === "login") {
        await DB.signIn(ident.trim(), pw);
      } else if (mode === "signup") {
        const data = await DB.signUp(email.trim(), pw, name.trim() || username.trim(), username.trim());
        if (data.user && !data.session) {
          setErrMsg("✓ สมัครสำเร็จ! ตรวจสอบ Email เพื่อยืนยันก่อน Login (หรือ Admin ปิด confirm ใน Supabase)");
        }
      } else {
        await DB.resetPassword(email.trim());
        setErrMsg("✓ ส่ง reset link ไปที่ " + email.trim() + " แล้ว — ตรวจสอบ inbox (และ spam)");
      }
    } catch (e) {
      setErrMsg(e.message || "เกิดข้อผิดพลาด");
    } finally {
      setLoading(false);
    }
  };

  return (
    <div style={{ display:"flex",alignItems:"center",justifyContent:"center",minHeight:"100vh",background:"var(--bg)",padding:20,position:"relative",overflow:"hidden" }}>
      <div style={{ position:"absolute",width:400,height:400,borderRadius:"50%",background:"radial-gradient(circle,var(--accent-subtle) 0%,transparent 70%)",top:"-100px",right:"-100px",pointerEvents:"none" }}/>
      <div style={{ position:"absolute",width:360,height:360,borderRadius:"50%",background:"radial-gradient(circle,var(--info-bg) 0%,transparent 70%)",bottom:"-80px",left:"-80px",pointerEvents:"none" }}/>

      <div className="xr-card" style={{ width:"100%",maxWidth:400,padding:36,textAlign:"center",position:"relative" }}>
        <div style={{ display:"flex",justifyContent:"center",marginBottom:16 }}>
          <XRealLogoMark size={56}/>
        </div>
        <div style={{ fontSize:26,fontWeight:900,letterSpacing:2,marginBottom:2 }}>X-REAL</div>
        <div style={{ fontSize:11,color:"var(--text-3)",letterSpacing:2.5,marginBottom:6 }}>STOCK SYSTEM v5</div>
        <div style={{ fontSize:13,color:"var(--text-2)",marginBottom:28 }}>ระบบจัดการสต็อคยุคใหม่</div>

        {/* Mode toggle */}
        <div style={{ display:"flex",borderRadius:8,overflow:"hidden",border:"1px solid var(--border)",marginBottom:20 }}>
          {["login","signup"].map(m => (
            <button key={m} onClick={() => switchMode(m)}
              style={{ flex:1,padding:"8px 0",fontSize:13,fontWeight:(mode===m||mode==="forgot")&&m==="login"?600:mode===m?600:400,
                background:m==="login"?(mode==="login"||mode==="forgot")?"var(--accent)":"transparent":mode==="signup"?"var(--accent)":"transparent",
                color:m==="login"?(mode==="login"||mode==="forgot")?"#fff":"var(--text-2)":mode==="signup"?"#fff":"var(--text-2)",
                border:"none",cursor:"pointer" }}>
              {m === "login" ? "เข้าสู่ระบบ" : "สมัครสมาชิก"}
            </button>
          ))}
        </div>

        <div style={{ display:"flex",flexDirection:"column",gap:12,marginBottom:16,textAlign:"left" }}>
          {mode === "forgot" ? (
            <>
              <div style={{ fontSize:13,color:"var(--text-2)",marginBottom:4 }}>
                กรอก Email ที่ใช้สมัคร — ระบบจะส่ง link รีเซ็ตรหัสผ่านให้
              </div>
              <FG label="Email">
                <input className="xr-input" type="email" placeholder="you@example.com" value={email}
                  onChange={e => setEmail(e.target.value)}
                  onKeyDown={e => e.key === "Enter" && submit()}
                  autoCapitalize="none" autoCorrect="off" autoComplete="email"
                  autoFocus spellCheck="false"/>
              </FG>
            </>
          ) : mode === "login" ? (
            <>
              <FG label="Username หรือ Email">
                <input className="xr-input" placeholder="username หรือ you@example.com" value={ident}
                  onChange={e => setIdent(e.target.value)}
                  onKeyDown={e => e.key === "Enter" && submit()}
                  autoCapitalize="none" autoCorrect="off" autoComplete="username"
                  autoFocus spellCheck="false"/>
              </FG>
              <FG label="Password">
                <input className="xr-input" type="password" placeholder="••••••••" value={pw}
                  onChange={e => setPw(e.target.value)}
                  onKeyDown={e => e.key === "Enter" && submit()}
                  autoCapitalize="none" autoCorrect="off" autoComplete="current-password"/>
              </FG>
              <div style={{ textAlign:"right",marginTop:-4 }}>
                <button onClick={() => switchMode("forgot")} style={{ fontSize:12,color:"var(--accent)",background:"none",border:"none",cursor:"pointer",padding:0 }}>
                  ลืมรหัสผ่าน?
                </button>
              </div>
            </>
          ) : (
            <>
              <FG label="Username (ใช้ Login)">
                <input className="xr-input" placeholder="เช่น jin, xreal01" value={username}
                  onChange={e => setUsername(e.target.value.replace(/[^a-zA-Z0-9_.-]/g, ""))}
                  autoCapitalize="none" autoCorrect="off" autoComplete="username"
                  autoFocus spellCheck="false"/>
                <div style={{ fontSize:11,color:"var(--text-3)",marginTop:3 }}>ตัวอักษร a-z, 0-9 เท่านั้น</div>
              </FG>
              <FG label="ชื่อที่แสดง (ไม่บังคับ)">
                <input className="xr-input" placeholder="เช่น พี่จิน" value={name}
                  onChange={e => setName(e.target.value)}/>
              </FG>
              <FG label="Email">
                <input className="xr-input" type="email" placeholder="you@example.com" value={email}
                  onChange={e => setEmail(e.target.value)}
                  autoCapitalize="none" autoCorrect="off" autoComplete="email"/>
              </FG>
              <FG label="Password">
                <input className="xr-input" type="password" placeholder="••••••••" value={pw}
                  onChange={e => setPw(e.target.value)}
                  onKeyDown={e => e.key === "Enter" && submit()}
                  autoCapitalize="none" autoCorrect="off" autoComplete="new-password"/>
              </FG>
            </>
          )}
        </div>

        {errMsg && (
          <div style={{ fontSize:12,color: errMsg.startsWith("✓") ? "var(--ok)" : "var(--err)",
            background: errMsg.startsWith("✓") ? "var(--ok-bg)" : "var(--err-bg)",
            border:`1px solid ${errMsg.startsWith("✓") ? "var(--ok-border)" : "var(--err-border)"}`,
            borderRadius:8,padding:"8px 12px",marginBottom:12,textAlign:"left" }}>
            {errMsg}
          </div>
        )}

        <Btn variant="accent" size="lg" icon="arrow-right" onClick={submit} full disabled={loading}>
          {loading ? "กำลังโหลด…" : mode === "login" ? "เข้าสู่ระบบ" : mode === "signup" ? "สมัครสมาชิก" : "ส่ง Reset Link"}
        </Btn>
        {mode === "forgot" && (
          <button onClick={() => switchMode("login")} style={{ fontSize:12,color:"var(--text-3)",background:"none",border:"none",cursor:"pointer",marginTop:10 }}>
            ← กลับไปหน้า Login
          </button>
        )}
        <div style={{ fontSize:11,color:"var(--text-3)",marginTop:10 }}>
          {mode === "login" ? "Session จะถูกจดจำในเบราว์เซอร์นี้" : mode === "signup" ? "หลังสมัครแล้ว Login ด้วย Username ได้เลย" : "ตรวจสอบ inbox และ spam folder"}
        </div>
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App/>);
