/* ============================================================================
   MAIN — app shell, router, bottom nav, add-expense flow, tweaks.
   ============================================================================ */
const { useState, useEffect, useRef } = React;

const ACCENTS = {
  jade:    { teal: "#038387", dark: "#006666", name: "Jade" },
  lantern: { teal: "#ca5010", dark: "#8a4a16", name: "Lantern" },
  lotus:   { teal: "#b146c2", dark: "#7a1f8a", name: "Lotus" },
};

/* In-app Settings screen — appearance (light/dark) + translation API keys.
   Replaces the old floating tweaks panel. */
function SettingsScreen({ go, dark, setDark }) {
  const tr = window.translation;
  const [cfg, setCfg] = useState(() => tr ? tr.getConfig() : { provider: "free", key: "", model: "" });
  const update = (patch) => {
    const next = { ...cfg, ...patch };
    if (patch.provider) next.model = (tr && tr.DEFAULT_MODEL[patch.provider]) || "";
    if (tr) tr.setConfig(next);
    setCfg(next);
  };

  const pill = (active) => ({
    flex: 1, padding: "10px 8px", borderRadius: 11, cursor: "pointer", fontFamily: "var(--fontFamilyBase)",
    fontSize: 13.5, fontWeight: 600, textAlign: "center",
    border: active ? "1px solid var(--color-teal)" : "1px solid var(--colorNeutralStroke1)",
    background: active ? "rgba(3,131,135,0.10)" : "var(--colorNeutralBackground1)",
    color: active ? "var(--color-darkTeal)" : "var(--colorNeutralForeground2)",
  });

  const providers = [
    { id: "free", label: "Free" },
    { id: "gemini", label: "Gemini" },
    { id: "deepseek", label: "DeepSeek" },
    { id: "anthropic", label: "Claude" },
  ];
  const keyHint = {
    gemini: "Needs a free Google AI Studio key (ai.google.dev) — your Gemini app subscription does not include API access.",
    deepseek: "Use your DeepSeek API key (platform.deepseek.com).",
    anthropic: "Use your Anthropic API key (console.anthropic.com).",
  }[cfg.provider];

  return (
    <div style={{ minHeight: "100%", background: "var(--colorNeutralBackground2)" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "14px 16px",
        background: "var(--colorNeutralBackground1)", borderBottom: "1px solid var(--colorNeutralStroke2)",
        position: "sticky", top: 0, zIndex: 10 }}>
        <button onClick={() => go("home")} aria-label="back" style={{ width: 36, height: 36, borderRadius: 10,
          border: "1px solid var(--colorNeutralStroke2)", background: "var(--colorNeutralBackground1)",
          display: "inline-flex", alignItems: "center", justifyContent: "center", cursor: "pointer" }}>
          <Icon name="chevron_left" size={20} color="var(--colorNeutralForeground1)" />
        </button>
        <Serif size={20} weight={600}>Settings</Serif>
      </div>

      <div style={{ padding: 16, display: "flex", flexDirection: "column", gap: 20 }}>
        <Field label="Appearance">
          <div style={{ display: "flex", gap: 10 }}>
            <button onClick={() => setDark(false)} style={pill(!dark)}>Light</button>
            <button onClick={() => setDark(true)} style={pill(dark)}>Dark</button>
          </div>
        </Field>

        <Field label="Translation engine">
          <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
            {providers.map((p) => (
              <button key={p.id} onClick={() => update({ provider: p.id })}
                style={{ ...pill(cfg.provider === p.id), flex: "1 1 40%" }}>{p.label}</button>
            ))}
          </div>
          <div style={{ fontSize: 11.5, color: "var(--colorNeutralForeground3)", marginTop: 8, lineHeight: 1.45 }}>
            {cfg.provider === "free"
              ? "Free online translation (MyMemory) — no key, no cost. Voice in/out work without a key too."
              : "Your key is stored only on this device. " + (keyHint || "")}
          </div>
          {cfg.provider !== "free" && (
            <div style={{ marginTop: 12, display: "flex", flexDirection: "column", gap: 10 }}>
              <input type="password" value={cfg.key} placeholder="Paste API key" autoComplete="off"
                onChange={(e) => update({ key: e.target.value })} style={inputStyle} />
              <input type="text" value={cfg.model} placeholder={(tr && tr.DEFAULT_MODEL[cfg.provider]) || "model"}
                onChange={(e) => update({ model: e.target.value })} style={inputStyle} />
            </div>
          )}
        </Field>

        {window.db && window.db.configured && (
          <Field label="Account">
            <div style={{ fontSize: 12.5, color: "var(--colorNeutralForeground3)", marginBottom: 10 }}>Signed in to the shared trip on this device.</div>
            <Btn kind="ghost" onClick={() => window.db.auth.signOut()} full>Sign out</Btn>
          </Field>
        )}
      </div>
    </div>
  );
}

function App() {
  const T = window.TRIP;
  const [dark, setDark] = useState(() => { try { return localStorage.getItem("vn_theme") === "dark"; } catch (e) { return false; } });
  const toggleDark = (v) => { setDark(v); try { localStorage.setItem("vn_theme", v ? "dark" : "light"); } catch (e) {} };
  const [route, setRoute] = useState("home");
  const online = window.db.useOnline();
  const photos = usePhotos();
  const scrollRef = useRef(null);

  // shared data (Supabase, cached): expenses, toggle states, shared settings
  const expenseStore = window.db.useStore(window.db.expenses);
  const tog = window.db.useStore(window.db.toggles);
  window.db.useStore(window.db.settings); // pulls the shared Gemini key onto this device
  const expenses = expenseStore.list;
  const places = T.places.map((p) => ({ ...p, visited: tog.has("place", p.id) }));
  const dishes = T.dishes.map((d) => ({ ...d, tried: tog.has("dish", d.id) }));
  const restaurants = T.restaurants.map((r) => ({ ...r, bookmarked: tog.has("rest", r.id) }));

  // reset scroll on route change
  useEffect(() => { if (scrollRef.current) scrollRef.current.scrollTop = 0; }, [route]);

  const actions = {
    togglePlace: (id) => tog.set("place", id, !tog.has("place", id)),
    toggleDish: (id) => tog.set("dish", id, !tog.has("dish", id)),
    toggleBookmark: (id) => tog.set("rest", id, !tog.has("rest", id)),
    addExpense: (e) => { window.db.expenses.upsert(e); setRoute("money"); },
  };
  const state = { places, dishes, restaurants, expenses, filledPhotos: photos.list.length, tripTitle: T.meta.title };
  const go = (r) => setRoute(r);

  const rootVars = {
    "--color-teal": ACCENTS.jade.teal,
    "--color-darkTeal": ACCENTS.jade.dark,
    "--fontFamilySerif": '"Sitka Small", Cambria, Georgia, serif',
  };

  const navItems = [
    { id: "home", label: "Home", icon: "home" },
    { id: "places", label: "Places", icon: "location" },
    { id: "money", label: "Spend", icon: "wallet" },
    { id: "photos", label: "Photos", icon: "image_multiple" },
    { id: "translate", label: "Translate", icon: "translate" },
    { id: "recap", label: "Recap", icon: "sparkle" },
  ];
  const showNav = route !== "vault" && route !== "add" && route !== "settings";

  let screen, topbar = null;
  if (route === "home") {
    screen = <HomeScreen state={state} go={go} openAddExpense={() => go("add")} />;
  } else if (route === "places") {
    topbar = <TopBar title="Places & food" subtitle="Tick off as you explore" />;
    screen = <PlacesScreen state={state} actions={actions} />;
  } else if (route === "money") {
    topbar = <TopBar title="Money" subtitle={`${expenses.length} expenses · split ${T.people.length} ways`} action={{ icon: "add", label: "Add", onClick: () => go("add") }} />;
    screen = <MoneyScreen state={state} actions={actions} openAddExpense={() => go("add")} />;
  } else if (route === "photos") {
    topbar = <TopBar title="Memories" subtitle="Your trip scrapbook" />;
    screen = <MemoriesScreen />;
  } else if (route === "translate") {
    topbar = <TopBar title="Translate" subtitle="Two-way voice & text · EN · ಕನ್ನಡ · Tiếng Việt" />;
    screen = <TranslateScreen />;
  } else if (route === "recap") {
    screen = <RecapScreen state={state} />;
  } else if (route === "vault") {
    screen = <VaultScreen go={go} />;
  } else if (route === "add") {
    screen = <AddExpenseScreen go={go} onSave={actions.addExpense} />;
  } else if (route === "settings") {
    screen = <SettingsScreen go={go} dark={dark} setDark={toggleDark} />;
  }

  return (
    <div id="vn-root" data-theme={dark ? "dark" : undefined} style={{ ...rootVars, fontFamily: "var(--fontFamilyBase)", color: "var(--colorNeutralForeground1)",
      WebkitFontSmoothing: "antialiased", height: "100%" }}>
      <div id="vn-shell" style={{
        position: "relative", height: "100dvh", width: "100%", maxWidth: 480, margin: "0 auto",
        display: "flex", flexDirection: "column", overflow: "hidden",
        background: "var(--colorNeutralBackground2)",
        paddingTop: "env(safe-area-inset-top)",
      }}>
        {!online && (
          <div style={{ flexShrink: 0, display: "flex", alignItems: "center", justifyContent: "center", gap: 6,
            padding: "6px 12px", background: "var(--color-marigold)", color: "#3a2c00", fontSize: 12, fontWeight: 700 }}>
            <Icon name="globe" size={13} color="#3a2c00" /> Offline — showing saved data
          </div>
        )}
        <div ref={scrollRef} style={{ flex: 1, overflowY: "auto", overflowX: "hidden", WebkitOverflowScrolling: "touch" }}>
          {topbar}
          {screen}
          <div style={{ height: showNav ? 8 : 24 }} />
        </div>
        {showNav && <BottomNav items={navItems} route={route} go={go} />}
      </div>
    </div>
  );
}

function TopBar({ title, subtitle, action }) {
  return (
    <div style={{
      position: "sticky", top: 0, zIndex: 30,
      padding: "16px 16px 12px",
      background: "rgba(250,250,250,0.86)", backdropFilter: "blur(12px)", WebkitBackdropFilter: "blur(12px)",
      borderBottom: "1px solid var(--colorNeutralStroke3)",
      display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 10,
    }}>
      <div>
        <Serif size={24} weight={600}>{title}</Serif>
        {subtitle && <div style={{ fontSize: 12.5, color: "var(--colorNeutralForeground3)", marginTop: 2 }}>{subtitle}</div>}
      </div>
      {action && (
        <button onClick={action.onClick} style={{
          display: "inline-flex", alignItems: "center", gap: 5, padding: "8px 13px", borderRadius: 11,
          border: "none", background: "var(--color-teal)", color: "#fff", fontWeight: 600, fontSize: 13.5,
          cursor: "pointer", fontFamily: "var(--fontFamilyBase)",
        }}>
          <Icon name={action.icon} size={16} color="#fff" />{action.label}
        </button>
      )}
    </div>
  );
}

function BottomNav({ items, route, go }) {
  return (
    <div style={{
      flexShrink: 0, display: "flex", padding: "8px 6px max(env(safe-area-inset-bottom), 12px)",
      background: "var(--colorNeutralBackground1)", backdropFilter: "blur(16px)", WebkitBackdropFilter: "blur(16px)",
      borderTop: "1px solid var(--colorNeutralStroke2)",
    }}>
      {items.map((it) => {
        const on = route === it.id;
        return (
          <button key={it.id} onClick={() => go(it.id)} style={{
            flex: 1, border: "none", background: "none", cursor: "pointer", padding: "4px 0",
            display: "flex", flexDirection: "column", alignItems: "center", gap: 3, fontFamily: "var(--fontFamilyBase)",
          }}>
            <Icon name={it.icon} size={24} filled={on} color={on ? "var(--color-teal)" : "var(--colorNeutralForeground4)"} />
            <span style={{ fontSize: 10.5, fontWeight: 600, color: on ? "var(--color-darkTeal)" : "var(--colorNeutralForeground4)" }}>{it.label}</span>
          </button>
        );
      })}
    </div>
  );
}

/* ---------------------- Add expense (push screen) ---------------------- */
function AddExpenseScreen({ go, onSave }) {
  const T = window.TRIP;
  const [title, setTitle] = useState("");
  const [amount, setAmount] = useState("");
  const [cat, setCat] = useState("Food");
  const [by, setBy] = useState("you");
  const [split, setSplit] = useState(T.people.map((p) => p.id));
  const cats = ["Food", "Transport", "Stay", "Tours", "Other"];
  const valid = title.trim() && Number(amount) > 0 && split.length > 0;

  const toggleSplit = (id) => setSplit((s) => s.includes(id) ? s.filter((x) => x !== id) : [...s, id]);

  const save = () => {
    if (!valid) return;
    onSave({
      id: "e" + Date.now(), title: title.trim(), cat,
      vnd: Math.round(Number(amount)), by, split: [...split], day: "Today",
    });
  };

  return (
    <div style={{ minHeight: "100%", background: "var(--colorNeutralBackground2)" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "14px 16px 14px",
        background: "var(--colorNeutralBackground1)", borderBottom: "1px solid var(--colorNeutralStroke2)",
        position: "sticky", top: 0, zIndex: 10 }}>
        <button onClick={() => go("money")} aria-label="cancel" style={{ width: 36, height: 36, borderRadius: 10, border: "1px solid var(--colorNeutralStroke2)", background: "var(--colorNeutralBackground1)", display: "inline-flex", alignItems: "center", justifyContent: "center", cursor: "pointer" }}>
          <Icon name="dismiss" size={18} color="var(--colorNeutralForeground1)" />
        </button>
        <Serif size={20} weight={600} style={{ flex: 1 }}>New expense</Serif>
        <Btn kind={valid ? "primary" : "soft"} size="sm" onClick={save} style={valid ? {} : { opacity: 0.5 }}>Save</Btn>
      </div>

      <div style={{ padding: 16, display: "flex", flexDirection: "column", gap: 18 }}>
        {/* amount */}
        <div style={{ textAlign: "center", padding: "10px 0 4px" }}>
          <div style={{ display: "inline-flex", alignItems: "baseline", gap: 4 }}>
            <span style={{ fontSize: 30, fontWeight: 700, color: "var(--colorNeutralForeground3)" }}>₫</span>
            <input value={amount} onChange={(e) => setAmount(e.target.value.replace(/[^0-9]/g, ""))} inputMode="numeric" placeholder="0" style={{
              border: "none", outline: "none", background: "transparent", fontFamily: "var(--fontFamilyBase)",
              fontSize: 44, fontWeight: 700, width: 200, textAlign: "center", color: "var(--colorNeutralForeground1)",
            }} />
          </div>
          {Number(amount) > 0 && <div style={{ fontSize: 13, color: "var(--colorNeutralForeground3)" }}>≈ {T.toINR(Number(amount))}</div>}
        </div>

        <Field label="What was it for?">
          <input value={title} onChange={(e) => setTitle(e.target.value)} placeholder="e.g. Lunch at Morning Glory" style={inputStyle} />
        </Field>

        <Field label="Category">
          <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
            {cats.map((c) => (
              <button key={c} onClick={() => setCat(c)} style={{
                padding: "8px 14px", borderRadius: 999, cursor: "pointer", fontFamily: "var(--fontFamilyBase)",
                border: cat === c ? "1px solid var(--color-teal)" : "1px solid var(--colorNeutralStroke1)",
                background: cat === c ? "rgba(3,131,135,0.10)" : "#fff",
                color: cat === c ? "var(--color-darkTeal)" : "var(--colorNeutralForeground2)",
                fontSize: 13, fontWeight: 600,
              }}>{c}</button>
            ))}
          </div>
        </Field>

        <Field label="Paid by">
          <div style={{ display: "flex", gap: 10 }}>
            {T.people.map((p) => (
              <button key={p.id} onClick={() => setBy(p.id)} style={{
                flex: 1, padding: "10px 4px", borderRadius: 13, cursor: "pointer", fontFamily: "var(--fontFamilyBase)",
                border: by === p.id ? "2px solid var(--color-teal)" : "1px solid var(--colorNeutralStroke2)",
                background: "var(--colorNeutralBackground1)", display: "flex", flexDirection: "column", alignItems: "center", gap: 5,
              }}>
                <Avatar person={p} size={32} />
                <span style={{ fontSize: 11.5, fontWeight: 600, color: "var(--colorNeutralForeground2)" }}>{p.name}</span>
              </button>
            ))}
          </div>
        </Field>

        <Field label={`Split between · ${split.length}`}>
          <div style={{ display: "flex", gap: 10 }}>
            {T.people.map((p) => {
              const on = split.includes(p.id);
              return (
                <button key={p.id} onClick={() => toggleSplit(p.id)} style={{
                  flex: 1, padding: "10px 4px", borderRadius: 13, cursor: "pointer", fontFamily: "var(--fontFamilyBase)",
                  border: on ? "2px solid var(--color-teal)" : "1px solid var(--colorNeutralStroke2)",
                  background: on ? "rgba(3,131,135,0.06)" : "var(--colorNeutralBackground3)", opacity: on ? 1 : 0.55,
                  display: "flex", flexDirection: "column", alignItems: "center", gap: 5, position: "relative",
                }}>
                  <Avatar person={p} size={32} />
                  <span style={{ fontSize: 11.5, fontWeight: 600, color: "var(--colorNeutralForeground2)" }}>{p.name}</span>
                </button>
              );
            })}
          </div>
          {Number(amount) > 0 && split.length > 0 && (
            <div style={{ fontSize: 12.5, color: "var(--colorNeutralForeground3)", marginTop: 10, textAlign: "center" }}>
              {T.fmtVND(Number(amount) / split.length)} each
            </div>
          )}
        </Field>
      </div>
    </div>
  );
}

const inputStyle = {
  width: "100%", boxSizing: "border-box", padding: "12px 14px", borderRadius: 12,
  border: "1px solid var(--colorNeutralStroke1)", background: "var(--colorNeutralBackground1)", fontSize: 15,
  fontFamily: "var(--fontFamilyBase)", outline: "none", color: "var(--colorNeutralForeground1)",
};

function Field({ label, children }) {
  return (
    <div>
      <div style={{ fontSize: 12, fontWeight: 700, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--colorNeutralForeground3)", marginBottom: 8 }}>{label}</div>
      {children}
    </div>
  );
}

/* ---------------------- Auth gate (shared trip login) ---------------------- */
function LoginScreen() {
  const [email, setEmail] = useState("");
  const [pw, setPw] = useState("");
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState("");
  const submit = async (e) => {
    if (e) e.preventDefault();
    if (!email.trim() || !pw || busy) return;
    setBusy(true); setErr("");
    const { error } = await window.db.auth.signIn(email, pw);
    if (error) { setErr(error.message || "Couldn't sign in"); setBusy(false); }
    // on success, the auth listener re-renders Root into the app
  };
  const inp = { width: "100%", boxSizing: "border-box", padding: "13px 14px", borderRadius: 12,
    border: "1px solid var(--colorNeutralStroke1)", background: "var(--colorNeutralBackground1)", fontSize: 15,
    fontFamily: "var(--fontFamilyBase)", outline: "none", color: "var(--colorNeutralForeground1)", marginTop: 10 };
  return (
    <div style={{ minHeight: "100dvh", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center",
      padding: 24, background: "linear-gradient(160deg, var(--color-darkTeal), var(--color-teal))", color: "#fff" }}>
      <div style={{ width: 64, height: 64, borderRadius: 18, background: "rgba(255,255,255,0.16)", display: "flex", alignItems: "center", justifyContent: "center", marginBottom: 14 }}>
        <Icon name="shield_keyhole" size={32} filled color="#fff" />
      </div>
      <Serif size={30} weight={700} color="#fff">GAP Việt Nam</Serif>
      <div style={{ fontSize: 13.5, color: "rgba(255,255,255,0.8)", marginTop: 4, marginBottom: 18 }}>Sign in to your shared trip</div>
      <form onSubmit={submit} style={{ width: "100%", maxWidth: 340 }}>
        <input type="email" inputMode="email" autoComplete="username" placeholder="Trip email" value={email} onChange={(e) => setEmail(e.target.value)} style={inp} />
        <input type="password" autoComplete="current-password" placeholder="Password" value={pw} onChange={(e) => setPw(e.target.value)} style={inp} />
        {err && <div style={{ fontSize: 12.5, color: "#ffd9c2", marginTop: 10 }}>{err}</div>}
        <button type="submit" disabled={busy} style={{ width: "100%", marginTop: 16, padding: "13px", borderRadius: 12, border: "none",
          background: "#fff", color: "var(--color-darkTeal)", fontWeight: 700, fontSize: 15, cursor: "pointer", fontFamily: "var(--fontFamilyBase)", opacity: busy ? 0.6 : 1 }}>
          {busy ? "Signing in…" : "Sign in"}
        </button>
      </form>
      <div style={{ fontSize: 11.5, color: "rgba(255,255,255,0.6)", marginTop: 16, textAlign: "center", maxWidth: 320 }}>
        Shared by you, Girish & Abhishek. Documents stay private behind this login.
      </div>
    </div>
  );
}

function Root() {
  const { session, configured, ready } = window.db.useSession();
  if (configured && !ready) {
    return <div style={{ minHeight: "100dvh", display: "flex", alignItems: "center", justifyContent: "center", background: "var(--color-darkTeal)", color: "#fff", fontFamily: "var(--fontFamilyBase)" }}>Loading…</div>;
  }
  if (configured && !session) return <LoginScreen />;
  return <App />;
}

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