/* ============================================================
   Narabuzz Backoffice — App shell, routing, state
   ============================================================ */
const { useState, useMemo, useCallback } = React;

const USERS = {
  exec: { name: "大久保 透", role: "exec", initial: "大" },
  crm:  { name: "本田 さくら", role: "crm", initial: "本" },
  logi: { name: "森田 健一", role: "logi", initial: "森" },
  acct: { name: "西 由美子", role: "acct", initial: "西" },
};

const NAV = [
  { sec: "業務" },
  { key: "dashboard", label: "ダッシュボード", icon: "dashboard" },
  { key: "clients", label: "クライアント", icon: "clients" },
  { key: "tours", label: "ツアー物販", icon: "tour", badgeKey: "pending" },
  { key: "ec", label: "EC委託販売", icon: "globe", badgeKey: "ecPending" },
  { sec: "売上・経理" },
  { key: "sales", label: "売上管理", icon: "sales" },
  { key: "products", label: "商品・在庫", icon: "product" },
  { key: "invoices", label: "請求書・レポート", icon: "invoice" },
  { sec: "" },
  { key: "settings", label: "設定", icon: "settings" },
];

const ROUTE_TITLE = {
  dashboard: "ダッシュボード", clients: "クライアント", client: "クライアント詳細",
  tours: "ツアー物販", tour: "ツアー詳細", ec: "EC委託販売", sales: "売上管理", products: "商品・在庫",
  invoices: "請求書・レポート", settings: "設定",
};

function App() {
  const DB = window.DB;
  const [roleKey, setRoleKey] = useState("exec");
  const [route, setRoute] = useState("dashboard");
  const [param, setParam] = useState(null);
  const [roleOpen, setRoleOpen] = useState(false);
  const [period, setPeriod] = useState("month");
  const [navOpen, setNavOpen] = useState(false);
  const [settleTour_, setSettleTour_] = useState(null);
  const [addOpen, setAddOpen] = useState(null);
  const [toastMsg, setToastMsg] = useState(null);

  // ---- mutable tour state (for settlement) ----
  const [tours, setTours] = useState(() => DB.tours.map((t) => ({ ...t })));
  const [consign, setConsign] = useState(() => DB.consignEC.map((c) => ({ ...c })));
  const [extra, setExtra] = useState({ confirmed: 0, payable: 0 });

  const go = useCallback((r, p = null) => { setRoute(r); setParam(p); setNavOpen(false); document.querySelector(".scroll")?.scrollTo(0, 0); }, []);
  const toast = useCallback((m) => { setToastMsg(m); clearTimeout(window.__t); window.__t = setTimeout(() => setToastMsg(null), 2600); }, []);

  const openSettle = useCallback((t) => setSettleTour_(t), []);
  const openAdd = useCallback((type = "tour") => setAddOpen({ type }), []);
  const settleTour = useCallback((id, { share, pay }) => {
    setTours((ts) => ts.map((t) => (t.id === id ? { ...t, status: "settled", gross: t.held, settledShare: share, settledPay: pay, settledDate: "2026-06-04", held: 0 } : t)));
    setExtra((e) => ({ confirmed: e.confirmed + share, payable: e.payable + pay }));
    toast("精算を確定しました");
  }, [toast]);
  const settleConsign = useCallback((id, { share, pay }) => {
    setConsign((cs) => cs.map((c) => (c.id === id ? { ...c, status: "settled", settledShare: share, settledPay: pay, settledDate: "2026-06-04", held: 0 } : c)));
    setExtra((e) => ({ confirmed: e.confirmed + share, payable: e.payable + pay }));
    toast("月次預かりを精算しました");
  }, [toast]);

  // ---- finance (derived) ----
  const fin = useMemo(() => {
    const tourHeld = tours.filter((t) => t.status !== "settled").reduce((a, t) => a + t.held, 0);
    const ecHeld = consign.filter((c) => c.status !== "settled").reduce((a, c) => a + c.held, 0);
    const held = tourHeld + ecHeld;
    // 自社確定売上は期間で変動（累積）。預かり金は現在残高のスナップショットなので期間に依らず一定。
    const confirmed = DB.periods[period].confirmed + extra.confirmed;
    const clientPayable = extra.payable;
    const totalReceived = held + confirmed + clientPayable;
    const bankBalance = DB.finance.bankBalance;
    const ownFunds = bankBalance - held - clientPayable;
    return { held, tourHeld, ecHeld, confirmed, clientPayable, totalReceived, bankBalance, ownFunds };
  }, [tours, consign, extra, period]);

  const user = USERS[roleKey];
  const ctx = { db: DB, fin, tours, consign, role: roleKey, user, manager: DB.manager, period, setPeriod, periods: DB.periods, go, openSettle, settleTour, settleConsign, openAdd, toast };
  const pendingCount = tours.filter((t) => t.status === "pending").length;
  const ecPendingCount = consign.filter((c) => c.status !== "settled").length;

  return (
    <div className="app">
      {/* ---------------- Sidebar ---------------- */}
      <aside className={"side" + (navOpen ? " open" : "")}>
        <div className="side-head">
          <div className="side-mark"><img src="assets/penguin_main.png" width="36" height="36" alt="" /></div>
          <div className="wordmark"><b>HF</b><span>BACKOFFICE</span></div>
        </div>
        <nav className="side-nav">
          {NAV.map((n, i) => n.sec !== undefined
            ? (n.sec ? <div key={i} className="nav-sec">{n.sec}</div> : <div key={i} style={{ height: 10 }} />)
            : (
              <div key={n.key} className={"nav-item" + (route === n.key || (route === "client" && n.key === "clients") || (route === "tour" && n.key === "tours") ? " active" : "")}
                onClick={() => go(n.key)}>
                <Icon name={n.icon} size={18} className="nav-ic" />
                {n.label}
                {n.badgeKey === "pending" && pendingCount > 0 && <span className="nav-badge alert">{pendingCount}</span>}
                {n.badgeKey === "ecPending" && ecPendingCount > 0 && <span className="nav-badge alert">{ecPendingCount}</span>}
              </div>
            ))}
        </nav>
        <div className="side-foot">
          <div className="side-user">
            <div className="side-ava" style={{ background: DB.manager.color }}>{DB.manager.initial}</div>
            <div className="side-user-meta"><b>{DB.manager.name}</b><span>{DB.manager.label}</span></div>
          </div>
        </div>
      </aside>
      {navOpen && <div className="nav-overlay" onClick={() => setNavOpen(false)} />}

      {/* ---------------- Main ---------------- */}
      <div className="main">
        <header className="topbar">
          <button className="icon-btn only-sp" onClick={() => setNavOpen(true)} aria-label="メニュー"><Icon name="menu" size={20} /></button>
          <div className="crumb">
            <img src="assets/penguin_circle.png" width="22" height="22" alt="" style={{ opacity: .95 }} />
            <Icon name="chevRight" size={13} />
            <b>{ROUTE_TITLE[route]}</b>
          </div>
          <div className="topbar-spacer" />
          <div className="searchbox" onClick={() => toast("検索（デモ）")}>
            <Icon name="search" size={15} /><span>検索…</span><kbd>⌘K</kbd>
          </div>
          <div style={{ position: "relative" }}>
            <div className="role-switch" onClick={() => setRoleOpen((v) => !v)}>
              <span className="role-dot" style={{ background: DB.roles[roleKey].color }} />
              <b>{DB.roles[roleKey].label}</b>
              <Icon name="chevDown" size={14} />
            </div>
            {roleOpen && (
              <>
                <div style={{ position: "fixed", inset: 0, zIndex: 40 }} onClick={() => setRoleOpen(false)} />
                <div style={{ position: "absolute", top: 44, right: 0, width: 248, background: "#fff", border: "1px solid var(--border)", borderRadius: 12, boxShadow: "var(--sh-lg)", zIndex: 50, padding: 6, animation: "pop .14s ease" }}>
                  <div style={{ fontSize: 10.5, fontWeight: 700, letterSpacing: ".1em", color: "var(--ink-3)", padding: "8px 10px 6px" }}>ロールを切り替え（権限プレビュー）</div>
                  {Object.values(DB.roles).map((r) => (
                    <div key={r.key} onClick={() => { setRoleKey(r.key); setRoleOpen(false); }}
                      className="role-opt" style={{ display: "flex", gap: 10, alignItems: "center", padding: "9px 10px", borderRadius: 8, cursor: "pointer", background: roleKey === r.key ? "var(--surface-3)" : "transparent" }}>
                      <span className="role-dot" style={{ background: r.color, width: 9, height: 9 }} />
                      <div style={{ flex: 1 }}><b style={{ fontSize: 12.5 }}>{r.label}</b><div className="muted" style={{ fontSize: 11 }}>{r.desc}</div></div>
                      {roleKey === r.key && <Icon name="check" size={15} style={{ color: "var(--brand)" }} />}
                    </div>
                  ))}
                </div>
              </>
            )}
          </div>
          <button className="icon-btn" onClick={() => toast("通知（デモ）")}><Icon name="bell" size={17} /><span className="dot" /></button>
        </header>

        <div className="scroll">
          {route === "dashboard" && <Dashboard ctx={ctx} />}
          {route === "clients" && <Clients ctx={ctx} />}
          {route === "client" && <ClientDetail ctx={ctx} clientId={param} />}
          {route === "tours" && <Tours ctx={ctx} />}
          {route === "tour" && <TourDetail ctx={ctx} tourId={param} />}
          {route === "ec" && <ECProjects ctx={ctx} />}
          {route === "sales" && <Sales ctx={ctx} />}
          {route === "invoices" && <Invoices ctx={ctx} />}
          {route === "products" && <Placeholder title="商品・在庫" sub="預かり品（委託）と卸（買取）を区別して管理。最小限の原価で卸利益を算出。" icon="product" />}
          {route === "settings" && <Placeholder title="設定" sub="ユーザー・ロール権限、各種マスタ、締め日・税率設定。" icon="settings" />}
        </div>
      </div>

      {settleTour_ && <SettleModal ctx={ctx} tour={settleTour_} onClose={() => setSettleTour_(null)} />}
      {addOpen && <AddProjectModal ctx={ctx} initialType={addOpen.type} onClose={() => setAddOpen(null)} />}
      {toastMsg && <div className="toast"><Icon name="checkCircle" size={18} />{toastMsg}</div>}
      <style>{`.role-opt:hover{background:var(--surface-2)!important;}`}</style>
    </div>
  );
}

function Placeholder({ title, sub, icon }) {
  return (
    <div className="page">
      <h1 className="page-title">{title}</h1>
      <p className="page-sub">{sub}</p>
      <div className="card" style={{ marginTop: 20 }}>
        <div className="empty" style={{ padding: "56px 20px" }}>
          <Mascot size={130} />
          <div style={{ fontSize: 14, fontWeight: 600, color: "var(--ink-2)" }}>この画面は次のフェーズで設計します</div>
          <div className="muted" style={{ fontSize: 12.5, maxWidth: 380 }}>{sub}</div>
        </div>
      </div>
    </div>
  );
}

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