// App.jsx — root: state, routing between screens, tab bar
const { useState, useMemo, useEffect, useRef } = React;

const TWEAK_DEFAULTS = {
  amountFontSize: 70,
  keyHeight: 56,
  accent: "#2D6A4F",
  density: "regular",
  splitDefault: "even",
  otherName: "其他",
};

function TabIcon({ kind, on }) {
  const stroke = on ? "#1A1A1A" : "#888888";
  const sw = on ? 1.6 : 1.2;
  if (kind === "entry") return (
    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke={stroke} strokeWidth={sw}>
      <circle cx="12" cy="12" r="9" />
      <path d="M12 8v8M8 12h8" />
    </svg>
  );
  if (kind === "history") return (
    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke={stroke} strokeWidth={sw}>
      <rect x="4" y="5" width="16" height="15" rx="1" />
      <path d="M8 10h8M8 14h8" />
    </svg>
  );
  if (kind === "settle") return (
    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke={stroke} strokeWidth={sw}>
      <path d="M5 9h12l-3-3M19 15H7l3 3" />
    </svg>
  );
  if (kind === "stats") return (
    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke={stroke} strokeWidth={sw}>
      <path d="M5 19V11M11 19V5M17 19v-7" />
    </svg>
  );
  if (kind === "more") return (
    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke={stroke} strokeWidth={sw}>
      <circle cx="6" cy="12" r="1.2" fill={stroke} />
      <circle cx="12" cy="12" r="1.2" fill={stroke} />
      <circle cx="18" cy="12" r="1.2" fill={stroke} />
    </svg>
  );
}

function TabBar({ tab, setTab }) {
  const items = [
    { id: "entry",   label: "記帳" },
    { id: "history", label: "歷史" },
    { id: "settle",  label: "結算" },
    { id: "stats",   label: "統計" },
    { id: "more",    label: "更多" },
  ];
  return (
    <nav className="tabbar">
      {items.map((it) => (
        <button
          key={it.id}
          className={"tab" + (tab === it.id ? " is-on" : "")}
          onClick={() => setTab(it.id)}
        >
          <TabIcon kind={it.id} on={tab === it.id} />
          <span>{it.label}</span>
        </button>
      ))}
    </nav>
  );
}

function App() {
  const [tweaks, setTweaks] = useState(TWEAK_DEFAULTS);
  const t = tweaks;
  const setTweak = (key, val) => setTweaks((prev) => ({ ...prev, [key]: val }));
  const cats = useMemo(() => categoriesWith(t.otherName), [t.otherName]);

  const [user, setUser]         = useState(null); // null | "A" | "B"
  const [names, setNames]       = useState(DEFAULT_NAMES);
  const [tab, setTab]           = useState("entry");
  const [moreView, setMoreView] = useState("menu"); // menu | books | settings | templates
  const [editing, setEditing]   = useState(null);
  const [pendingFilter, setPendingFilter] = useState(false);

  // Firestore-backed state
  const [fbReady, setFbReady] = useState(!!window.firebaseApi);
  const [transactions, setTransactions] = useState([]);
  const [books, setBooks] = useState([]);
  const [templates, setTemplates] = useState([]);
  const [currentBookId, setCurrentBookId] = useState(null);
  const seedingRef = useRef(false);

  // Wait for module-loaded firebase.js (defensive — usually ready already)
  useEffect(() => {
    if (window.firebaseApi) { setFbReady(true); return; }
    const onReady = () => setFbReady(true);
    window.addEventListener("firebase-ready", onReady);
    return () => window.removeEventListener("firebase-ready", onReady);
  }, []);

  // Subscribe to Firebase Auth — derive identity (A/B) from whitelist position.
  // Non-whitelisted users get signed out immediately (defense line 1).
  useEffect(() => {
    if (!fbReady) return;
    return window.firebaseApi.auth.onAuth(async (fbUser) => {
      if (!fbUser) { setUser(null); return; }
      const identity = window.firebaseApi.auth.emailToIdentity(fbUser.email);
      if (!identity) {
        await window.firebaseApi.auth.signOut();
        setUser(null);
        return;
      }
      setUser(identity);
    });
  }, [fbReady]);

  // Subscribe to Firestore once Firebase is ready AND user is authed.
  // Gating on `user` avoids firing subscriptions while signed out — Rules
  // would deny them and noise up the console. On logout, cleanup unsubs and
  // we reset the cached collections so a different signed-in user wouldn't
  // see stale data flash before the next snapshot lands.
  useEffect(() => {
    if (!fbReady || !user) {
      setTransactions([]);
      setBooks([]);
      setTemplates([]);
      setCurrentBookId(null);
      seedingRef.current = false;
      return;
    }
    const api = window.firebaseApi;

    const unsubBooks = api.watchBooks((list) => {
      setBooks(list);
      if (list.length === 0 && !seedingRef.current) {
        seedingRef.current = true;
        api.createBook({
          name: "日常", type: "daily", status: "active",
          startedAt: null, endedAt: null,
        }).catch((err) => {
          console.error("auto-seed daily book failed", err);
          seedingRef.current = false;
        });
      }
    });
    const unsubEntries = api.watchEntries(setTransactions);
    const unsubTpl = api.watchTemplates(setTemplates);

    return () => { unsubBooks(); unsubEntries(); unsubTpl(); };
  }, [fbReady, user]);

  // Pick a sensible default current book once books arrive.
  useEffect(() => {
    if (currentBookId && books.some((b) => b.id === currentBookId)) return;
    const daily = books.find((b) => b.type === "daily" && b.status === "active");
    if (daily) setCurrentBookId(daily.id);
    else if (books.length > 0) setCurrentBookId(books[0].id);
  }, [books, currentBookId]);

  const pendingCount = useMemo(
    () => transactions.filter((tx) => tx.pending).length,
    [transactions]
  );

  async function handleSave(tx) {
    const api = window.firebaseApi;
    const { id, bookId, ...data } = tx;
    if (editing && editing.id) {
      if (editing.bookId !== bookId) {
        // moved across books — delete old path, write to new one
        await api.deleteEntry(editing.bookId, editing.id);
        await api.addEntry(bookId, data);
      } else {
        await api.updateEntry(bookId, id, data);
      }
    } else {
      await api.addEntry(bookId, data);
    }
    setCurrentBookId(bookId);
  }

  function handleDelete(tx) {
    return window.firebaseApi.deleteEntry(tx.bookId, tx.id);
  }

  function handleEdit(tx) {
    setEditing(tx);
    setTab("entry");
  }

  async function handleSettle({ from, to, amount }) {
    const dailyBook = books.find((b) => b.type === "daily" && b.status === "active");
    const targetBookId = dailyBook?.id || currentBookId;
    if (!targetBookId) return;

    // Push the settle marker so it sorts after the latest entry.
    const latest = transactions.reduce((max, tx) => tx.date > max ? tx.date : max, "");
    const nowIso = new Date().toISOString();
    const settleIso = latest && nowIso <= latest
      ? new Date(new Date(latest).getTime() + 1000).toISOString()
      : nowIso;

    await window.firebaseApi.addEntry(targetBookId, {
      type: "settle",
      amount,
      payer: from,
      date: settleIso,
      note: `${names[from]} 給 ${names[to]}`,
    });
    setTab("history");
  }

  async function handleCreateBook(b) {
    const { id: _id, ...data } = b;
    const ref = await window.firebaseApi.createBook(data);
    setCurrentBookId(ref.id);
  }

  function handleArchiveBook(id) {
    window.firebaseApi.updateBook(id, { status: "archived" });
    if (currentBookId === id) {
      const fallback = books.find((b) => b.type === "daily" && b.status === "active" && b.id !== id);
      if (fallback) setCurrentBookId(fallback.id);
    }
  }

  function handleUnarchiveBook(id) {
    window.firebaseApi.updateBook(id, { status: "active" });
  }

  function handleSaveTemplate(tpl) {
    return window.firebaseApi.saveTemplate(tpl);
  }

  function handleDeleteTemplate(id) {
    return window.firebaseApi.deleteTemplate(id);
  }

  function handleSaveAsTemplate(tx, name) {
    return window.firebaseApi.saveTemplate({
      name: name || tx.note || "未命名",
      amount: tx.amount || 0,
      category: tx.category,
      note: tx.note || "",
      split: tx.split || { mode: "even" },
    });
  }

  function handleExport() {
    const csv = transactionsToCsv(transactions, books, names, cats);
    const filename = `expense-${ymd(new Date().toISOString())}.csv`;
    downloadCsv(filename, csv);
  }

  if (!fbReady) {
    return (
      <div className="phone-stage">
        <div className="phone">
          <div className="empty">
            <div className="empty-title">連線中…</div>
          </div>
        </div>
      </div>
    );
  }

  if (!user) {
    return (
      <div className="phone-stage">
        <div className="phone">
          <LoginScreen accent={t.accent} />
        </div>
      </div>
    );
  }

  if (!currentBookId) {
    return (
      <div className="phone-stage">
        <div className="phone">
          <div className="empty">
            <div className="empty-title">連線中…</div>
            <div className="empty-sub">第一次開啟需要等 Firestore 建立日常帳本</div>
          </div>
        </div>
      </div>
    );
  }

  let screenEl;
  if (tab === "entry") {
    screenEl = (
      <EntryScreen
        me={user}
        names={names}
        books={books}
        cats={cats}
        templates={templates}
        currentBookId={currentBookId}
        setCurrentBookId={setCurrentBookId}
        onSave={handleSave}
        defaultMode={t.splitDefault}
        amountFontSize={t.amountFontSize}
        keyHeight={t.keyHeight}
        accent={t.accent}
        editing={editing}
        onCancelEdit={() => setEditing(null)}
      />
    );
  } else if (tab === "history") {
    screenEl = (
      <HistoryScreen
        transactions={transactions}
        books={books}
        names={names}
        cats={cats}
        accent={t.accent}
        density={t.density}
        pendingOnly={pendingFilter}
        onClearPendingFilter={() => setPendingFilter(false)}
        onSaveAsTemplate={handleSaveAsTemplate}
        onEdit={handleEdit}
        onDelete={handleDelete}
      />
    );
  } else if (tab === "settle") {
    screenEl = (
      <SettleScreen
        transactions={transactions}
        names={names}
        accent={t.accent}
        onSettle={handleSettle}
      />
    );
  } else if (tab === "stats") {
    screenEl = (
      <StatsScreen
        transactions={transactions}
        names={names}
        cats={cats}
        accent={t.accent}
      />
    );
  } else if (tab === "more") {
    if (moreView === "books") {
      screenEl = (
        <BooksScreen
          books={books}
          transactions={transactions}
          accent={t.accent}
          onCreate={handleCreateBook}
          onArchive={handleArchiveBook}
          onUnarchive={handleUnarchiveBook}
          onBack={() => setMoreView("menu")}
        />
      );
    } else if (moreView === "templates") {
      screenEl = (
        <TemplatesScreen
          templates={templates}
          cats={cats}
          names={names}
          accent={t.accent}
          onSave={handleSaveTemplate}
          onDelete={handleDeleteTemplate}
          onBack={() => setMoreView("menu")}
        />
      );
    } else if (moreView === "settings") {
      screenEl = (
        <SettingsScreen
          names={names}
          setNames={setNames}
          otherName={t.otherName}
          setOtherName={(v) => setTweak("otherName", v)}
          accent={t.accent}
          setAccent={(v) => setTweak("accent", v)}
          density={t.density}
          setDensity={(v) => setTweak("density", v)}
          splitDefault={t.splitDefault}
          setSplitDefault={(v) => setTweak("splitDefault", v)}
          onExport={handleExport}
          onLogout={() => { window.firebaseApi.auth.signOut(); setMoreView("menu"); }}
          onBack={() => setMoreView("menu")}
          onOpenBooks={() => setMoreView("books")}
          onOpenTemplates={() => setMoreView("templates")}
        />
      );
    } else {
      screenEl = (
        <div className="screen settings">
          <div className="sub-header" style={{ borderBottom: "1px solid var(--line)" }}>
            <span style={{ width: 44 }} />
            <div className="sub-title">更多</div>
            <span style={{ width: 44 }} />
          </div>
          <div className="settings-section">
            <div className="settings-section-t">當前身份</div>
            <div style={{fontSize:14, padding:"8px 0"}}>{names[user]}</div>
          </div>
          <div className="settings-section">
            <button className="settings-row" onClick={() => setMoreView("books")}>
              <span>帳本管理</span><span className="caret">›</span>
            </button>
            <button className="settings-row" onClick={() => setMoreView("templates")}>
              <span>常用組套</span><span className="caret">›</span>
            </button>
            <button className="settings-row" onClick={() => setMoreView("settings")}>
              <span>設定</span><span className="caret">›</span>
            </button>
            <button className="settings-row" onClick={() => window.firebaseApi.auth.signOut()}>
              <span>登出</span><span className="caret">›</span>
            </button>
          </div>
        </div>
      );
    }
  }

  return (
    <div className="phone-stage">
      <div className="phone">
        {screenEl}
        {pendingCount > 0 && tab !== "history" && (
          <button className="pending-banner" onClick={() => { setPendingFilter(true); setTab("history"); }}>
            <span className="pending-banner-l">{pendingCount} 筆待補金額</span>
            <span className="pending-banner-r">›</span>
          </button>
        )}
        <TabBar tab={tab} setTab={(x) => { setTab(x); if (x !== "more") setMoreView("menu"); if (x !== "entry") setEditing(null); if (x !== "history") setPendingFilter(false); }} />
      </div>
    </div>
  );
}

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