/* global React, ReactDOM, Icon, MOCK,
   DashboardPage, OrdersPage, StockOpnamePage, PackingModal, InventoryPage, InboundPage, StoresPage, ReturnsPage, ReportsPage, SettingsPage,
   MaterialsPage, OperatingCostPage, ProfitLossPage, BalanceSheetPage, CashFlowPage,
   AccountsPage, JournalsPage, CashBankPage, ReconciliationPage, TrialBalancePage,
   GeneralLedgerPage, RecurringPage, ClosingPage,
   ContactsPage, AgingReportPage, AuditLogPage, FixedAssetsPage,
   TweaksPanel, useTweaks, TweakSection, TweakRadio, TweakColor, TweakToggle */

const { useState, useEffect } = React;

// ===== Roles =====
// owner       — sees everything, including finance
// gudang      — admin gudang: operasional packing, inbound, materials only
// finance     — laba rugi, neraca, arus kas, biaya, pembelian material
const ROLES = {
  owner:   { label:"Owner",         sub:"Akses penuh",       initials:"BS", name:"Budi Santoso",     org:"Berkah Jaya" },
  gudang:  { label:"Admin Gudang",  sub:"Operasional",       initials:"AS", name:"Asep Sunandar",    org:"Gudang Surabaya" },
  finance: { label:"Admin Finance", sub:"Keuangan",          initials:"NW", name:"Nadya Wulandari",  org:"Finance · HQ" },
};

// Pages each role can see (id → roles[])
const PAGE_ACCESS = {
  dashboard:   ['owner','gudang','finance'],
  orders:      ['owner','gudang'],
  opname:      ['owner','gudang','finance'],
  packing:     ['owner','gudang'],
  returns:     ['owner','gudang'],
  inventory:   ['owner','gudang','finance'],
  inbound:     ['owner','gudang'],
  materials:   ['owner','gudang','finance'],
  matpurchase: ['owner','finance'],
  stores:      ['owner','gudang'],
  reports:     ['owner','finance'],
  costs:       ['owner','finance'],
  pl:          ['owner','finance'],
  balance:     ['owner','finance'],
  cashflow:    ['owner','finance'],
  accounts:    ['owner','finance'],
  journals:    ['owner','finance'],
  gl:          ['owner','finance'],
  cashbank:    ['owner','finance'],
  recon:       ['owner','finance'],
  trialbal:    ['owner','finance'],
  recurring:   ['owner','finance'],
  closing:     ['owner','finance'],
  contacts:    ['owner','finance','gudang'],
  aging:       ['owner','finance'],
  audit:       ['owner'],
  fixedasset:  ['owner','finance'],
  settings:    ['owner','gudang','finance'],
};

const NAV_GROUPS = [
  { section: "Operasional", items: [
    { id:"dashboard", label:"Dashboard",      icon:"dashboard" },
    { id:"orders",    label:"Pesanan",        icon:"orders", badge:"38" },
    { id:"packing",   label:"Packing",        icon:"packing" },
    { id:"returns",   label:"Retur",          icon:"returns", badge:"2" },
  ]},
  { section: "Katalog & Stok", items: [
    { id:"inventory", label:"Stok & Produk",  icon:"inventory" },
    { id:"opname",    label:"Stock Opname",   icon:"inventory" },
    { id:"inbound",   label:"Penerimaan",     icon:"inbound", badge:"1" },
    { id:"materials", label:"Bahan Material", icon:"material" },
    { id:"stores",    label:"Toko Marketplace", icon:"stores" },
  ]},
  { section: "Akuntansi", items: [
    { id:"accounts",  label:"Akun Perkiraan", icon:"ledger" },
    { id:"journals",  label:"Jurnal Umum",    icon:"finance" },
    { id:"recurring", label:"Jurnal Berulang", icon:"finance" },
    { id:"gl",        label:"Buku Besar",     icon:"reports" },
    { id:"cashbank",  label:"Kas & Bank",     icon:"cash" },
    { id:"recon",     label:"Rekonsiliasi",   icon:"flow" },
    { id:"trialbal",  label:"Neraca Saldo",   icon:"reports" },
    { id:"aging",     label:"Aging Report",   icon:"finance" },
    { id:"contacts",  label:"Kontak",         icon:"help" },
    { id:"fixedasset",label:"Aset Tetap",     icon:"box" },
    { id:"closing",   label:"Tutup Buku",     icon:"finance" },
    { id:"audit",     label:"Audit Log",      icon:"settings" },
  ]},
  { section: "Laporan Keuangan", items: [
    { id:"costs",     label:"Biaya Berjalan", icon:"cost" },
    { id:"pl",        label:"Laba Rugi",      icon:"finance" },
    { id:"balance",   label:"Neraca",         icon:"ledger" },
    { id:"cashflow",  label:"Arus Kas",       icon:"flow" },
  ]},
  { section: "Lainnya", items: [
    { id:"reports",   label:"Laporan",        icon:"reports" },
    { id:"settings",  label:"Pengaturan",     icon:"settings" },
  ]},
];

function App() {
  const [bootState, setBootState] = useState('loading'); // loading | ready | error
  const [bootError, setBootError] = useState('');
  const [role, setRole] = useState('owner');
  const [page, setPage] = useState('dashboard');
  const [packing, setPacking] = useState(false);
  const [roleOpen, setRoleOpen] = useState(false);

  // Load session + initial data once on mount
  useEffect(() => {
    (async () => {
      try {
        const u = await window.Api.loadAppData();
        if (u?.role) setRole(u.role);
        setBootState('ready');
      } catch (e) {
        if (e.message === 'unauthenticated') return; // already redirected
        setBootError(e.message || 'Gagal memuat data');
        setBootState('error');
      }
    })();
  }, []);

  // If role switches and current page not allowed, jump to dashboard
  useEffect(() => {
    if (!PAGE_ACCESS[page]?.includes(role)) setPage('dashboard');
  }, [role]);

  const switchRole = async (newRole) => {
    try {
      await window.Api.patch('/api/me/role', { role: newRole });
      // Refresh data because scoping may differ per role
      await window.Api.loadAppData();
      setRole(newRole);
      setRoleOpen(false);
    } catch (e) {
      alert('Gagal ganti peran: ' + (e.message || ''));
    }
  };

  const logout = async () => {
    try { await window.Api.auth.signOut(); } catch {}
    window.location.href = 'login.html';
  };

  const [tweaks, setTweak] = useTweaks(/*EDITMODE-BEGIN*/{
    "accentColor": "#ed3a1a",
    "density": "comfortable",
    "showRealtime": true,
    "language": "id"
  }/*EDITMODE-END*/);

  useEffect(() => {
    document.documentElement.style.setProperty('--brand-500', tweaks.accentColor);
  }, [tweaks.accentColor]);

  const go = (p) => {
    if (p === 'packing') { setPacking(true); return; }
    setPage(p);
    window.scrollTo(0, 0);
  };

  // Bootstrapping splash
  if (bootState === 'loading') {
    return (
      <div style={{
        position:'fixed', inset:0, display:'grid', placeItems:'center',
        background:'var(--bg, #fafaf8)', flexDirection:'column', gap:14
      }}>
        <div style={{
          width:46, height:46, border:'3px solid var(--border, #eee)',
          borderTopColor:'var(--brand-500, #ed3a1a)', borderRadius:'50%',
          animation:'spin .8s linear infinite'
        }}/>
        <div style={{ fontSize:13, color:'var(--ink-500, #666)' }}>Memuat data Simantep…</div>
        <style>{`@keyframes spin { to { transform: rotate(360deg) } }`}</style>
      </div>
    );
  }
  if (bootState === 'error') {
    return (
      <div style={{ padding:40, fontFamily:'system-ui' }}>
        <h2>Gagal memuat dashboard</h2>
        <p style={{ color:'#a82210' }}>{bootError}</p>
        <button onClick={() => location.reload()} style={{ padding:'8px 16px' }}>Coba lagi</button>
      </div>
    );
  }

  const apiUser = window.__user || {};
  const user = {
    ...ROLES[role],
    name: apiUser.name || ROLES[role].name,
    org: apiUser.businessName || ROLES[role].org,
    initials: (apiUser.name || ROLES[role].name)
      .split(' ').map(s => s[0]).slice(0, 2).join('').toUpperCase(),
  };

  // Filter visible nav by role + drop empty sections
  const visibleNav = NAV_GROUPS
    .map(g => ({ ...g, items: g.items.filter(it => PAGE_ACCESS[it.id]?.includes(role)) }))
    .filter(g => g.items.length > 0);

  return (
    <div className="app" data-role={role}>
      {/* SIDEBAR */}
      <aside className="sidebar">
        <div className="sb-brand">
          <img src={window.__resources?.logo || "assets/simantep-logo.png"} alt="Simantep"/>
          <div className="sb-brand-text">
            <strong>Simantep</strong>
            <span>WMS</span>
          </div>
        </div>

        {visibleNav.map(g => (
          <React.Fragment key={g.section}>
            <div className="sb-section">{g.section}</div>
            {g.items.map(it => {
              const I = Icon[it.icon];
              const active = page === it.id || (it.id === 'packing' && packing);
              return (
                <button key={it.id} className={`sb-item ${active?'active':''}`} onClick={() => go(it.id)}>
                  <I/>
                  <span>{it.label}</span>
                  {it.badge && <span className="sb-badge">{it.badge}</span>}
                </button>
              );
            })}
          </React.Fragment>
        ))}

        <div className="sb-footer">
          <button className="sb-user sb-user-btn" onClick={() => setRoleOpen(o => !o)}>
            <div className="sb-avatar" data-role={role}>{user.initials}</div>
            <div className="sb-user-meta">
              <strong>{user.name}</strong>
              <span>{user.label} · {user.org}</span>
            </div>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ opacity:.5 }}>
              <path d="M7 10l5-5 5 5M7 14l5 5 5-5"/>
            </svg>
          </button>

          {roleOpen && (
            <div className="role-menu">
              <div className="role-menu-title">Beralih peran (demo)</div>
              {Object.entries(ROLES).map(([k, r]) => (
                <button key={k} className={`role-opt ${role===k?'on':''}`} onClick={() => switchRole(k)}>
                  <div className="sb-avatar" data-role={k}>{r.initials}</div>
                  <div style={{ flex:1, textAlign:'left' }}>
                    <strong style={{ display:'block', fontSize:13 }}>{r.label}</strong>
                    <span style={{ fontSize:11.5, color:'var(--ink-500)' }}>{r.name} — {r.sub}</span>
                  </div>
                  {role===k && <Icon.check/>}
                </button>
              ))}
              <button onClick={logout} className="role-opt" style={{ borderTop:'1px solid var(--border)', marginTop:6, paddingTop:10, color:'var(--ink-600)', width:'100%' }}>
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ marginLeft:4 }}>
                  <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9"/>
                </svg>
                <span style={{ fontSize:13 }}>Keluar</span>
              </button>
            </div>
          )}
        </div>
      </aside>

      {/* MAIN */}
      <main className="main">
        <header className="topbar">
          <div className="tb-search">
            <Icon.search/>
            <input placeholder="Cari pesanan, produk, atau pembeli…"/>
            <kbd>⌘K</kbd>
          </div>
          {tweaks.showRealtime && (
            <div className="tb-store-pill">
              <span className="dot-online"/>
              Real-time aktif
            </div>
          )}
          <LiveClock/>
          <div className="tb-actions">
            <button className="tb-icon-btn" title="Bantuan"><Icon.help/></button>
            <button className="tb-icon-btn" title="Notifikasi"><Icon.bell/><span className="dot"/></button>
            <div className="tb-divider"/>
            {(role === 'owner' || role === 'gudang') && (
              <button className="btn btn-primary btn-sm" onClick={() => setPacking(true)}>
                <Icon.scan/> Packing
              </button>
            )}
            {role === 'finance' && (
              <button className="btn btn-primary btn-sm" onClick={() => go('costs')}>
                <Icon.cost/> Biaya Berjalan
              </button>
            )}
          </div>
        </header>

        {page === 'dashboard'   && <DashboardPage go={go} role={role}/>}
        {page === 'orders'      && <OrdersPage openPacking={() => setPacking(true)}/>}
        {page === 'opname'      && <StockOpnamePage/>}
        {page === 'inventory'   && <InventoryPage/>}
        {page === 'inbound'     && <InboundPage/>}
        {page === 'materials'   && <MaterialsPage/>}
        {page === 'stores'      && <StoresPage/>}
        {page === 'returns'     && <ReturnsPage/>}
        {page === 'reports'     && <ReportsPage/>}
        {page === 'accounts'    && <AccountsPage/>}
        {page === 'journals'    && <JournalsPage/>}
        {page === 'recurring'   && <RecurringPage/>}
        {page === 'gl'          && <GeneralLedgerPage/>}
        {page === 'cashbank'    && <CashBankPage/>}
        {page === 'recon'       && <ReconciliationPage/>}
        {page === 'trialbal'    && <TrialBalancePage/>}
        {page === 'closing'     && <ClosingPage/>}
        {page === 'contacts'    && <ContactsPage/>}
        {page === 'aging'       && <AgingReportPage/>}
        {page === 'audit'       && <AuditLogPage/>}
        {page === 'fixedasset'  && <FixedAssetsPage/>}
        {page === 'costs'       && <OperatingCostPage/>}
        {page === 'pl'          && <ProfitLossPage/>}
        {page === 'balance'     && <BalanceSheetPage/>}
        {page === 'cashflow'    && <CashFlowPage/>}
        {page === 'settings'    && <SettingsPage/>}
      </main>

      {packing && <PackingModal onClose={() => setPacking(false)}/>}

      <TweaksPanel title="Tweaks">
        <TweakSection title="Branding">
          <TweakColor label="Warna utama" value={tweaks.accentColor}
            onChange={v => setTweak('accentColor', v)}
            presets={["#ed3a1a","#d12a0d","#ff6b50","#1f6fd9","#1c8e5a","#1a1614"]}
          />
        </TweakSection>
        <TweakSection title="Tampilan">
          <TweakRadio label="Density" value={tweaks.density}
            onChange={v => setTweak('density', v)}
            options={[
              {value:"comfortable", label:"Nyaman"},
              {value:"compact", label:"Kompak"},
            ]}
          />
          <TweakRadio label="Peran (preview)" value={role}
            onChange={v => setRole(v)}
            options={[
              {value:"owner", label:"Owner"},
              {value:"gudang", label:"Gudang"},
              {value:"finance", label:"Finance"},
            ]}
          />
          <TweakToggle label="Tampilkan status real-time" value={tweaks.showRealtime}
            onChange={v => setTweak('showRealtime', v)}/>
        </TweakSection>
      </TweaksPanel>
    </div>
  );
}

// Live clock pill in topbar — updates every second.
function LiveClock() {
  const [now, setNow] = useState(new Date());
  useEffect(() => {
    const t = setInterval(() => setNow(new Date()), 1000);
    return () => clearInterval(t);
  }, []);
  const dateStr = window.fmtDateLong ? window.fmtDateLong(now) : now.toLocaleDateString('id-ID');
  const hh = String(now.getHours()).padStart(2, '0');
  const mm = String(now.getMinutes()).padStart(2, '0');
  const ss = String(now.getSeconds()).padStart(2, '0');
  return (
    <div className="tb-clock" title={dateStr} style={{
      display:'flex', alignItems:'center', gap:8,
      padding:'6px 12px', borderRadius:'var(--r-md, 8px)',
      background:'var(--surface-2, #f3f3f0)',
      border:'1px solid var(--border, #e5e5e5)',
      fontSize:12.5, color:'var(--ink-700, #444)',
      lineHeight:1, whiteSpace:'nowrap',
    }}>
      <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ opacity:.6 }}>
        <circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>
      </svg>
      <span style={{ fontFeatureSettings:'"tnum"', fontWeight:600 }}>
        {hh}:{mm}<span style={{ opacity:.5 }}>:{ss}</span>
      </span>
      <span style={{ opacity:.5 }}>·</span>
      <span style={{ color:'var(--ink-500, #666)' }}>{dateStr}</span>
    </div>
  );
}

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