/* app.jsx — shell, reducer, nav, modal orchestration */
const { useReducer, useEffect: aEffect, useState: aState } = React;
const LP = window.LP;
const AUTH_KEY = "lp_tracker_auth_v1";

function AuthGate() {
  const [authed, setAuthed] = aState(() => localStorage.getItem(AUTH_KEY) === "1");
  const [email, setEmail] = aState("");
  const [password, setPassword] = aState("");
  const [error, setError] = aState("");
  const [busy, setBusy] = aState(false);

  const submit = async (e) => {
    e.preventDefault();
    setBusy(true);
    setError("");
    try {
      const res = await fetch("/api/login", {
        method: "POST",
        credentials: "include",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email, password }),
      });
      if (!res.ok) throw new Error("Email or password is incorrect.");
      localStorage.setItem(AUTH_KEY, "1");
      setAuthed(true);
    } catch (err) {
      setError(err.message || "This browser could not verify the login.");
    } finally {
      setBusy(false);
    }
  };

  const logout = () => {
    fetch("/api/logout", { method: "POST", credentials: "include" }).catch(() => {});
    localStorage.removeItem(AUTH_KEY);
    setAuthed(false);
  };

  if (authed) return <App onLogout={logout} />;

  return (
    <div className="auth-page">
      <div className="auth-panel">
        <div className="auth-brand">
          <div className="auth-mark">L</div>
          <div className="auth-title">
            <strong>Lena Tracker</strong>
            <span>Private dashboard</span>
          </div>
        </div>
        <form className="auth-form" onSubmit={submit}>
          {error && <div className="auth-error">{error}</div>}
          <Field label="Email">
            <Input type="email" value={email} onChange={(e) => setEmail(e.target.value)} autoComplete="username" autoFocus required />
          </Field>
          <Field label="Password">
            <Input type="password" value={password} onChange={(e) => setPassword(e.target.value)} autoComplete="current-password" required />
          </Field>
          <button className="auth-submit" disabled={busy}>{busy ? "Signing in..." : "Sign in"}</button>
        </form>
        <p className="auth-note">Access is limited to the owner of this dashboard.</p>
      </div>
    </div>
  );
}

function reducer(state, a) {
  const clone = structuredClone(state);
  const stu = (id) => clone.students.find((s) => s.id === id);
  switch (a.type) {
    case "addSession": {
      const s = stu(a.studentId); s.sessions.push({ ...a.session, id: LP.uid() }); break;
    }
    case "editSession": {
      const s = stu(a.studentId); const i = s.sessions.findIndex((x) => x.id === a.session.id);
      if (i > -1) s.sessions[i] = a.session; break;
    }
    case "delSession": {
      const s = stu(a.studentId); s.sessions = s.sessions.filter((x) => x.id !== a.sessionId); break;
    }
    case "togglePin": {
      const s = stu(a.studentId); const x = s.sessions.find((y) => y.id === a.sessionId);
      if (x) x.pinned = !x.pinned; break;
    }
    case "addPackage": { stu(a.studentId).packages.push({ ...a.pkg, id: LP.uid() }); break; }
    case "editPackage": {
      const s = stu(a.studentId); const i = s.packages.findIndex((x) => x.id === a.pkg.id);
      if (i > -1) s.packages[i] = a.pkg; break;
    }
    case "delPackage": {
      const s = stu(a.studentId); s.packages = s.packages.filter((x) => x.id !== a.pkgId); break;
    }
    case "editPricing": { stu(a.studentId).pricingNote = a.pricingNote; break; }
    case "addStudent": {
      const name = (a.student.name || "").trim();
      if (!name || clone.students.some((s) => s.name.trim().toLowerCase() === name.toLowerCase())) return state;
      clone.students.unshift({ id: LP.uid(), packages: [], sessions: [], tags: [], ...a.student, name }); break;
    }
    case "editStudent": {
      const i = clone.students.findIndex((s) => s.id === a.student.id);
      if (i > -1) {
        const oldName = clone.students[i].name;
        const nextName = (a.student.name || "").trim();
        if (!nextName) return state;
        if (clone.students.some((s) => s.id !== a.student.id && s.name.trim().toLowerCase() === nextName.toLowerCase())) return state;
        clone.students[i] = { ...clone.students[i], ...a.student, name: nextName };
        clone.payments = clone.payments.map((p) => ({
          ...p,
          student: p.student === oldName ? nextName : p.student,
          from: p.from === oldName ? nextName : p.from,
        }));
      }
      break;
    }
    case "addPayment": { clone.payments.unshift({ ...a.payment, id: LP.uid() }); break; }
    case "editPayment": {
      const i = clone.payments.findIndex((p) => p.id === a.payment.id);
      if (i > -1) clone.payments[i] = a.payment; break;
    }
    case "delPayment": { clone.payments = clone.payments.filter((p) => p.id !== a.id); break; }
    case "replaceAll": return a.data;
    case "reset": return LP.resetSeed();
    default: return state;
  }
  clone.meta = { ...clone.meta, updated: new Date().toISOString().slice(0, 10) };
  return clone;
}

const NAV = [
  { key: "dashboard", label: "概览", en: "Overview", icon: Icon.grid },
  { key: "students", label: "Library", en: "Student Catalog", icon: Icon.users },
  { key: "payments", label: "资金对账", en: "Payments", icon: Icon.wallet },
];

function App({ onLogout }) {
  const [state, dispatch] = useReducer(reducer, null, LP.load);
  const [hydrated, setHydrated] = aState(false);
  const [view, setView] = aState("dashboard");
  const [studentId, setStudentId] = aState(null);
  const [modal, setModal] = aState(null);
  const [navOpen, setNavOpen] = aState(false);
  const [tick, setTick] = aState(0);

  aEffect(() => {
    let alive = true;
    LP.loadRemote()
      .then((remote) => {
        if (!alive) return;
        if (remote) dispatch({ type: "replaceAll", data: remote });
        setHydrated(true);
      })
      .catch(() => {
        if (alive) setHydrated(true);
      });
    return () => { alive = false; };
  }, []);
  aEffect(() => {
    if (!hydrated) return;
    LP.save(state);
    LP.saveRemote(state).catch(() => {});
    setTick((t) => t + 1);
  }, [state, hydrated]);
  aEffect(() => { const id = setInterval(() => setTick((t) => t + 1), 30000); return () => clearInterval(id); }, []);

  const goStudent = (id) => { setStudentId(id); setView("studentDetail"); window.scrollTo(0, 0); };
  const goView = (v) => { setView(v); setStudentId(null); setNavOpen(false); window.scrollTo(0, 0); };
  const openModal = (m) => setModal(m);
  const closeModal = () => setModal(null);

  // quick-add: chooser routes to the right form
  const onQuickPick = (key) => {
    if (key === "session") setModal({ type: "session" }); // no studentId -> picker
    else if (key === "payment") setModal({ type: "payment" });
  };

  const currentStudent = state.students.find((s) => s.id === studentId);

  // alert count for nav badge
  const alertCount = state.students.filter((s) => s.status === "active" && ["low", "over"].includes(LP.calc.balanceState(s))).length;

  return (
    <div className="app">
      {/* sidebar */}
      <aside className={"sidebar" + (navOpen ? " is-open" : "")}>
        <div className="brand">
          <div className="brand-mark">L</div>
          <div className="brand-text">
            <strong>Lena Tracker</strong>
            <span>课时 · 收款看板</span>
          </div>
        </div>
        <nav className="nav">
          <button className="quick-add-btn" onClick={() => openModal({ type: "quickadd" })}>
            <Icon.plus size={18} /> 录入数据
          </button>
          {NAV.map((n) => {
            const active = view === n.key || (n.key === "students" && view === "studentDetail");
            return (
              <button key={n.key} className={"nav-item" + (active ? " is-active" : "")} onClick={() => goView(n.key)}>
                <n.icon size={19} />
                <span className="nav-label">{n.label}<em>{n.en}</em></span>
                {n.key === "students" && alertCount > 0 && <span className="nav-badge">{alertCount}</span>}
              </button>
            );
          })}
        </nav>
        <div className="sidebar-foot">
          <button className="nav-item nav-quiet" onClick={() => openModal({ type: "data" })}>
            <Icon.doc size={18} /><span className="nav-label">数据备份 / 导出</span>
          </button>
          <button className="nav-item nav-quiet" onClick={() => openModal({ type: "confirm", title: "恢复示例数据", message: "这会清除你在浏览器里所有的修改，恢复到从 Excel 导入的初始数据。确认？", confirmLabel: "恢复", onConfirm: () => dispatch({ type: "reset" }) })}>
            <Icon.reset size={18} /><span className="nav-label">恢复示例数据</span>
          </button>
          <button className="nav-item nav-quiet" onClick={onLogout}>
            <Icon.close size={18} /><span className="nav-label">Sign out</span>
          </button>
          <div className="sidebar-saved"><SavedBadge tick={tick} /></div>
        </div>
      </aside>
      {navOpen && <div className="nav-scrim" onClick={() => setNavOpen(false)} />}

      {/* main */}
      <main className="main">
        <header className="topbar">
          <button className="topbar-menu" onClick={() => setNavOpen(true)}><Icon.menu size={20} /></button>
          <div className="topbar-title">{NAV.find((n) => n.key === view)?.label || (view === "studentDetail" ? "Student Detail" : "")}</div>
          <button className="topbar-add" onClick={() => openModal({ type: "quickadd" })}><Icon.plus size={18} /></button>
        </header>

        <div className="content">
          {view === "dashboard" && <Dashboard state={state} goStudent={goStudent} goView={goView} />}
          {view === "students" && <StudentsList state={state} goStudent={goStudent} onAddStudent={() => openModal({ type: "student" })} />}
          {view === "studentDetail" && <StudentDetail state={state} studentId={studentId} back={() => goView("students")} dispatch={dispatch} openModal={openModal} />}
          {view === "payments" && <Payments state={state} dispatch={dispatch} openModal={openModal} />}
        </div>
      </main>

      {/* modals */}
      {modal?.type === "quickadd" && <QuickAddChooser onPick={onQuickPick} onClose={closeModal} />}
      {modal?.type === "data" && <DataModal state={state} dispatch={dispatch} onClose={closeModal} />}
      {modal?.type === "session" && <SessionModal studentId={modal.studentId} session={modal.session} students={state.students} dispatch={dispatch} onClose={closeModal} />}
      {modal?.type === "package" && <PackageModal studentId={modal.studentId} pkg={modal.pkg} dispatch={dispatch} onClose={closeModal} />}
      {modal?.type === "pricing" && <PricingModal studentId={modal.studentId} current={currentStudent?.pricingNote} dispatch={dispatch} onClose={closeModal} />}
      {modal?.type === "student" && <StudentModal student={modal.student} students={state.students} dispatch={dispatch} onClose={closeModal} />}
      {modal?.type === "payment" && <PaymentModal payment={modal.payment} students={state.students} dispatch={dispatch} onClose={closeModal} />}
      {modal?.type === "confirm" && <Confirm title={modal.title} message={modal.message} confirmLabel={modal.confirmLabel} onConfirm={modal.onConfirm} onClose={closeModal} />}
    </div>
  );
}

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