/* ============ App shell + routing ============ */
const NAV = [
  { group: 'ภาพรวม', items: [{ id: 'dashboard', label: 'แดชบอร์ด', icon: 'dashboard' }] },
  { group: 'เอกสาร', items: [
    { id: 'scan', label: 'สแกน/อัปโหลด', icon: 'scan' },
    { id: 'docs', label: 'ทะเบียนเอกสาร', icon: 'docs', badgeKey: 'pending' },
  ] },
  { group: 'ภาษีกิจการ', entity: 'company', items: [
    { id: 'income', label: 'รายรับ (ภาษีขาย)', icon: 'income' },
    { id: 'receivables', label: 'ลูกหนี้ & เงินประกัน', icon: 'bank' },
    { id: 'expense', label: 'รายจ่าย (ภาษีซื้อ)', icon: 'expense' },
    { id: 'vat', label: 'ภ.พ.30 รายเดือน', icon: 'vat' },
  ] },
  { group: 'งบการเงิน', items: [
    { id: 'annual', label: 'งบประจำปี & วิเคราะห์', icon: 'bank' },
  ] },
  { group: 'ภาษีบุคคล', entity: 'personal', items: [
    { id: 'personal', label: 'ภาษีบุคคลธรรมดา', icon: 'person' },
  ] },
  { group: 'ส่งบัญชี', items: [{ id: 'export', label: 'แพ็กส่งสำนักงานบัญชี', icon: 'package' }] },
  { group: 'ระบบ', items: [
    { id: 'users', label: 'ผู้ใช้และสิทธิ์', icon: 'users', role: ['owner'] },
    { id: 'settings', label: 'ตั้งค่ากิจการ', icon: 'settings' },
    { id: 'audit', label: 'ประวัติการใช้งาน', icon: 'audit' },
  ] },
];

const MOBILE_NAV = [
  { id: 'dashboard', label: 'หน้าหลัก', icon: 'dashboard' },
  { id: 'docs', label: 'เอกสาร', icon: 'docs' },
  { id: 'scan', label: 'สแกน', icon: 'scan' },
  { id: 'vat', label: 'ภ.พ.30', icon: 'vat' },
  { id: 'more', label: 'เพิ่มเติม', icon: 'settings' },
];

// Curated color themes — each tweaks the brand family only (neutrals/semantics stay fixed)
const THEMES = {
  emerald: { label: 'มรกต', swatch: 'oklch(0.53 0.108 165)', vars: { '--primary': 'oklch(0.53 0.108 165)', '--primary-dark': 'oklch(0.45 0.10 166)', '--primary-press': 'oklch(0.39 0.092 167)', '--primary-tint': 'oklch(0.965 0.028 168)', '--primary-tint2': 'oklch(0.925 0.05 168)' } },
  teal:    { label: 'เขียวน้ำทะเล', swatch: 'oklch(0.55 0.085 200)', vars: { '--primary': 'oklch(0.55 0.085 200)', '--primary-dark': 'oklch(0.47 0.08 202)', '--primary-press': 'oklch(0.41 0.075 204)', '--primary-tint': 'oklch(0.965 0.024 200)', '--primary-tint2': 'oklch(0.925 0.045 200)' } },
  navy:    { label: 'น้ำเงินกรมท่า', swatch: 'oklch(0.45 0.11 256)', vars: { '--primary': 'oklch(0.45 0.11 256)', '--primary-dark': 'oklch(0.38 0.105 257)', '--primary-press': 'oklch(0.33 0.095 258)', '--primary-tint': 'oklch(0.962 0.028 256)', '--primary-tint2': 'oklch(0.92 0.05 256)' } },
  indigo:  { label: 'คราม', swatch: 'oklch(0.48 0.13 280)', vars: { '--primary': 'oklch(0.48 0.13 280)', '--primary-dark': 'oklch(0.41 0.12 281)', '--primary-press': 'oklch(0.35 0.11 282)', '--primary-tint': 'oklch(0.963 0.03 282)', '--primary-tint2': 'oklch(0.925 0.052 282)' } },
  plum:    { label: 'เม็ดมะปราง', swatch: 'oklch(0.47 0.12 350)', vars: { '--primary': 'oklch(0.47 0.12 350)', '--primary-dark': 'oklch(0.40 0.115 351)', '--primary-press': 'oklch(0.35 0.105 352)', '--primary-tint': 'oklch(0.963 0.028 350)', '--primary-tint2': 'oklch(0.925 0.05 350)' } },
  graphite:{ label: 'กราไฟต์', swatch: 'oklch(0.40 0.02 255)', vars: { '--primary': 'oklch(0.40 0.022 255)', '--primary-dark': 'oklch(0.33 0.02 255)', '--primary-press': 'oklch(0.28 0.018 255)', '--primary-tint': 'oklch(0.96 0.006 255)', '--primary-tint2': 'oklch(0.92 0.012 255)' } },
};
function applyTheme(key) {
  const th = THEMES[key] || THEMES.emerald;
  Object.entries(th.vars).forEach(([k, v]) => document.documentElement.style.setProperty(k, v));
}

function App() {
  const [user, setUser] = useState(null);
  const [page, setPage] = useState('dashboard');
  const [entity, setEntity] = useState('company');
  const [menuOpen, setMenuOpen] = useState(false);
  const [moreOpen, setMoreOpen] = useState(false);
  const [theme, setTheme] = useState('emerald');
  const [themeOpen, setThemeOpen] = useState(false);
  const [period, setPeriod] = useState({ ...CURRENT_PERIOD });
  const [pickOpen, setPickOpen] = useState(false);
  const [booting, setBooting] = useState(true);
  const [toast, toastNode] = useToast();

  // restore preferences + try to resume an existing session from the API
  useEffect(() => {
    const sp = localStorage.getItem('bt_page'); if (sp) setPage(sp);
    const se = localStorage.getItem('bt_entity'); if (se) setEntity(se);
    const st = localStorage.getItem('bt_theme'); if (st && THEMES[st]) { setTheme(st); applyTheme(st); }
    const pp = localStorage.getItem('bt_period2'); if (pp) { try { setPeriod(JSON.parse(pp)); } catch (e) {} }
    (async () => {
      if (API.getToken()) {
        const me = await API.me();
        if (me.ok && me.data.user) {
          const st2 = await API.state();
          if (st2.ok) window.hydrateData(st2.data);
          setUser(me.data.user);
        } else { API.setToken(null); }
      }
      setBooting(false);
    })();
  }, []);
  useEffect(() => { if (user) localStorage.setItem('bt_page', page); }, [page]);
  useEffect(() => { localStorage.setItem('bt_entity', entity); }, [entity]);
  useEffect(() => { applyTheme(theme); localStorage.setItem('bt_theme', theme); }, [theme]);
  useEffect(() => { localStorage.setItem('bt_period2', JSON.stringify(period)); }, [period]);

  // called by Login after a successful API.login — fetch state, then show the app
  const login = async (u) => {
    const st = await API.state();
    if (st.ok) window.hydrateData(st.data);
    setUser(u);
    toast('เข้าสู่ระบบสำเร็จ — ' + u.name);
  };
  const logout = async () => { try { await API.logout(); } catch (e) {} setUser(null); setPage('dashboard'); };

  if (booting) return (
    <div style={{ height: '100%', display: 'grid', placeItems: 'center', color: 'var(--ink-3)' }}>
      <div style={{ textAlign: 'center' }}>
        <div className="brand-mark" style={{ margin: '0 auto 12px', width: 46, height: 46, fontSize: 22 }}>ภ</div>
        <div style={{ fontSize: 14 }}>กำลังโหลดระบบ…</div>
      </div>
    </div>
  );

  if (!user) return <><Login onLogin={login} />{toastNode}</>;

  const role = user.role;
  const pending = D.docs.filter((d) => d.status === 'pending').length;
  const nav = (id) => { setPage(id); setMenuOpen(false); setMoreOpen(false); };

  const visibleNav = NAV.map((g) => ({
    ...g,
    items: g.items.filter((it) => (!it.role || it.role.includes(role)) && (!g.entity || g.entity === entity)),
  })).filter((g) => g.items.length);

  const pageTitle = (() => {
    for (const g of NAV) for (const it of g.items) if (it.id === page) return it.label;
    return '';
  })();

  const hasData = period.m === CURRENT_PERIOD.m && period.y === CURRENT_PERIOD.y;
  const ctx = { user, role, entity, onNav: nav, toast, period, setPeriod, pShort: periodShort(period), pLong: periodLong(period), hasData };

  const renderPage = () => {
    switch (page) {
      case 'dashboard': return <Dashboard entity={entity} onNav={nav} pLong={ctx.pLong} period={period} />;
      case 'scan': return <ScanPage {...ctx} />;
      case 'docs': return <DocsPage {...ctx} />;
      case 'income': return <IncomePage {...ctx} />;
      case 'receivables': return <ReceivablesPage {...ctx} />;
      case 'expense': return <ExpensePage {...ctx} />;
      case 'vat': return <VatPage {...ctx} />;
      case 'annual': return <AnnualPage {...ctx} />;
      case 'personal': return <PersonalPage {...ctx} />;
      case 'export': return <ExportPage {...ctx} />;
      case 'users': return <UsersPage {...ctx} />;
      case 'settings': return <SettingsPage {...ctx} />;
      case 'audit': return <AuditPage {...ctx} />;
      default: return <Dashboard entity={entity} onNav={nav} />;
    }
  };

  const Sidebar = (
    <aside className={'sidebar' + (menuOpen ? ' open' : '')}>
      <div className="brand">
        <div className="brand-mark">ภ</div>
        <div><div className="brand-name">บัญชี·ภาษี</div><div className="brand-sub">จัดเตรียมเอกสารภาษี</div></div>
      </div>
      <div className="entity-switch">
        <button className={entity === 'company' ? 'on' : ''} onClick={() => { setEntity('company'); if (page === 'personal') nav('dashboard'); }}>นิติบุคคล</button>
        <button className={entity === 'personal' ? 'on' : ''} onClick={() => { setEntity('personal'); nav(['income','expense','vat'].includes(page) ? 'personal' : page); }}>บุคคลธรรมดา</button>
      </div>
      <nav className="nav">
        {visibleNav.map((g) => (
          <div key={g.group}>
            <div className="nav-group-label">{g.group}</div>
            {g.items.map((it) => (
              <button key={it.id} className={'nav-item' + (page === it.id ? ' on' : '')} onClick={() => nav(it.id)}>
                <Icon name={it.icon} className="ic" />
                {it.label}
                {it.badgeKey === 'pending' && pending > 0 && <span className="nav-badge amber">{pending}</span>}
              </button>
            ))}
          </div>
        ))}
      </nav>
      <div className="sidebar-foot">
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <button className="user-chip" style={{ flex: 1 }} onClick={() => nav('settings')}>
            <div className="avatar">{user.name[0]}</div>
            <div style={{ flex: 1, minWidth: 0, textAlign: 'left' }}>
              <div className="nm" style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{user.name}</div>
              <div className="rl">{D.roleInfo[role].label}</div>
            </div>
          </button>
          <button className="x-btn" title="ออกจากระบบ" onClick={logout}><Icon name="logout" size={18} /></button>
        </div>
      </div>
    </aside>
  );

  return (
    <div className="app">
      {Sidebar}
      {menuOpen && <div className="scrim" onClick={() => setMenuOpen(false)}></div>}
      <div className="main">
        <header className="topbar">
          <button className="menu-btn" onClick={() => setMenuOpen(true)}><Icon name="docs" size={20} /></button>
          <div>
            <h1>{pageTitle}</h1>
          </div>
          <div style={{ position: 'relative', marginLeft: 'auto' }}>
            <button className="period-pill" style={{ marginLeft: 0, cursor: 'pointer' }} onClick={() => setPickOpen((o) => !o)}>
              <Icon name="calendar" size={15} style={{ color: 'var(--primary)' }} />{periodShort(period)}
              <Icon name="chevD" size={14} style={{ color: 'var(--ink-3)' }} />
            </button>
            {pickOpen && <MonthYearPicker period={period} onPick={(p) => { setPeriod(p); setPickOpen(false); }} onClose={() => setPickOpen(false)} />}
          </div>
          <div style={{ position: 'relative' }}>
            <button className="x-btn" title="เปลี่ยนธีมสี" onClick={() => setThemeOpen((o) => !o)}>
              <span style={{ width: 18, height: 18, borderRadius: '50%', background: THEMES[theme].swatch, border: '2px solid var(--surface)', boxShadow: '0 0 0 1px var(--line)' }}></span>
            </button>
            {themeOpen && (
              <>
                <div style={{ position: 'fixed', inset: 0, zIndex: 49 }} onClick={() => setThemeOpen(false)}></div>
                <div className="card" style={{ position: 'absolute', right: 0, top: 44, zIndex: 50, padding: 12, boxShadow: 'var(--shadow-lg)', width: 192 }}>
                  <div style={{ fontSize: 11.5, fontWeight: 600, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '.03em', marginBottom: 9, paddingLeft: 2 }}>ธีมสีระบบ</div>
                  <div style={{ display: 'grid', gridTemplateColumns: '1fr', gap: 4 }}>
                    {Object.entries(THEMES).map(([k, th]) => (
                      <button key={k} onClick={() => { setTheme(k); setThemeOpen(false); toast('เปลี่ยนธีมเป็น ' + th.label); }}
                        style={{ display: 'flex', alignItems: 'center', gap: 9, padding: '8px 10px', borderRadius: 9, border: '1px solid ' + (theme === k ? 'var(--primary)' : 'transparent'), background: theme === k ? 'var(--primary-tint)' : 'transparent', textAlign: 'left' }}
                        onMouseEnter={(e) => { if (theme !== k) e.currentTarget.style.background = 'var(--surface-2)'; }} onMouseLeave={(e) => { if (theme !== k) e.currentTarget.style.background = 'transparent'; }}>
                        <span style={{ width: 16, height: 16, borderRadius: '50%', background: th.swatch, flexShrink: 0 }}></span>
                        <span style={{ fontSize: 13, fontWeight: 600 }}>{th.label}</span>
                        {theme === k && <Icon name="check" size={15} style={{ marginLeft: 'auto', color: 'var(--primary)' }} />}
                      </button>
                    ))}
                  </div>
                </div>
              </>
            )}
          </div>
          <button className="x-btn" style={{ position: 'relative' }} title="การแจ้งเตือน">
            <Icon name="bell" size={19} />
            <span style={{ position: 'absolute', top: 6, right: 7, width: 7, height: 7, borderRadius: '50%', background: 'var(--danger)', border: '1.5px solid var(--surface)' }}></span>
          </button>
        </header>
        <main className="content">{renderPage()}</main>
      </div>

      {/* mobile bottom nav */}
      <nav className="bottom-nav">
        {MOBILE_NAV.map((it) => (
          <button key={it.id} className={(page === it.id || (it.id === 'more' && moreOpen)) ? 'on' : ''} onClick={() => it.id === 'more' ? setMoreOpen(true) : nav(it.id)}>
            <Icon name={it.icon} className="ic" />{it.label}
          </button>
        ))}
      </nav>

      {moreOpen && (
        <div className="overlay" onMouseDown={(e) => e.target === e.currentTarget && setMoreOpen(false)} style={{ alignItems: 'flex-end' }}>
          <div className="modal" style={{ maxWidth: 520, borderRadius: '18px 18px 0 0', animation: 'pop .2s' }}>
            <div className="modal-head"><h3>เมนูเพิ่มเติม</h3><button className="x-btn" onClick={() => setMoreOpen(false)}><Icon name="x" size={18} /></button></div>
            <div className="modal-body">
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
                {visibleNav.flatMap((g) => g.items).filter((it) => !MOBILE_NAV.find((m) => m.id === it.id)).map((it) => (
                  <button key={it.id} className="card" style={{ padding: 14, display: 'flex', flexDirection: 'column', gap: 9, alignItems: 'flex-start' }} onClick={() => nav(it.id)}>
                    <div className="stat-ic" style={{ background: 'var(--primary-tint)', color: 'var(--primary)' }}><Icon name={it.icon} size={18} /></div>
                    <span style={{ fontWeight: 600, fontSize: 13.5 }}>{it.label}</span>
                  </button>
                ))}
              </div>
              <div style={{ marginTop: 14, padding: 12, background: 'var(--surface-2)', borderRadius: 11, display: 'flex', alignItems: 'center', gap: 10 }}>
                <div className="avatar">{user.name[0]}</div>
                <div style={{ flex: 1 }}><div style={{ fontWeight: 600, fontSize: 13.5 }}>{user.name}</div><div style={{ fontSize: 12, color: 'var(--ink-3)' }}>{D.roleInfo[role].label}</div></div>
                <button className="btn btn-ghost btn-sm" onClick={logout}><Icon name="logout" className="ic" />ออก</button>
              </div>
            </div>
          </div>
        </div>
      )}
      {toastNode}
    </div>
  );
}

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