// admin/admin-app.jsx — Owner / ERP portal shell (Ambady workspace)

function useAdminRoute() {
  const parse = () => {
    const raw = (location.hash || '#/dashboard').slice(1);
    const [path, query] = raw.split('?');
    const seg = path.split('/').filter(Boolean);
    const params = {};
    (query || '').split('&').filter(Boolean).forEach(kv => { const [k, v] = kv.split('='); params[k] = decodeURIComponent(v || ''); });
    return { page: seg[0] || 'dashboard', params, crumbs: seg };
  };
  const [route, setRoute] = React.useState(parse());
  React.useEffect(() => {
    const fn = () => setRoute(parse());
    window.addEventListener('hashchange', fn);
    return () => window.removeEventListener('hashchange', fn);
  }, []);
  return route;
}

function go(page, params) {
  let h = '#/' + page;
  if (params && Object.keys(params).length) {
    h += '?' + Object.entries(params).map(([k, v]) => k + '=' + encodeURIComponent(v)).join('&');
  }
  location.hash = h;
}

const TITLES = {
  dashboard: 'Command Center', products: 'Products', inventory: 'Inventory',
  orders: 'Orders', customers: 'Customers', whatsapp: 'Communication',
  finance: 'Finance & GST', settings: 'Settings', imports: 'Import Center',
  rinpo: 'RINPO', intelligence: 'Intelligence Center', audit: 'Audit Log', health: 'System Health', integrity: 'Data Integrity',
  segments: 'CRM Segments', memory: 'Memory Explorer', graph: 'Memory Graph', quality: 'Data Quality', fulfilment: 'Fulfilment', automation: 'Automation',
  reviews: 'Reviews moderation', support: 'Support inbox',
  coupons: 'Coupons', redirects: 'Slug redirects', analytics: 'Analytics', campaigns: 'Campaigns',
  suppliers: 'Suppliers', 'purchase-orders': 'Purchase orders', transfers: 'Transfers',
  returns: 'Returns', tasks: 'Tasks', 'work-queue': 'Work queue'
};

function CapDot({ status }) {
  const label = status === 'live' ? 'Live' : status === 'partial' ? 'Partial' : 'Blocked';
  return <span className={'cap-dot cap-' + status} title={label} aria-label={label} />;
}

function GlobalSearch() {
  const [q, setQ] = React.useState('');
  const [open, setOpen] = React.useState(false);
  const results = q.trim() ? OwnerSearch.searchOwner(q, 12) : [];
  return (
    <div className="gs" onBlur={() => setTimeout(() => setOpen(false), 150)}>
      <div className="search-box gs__box">
        <AIcon name="search" />
        <input
          className="inp"
          placeholder="Search products, SKU, orders, customers…"
          value={q}
          onChange={(e) => { setQ(e.target.value); setOpen(true); }}
          onFocus={() => setOpen(true)}
          aria-label="Global search"
        />
      </div>
      {open && q.trim() && (
        <div className="gs__panel" role="listbox">
          {results.length === 0 ? (
            <div className="gs__empty muted">No matches</div>
          ) : results.map((r) => (
            <a key={r.entityType + r.id} className="gs__item" href={r.href} onClick={() => { setOpen(false); setQ(''); }}>
              <span className="badge b-new">{r.entityType}</span>
              <span className="gs__id">{r.subtitle}</span>
              <span className="gs__title">{r.title}</span>
            </a>
          ))}
        </div>
      )}
    </div>
  );
}

function QuickActions({ go }) {
  const [open, setOpen] = React.useState(false);
  const actions = [
    { label: 'Add product', run: () => go('products', { new: '1' }) },
    { label: 'Import products', run: () => go('imports') },
    { label: 'Adjust stock', run: () => go('inventory') },
    { label: 'Work queue', run: () => go('work-queue') },
    { label: 'Orders to pack', run: () => go('fulfilment') }
  ];
  return (
    <div className="qa">
      <button className="btn btn-sm btn-primary" onClick={() => setOpen((o) => !o)} aria-expanded={open}><AIcon name="plus" size={14} /> Quick</button>
      {open && (
        <div className="qa__menu">
          {actions.map((a) => (
            <button key={a.label} onClick={() => { setOpen(false); a.run(); }}>{a.label}</button>
          ))}
        </div>
      )}
    </div>
  );
}

function AdminApp() {
  const admin = useAdmin();
  const route = useAdminRoute();
  const [ready, setReady] = React.useState(!(window.APG_CONFIG && window.APG_CONFIG.useRemote));
  const [authed, setAuthed] = React.useState(!!admin.getAdmin());
  const [navOpen, setNavOpen] = React.useState(false);

  React.useEffect(() => {
    if (window.APG && window.APG.init) {
      window.APG.init().then(() => {
        setReady(true);
        setAuthed(!!admin.getAdmin());
        if (admin.getAdmin() && window.RinadsTenant && window.RinadsTenant.tenantLoginFromLegacyAdmin) {
          window.RinadsTenant.tenantLoginFromLegacyAdmin(admin.getAdmin());
          window.RinadsTenant.applyTenantTheme(document);
        }
        if (window.OwnerRuntime) window.OwnerRuntime.bootstrapTick();
      }).catch(() => setReady(true));
    } else setReady(true);
  }, []);

  React.useEffect(() => { if (ready) admin.seedDemoOrders(); }, [ready]);
  React.useEffect(() => { setNavOpen(false); }, [route.page]);

  React.useEffect(() => {
    if (!ready || !authed) return;
    if (route.page === 'rinpo' && window.RinpoRuntime) {
      window.RinpoRuntime.open({ tab: 'chat', source: 'route_rinpo', surface: 'admin' });
      go('dashboard');
    }
  }, [ready, authed, route.page]);

  if (!ready) {
    return (
      <div className="login-wrap">
        <div className="login-card" style={{ textAlign: 'center' }}>Loading owner portal…</div>
      </div>
    );
  }

  if (!authed) return <AdminLogin onIn={() => setAuthed(true)} />;

  const orders = admin.getOrders();
  const pending = orders.filter(o => ['new', 'packed', 'shipped', 'out_for_delivery'].includes(o.status)).length;
  const lowStock = HAP.PRODUCTS.filter(p => admin.stockStatus(p) !== 'in').length;
  const rolePreview = (typeof sessionStorage !== 'undefined' && sessionStorage.getItem('apg.owner.rolePreview')) || 'admin_legacy';
  const NAV = (OwnerCaps.navForRole ? OwnerCaps.navForRole(rolePreview) : OwnerCaps.NAV);
  const tenant = (window.RinadsTenant && window.RinadsTenant.currentTenant && window.RinadsTenant.currentTenant()) || (window.ErpCore && window.ErpCore.AMBADY_TENANT) || { name: 'Ambady Pebbles Garden', merchantBrand: 'Ambady Pebbles Garden', idPrefix: 'APG' };
  const brandName = tenant.merchantBrand || tenant.name || 'Ambady';
  const brandMark = (brandName.split(' ')[0] || 'TENANT').toUpperCase();

  const PageMap = {
    dashboard: DashboardPage,
    products: ProductsPage,
    inventory: InventoryHubPage,
    orders: OrdersPage,
    customers: CrmPage,
    whatsapp: WhatsAppPage,
    finance: FinancePage,
    settings: SettingsPage,
    imports: ImportsPage,
    rinpo: DashboardPage,
    intelligence: typeof IntelligenceCenterPage !== 'undefined' ? IntelligenceCenterPage : RinpoPage,
    integrity: IntegrityPage,
    audit: AuditPage,
    health: HealthPage,
    segments: SegmentsPage,
    memory: MemoryExplorerPage,
    graph: GraphExplorerPage,
    quality: DataQualityPage,
    fulfilment: OpsFulfilmentPage,
    automation: AutomationPage,
    reviews: ReviewsModerationPage,
    support: SupportInboxPage,
    coupons: CouponsPage,
    redirects: RedirectsPage,
    analytics: AnalyticsPage,
    campaigns: CampaignsPage,
    suppliers: SuppliersPage,
    'purchase-orders': PurchaseOrdersPage,
    transfers: TransfersPage,
    returns: ReturnsPage,
    tasks: TasksPage,
    'work-queue': WorkQueuePage
  };
  const Page = PageMap[route.page] || function AdminNotFound() {
    return <NotFoundPage homeHref="#/dashboard" title="Page not found" />;
  };

  const mobileNav = [
    { page: 'dashboard', label: 'Home', icon: 'dashboard' },
    { page: 'orders', label: 'Orders', icon: 'truck' },
    { page: 'products', label: 'Catalog', icon: 'box' },
    { page: 'inventory', label: 'Stock', icon: 'layers' },
    { page: 'rinpo', label: 'RINPO', icon: 'star', openRuntime: true }
  ];

  const openOwnerRinpo = function (e) {
    if (e) e.preventDefault();
    if (window.RinpoRuntime) {
      window.RinpoRuntime.open({ tab: 'chat', source: 'bottom_nav', surface: 'admin' });
    } else {
      go('rinpo');
    }
  };

  return (
    <AppErrorBoundary homeHref="#/dashboard">
    <div className="admin owner app-shell app-shell--admin">
      <aside className={'sidebar' + (navOpen ? ' open' : '')} aria-label="Owner navigation">
        <div className="sidebar__brand">
          <svg width="28" height="34" viewBox="0 0 34 40" fill="none" aria-hidden="true"><path d="M17 9c0-3 2.4-5.4 5.4-5.6C22.2 6.4 19.9 9 17 9z" fill="#7aa84a"/><ellipse cx="17" cy="15.5" rx="6.5" ry="3.1" fill="#c4533f"/><ellipse cx="17" cy="22" rx="9" ry="3.8" fill="#9c2f22"/><ellipse cx="17" cy="29.5" rx="11.5" ry="4.4" fill="#c4533f"/></svg>
          <div>
            <div className="mark">{brandMark}</div>
            <div className="sub">Landscape OS</div>
          </div>
        </div>
        <div className="tenant-chip">Tenant: {brandName} · {tenant.idPrefix || 'APG'}</div>
        <nav className="sidebar__nav">
          {NAV.map((item, i) => item.section
            ? <div key={i} className="sidebar__section">{item.section}</div>
            : <a key={item.page} className={'nav-link' + (route.page === item.page ? ' active' : '')} href={'#/' + item.page}>
                <AIcon name={item.icon} />
                <span style={{ flex: 1 }}>{item.label}</span>
                <CapDot status={(OwnerCaps.getCap(item.cap || item.page) || {}).status || 'partial'} />
                {item.badge === 'pending' && pending > 0 && <span className="count">{pending}</span>}
                {item.page === 'inventory' && lowStock > 0 && <span className="count">{lowStock}</span>}
              </a>
          )}
        </nav>
        <div className="sidebar__foot">
          <div className="muted" style={{ fontSize: '.72rem', padding: '0 12px 8px' }}>
            Role preview: <b>{rolePreview}</b>
            {rolePreview !== 'admin_legacy' && (
              <button className="btn btn-sm btn-ghost" style={{ marginLeft: 6 }} onClick={() => {
                sessionStorage.setItem('apg.owner.rolePreview', 'admin_legacy');
                location.reload();
              }}>Reset</button>
            )}
          </div>
          <a className="nav-link" href="index.html" target="_blank" rel="noreferrer"><AIcon name="store" />View storefront</a>
          <button className="nav-link" style={{ width: '100%' }} onClick={async () => { await admin.adminLogout(); setAuthed(false); }}><AIcon name="logout" />Sign out</button>
        </div>
      </aside>

      <div className="main app-shell__main">
        <div className="topbar app-shell__top">
          <button className="btn btn-icon btn-ghost menu-toggle" aria-label="Open menu" onClick={() => setNavOpen(o => !o)}><AIcon name="menu" /></button>
          <div className="topbar__titles">
            <div className="crumbs muted">Landscape OS {route.page !== 'dashboard' ? '› ' + (TITLES[route.page] || route.page) : ''}</div>
            <h1>{TITLES[route.page] || 'Owner'}</h1>
          </div>
          <GlobalSearch />
          <div className="topbar__spacer"></div>
          <QuickActions go={go} />
          {pending > 0 && <span className="badge b-out_for_delivery"><AIcon name="bell" size={13} />{pending}</span>}
          <span className="muted profile-chip">{(admin.getAdmin() && admin.getAdmin().email) || 'Owner'}</span>
        </div>
        <div className="content">
          <Page go={go} params={route.params} />
        </div>
      </div>

      <nav className="bottom-nav app-shell__nav" aria-label="Mobile primary">
        {mobileNav.map((n) => (
          n.openRuntime ? (
            <a key={n.page} href="#/rinpo" className={route.page === n.page ? 'on' : ''} onClick={openOwnerRinpo}>
              <AIcon name={n.icon} size={18} />
              <span>{n.label}</span>
            </a>
          ) : (
            <a key={n.page} href={'#/' + n.page} className={route.page === n.page ? 'on' : ''}>
              <AIcon name={n.icon} size={18} />
              <span>{n.label}</span>
            </a>
          )
        ))}
      </nav>

      {navOpen && <div className="no-print scrim-nav" onClick={() => setNavOpen(false)}></div>}
      <div className="app-shell__rinpo">
        <OwnerRinpoFab badge={pending > 0 ? pending : null} />
      </div>
      <div className="app-shell__overlays">
        {typeof AdminRinpoPhoneOverlay !== 'undefined' && <AdminRinpoPhoneOverlay />}
      </div>
    </div>
    </AppErrorBoundary>
  );
}

function AdminLogin({ onIn }) {
  const admin = useAdmin();
  const remote = !!(window.APG_CONFIG && window.APG_CONFIG.useRemote);
  const [email, setEmail] = React.useState('');
  const [pass, setPass] = React.useState('');
  const [err, setErr] = React.useState(false);
  const [loading, setLoading] = React.useState(false);
  const submit = async (e) => {
    e.preventDefault();
    setLoading(true);
    setErr(false);
    const ok = remote
      ? await admin.adminLogin(email, pass)
      : await admin.adminLogin(pass);
    setLoading(false);
    if (ok) onIn();
    else setErr(true);
  };
  return (
    <div className="login-wrap">
      <form className="login-card" onSubmit={submit}>
        <div className="row" style={{ gap: 10, marginBottom: 8 }}>
          <svg width="30" height="36" viewBox="0 0 34 40" fill="none" aria-hidden="true"><path d="M17 9c0-3 2.4-5.4 5.4-5.6C22.2 6.4 19.9 9 17 9z" fill="#7aa84a"/><ellipse cx="17" cy="15.5" rx="6.5" ry="3.1" fill="#c4533f"/><ellipse cx="17" cy="22" rx="9" ry="3.8" fill="#9c2f22"/><ellipse cx="17" cy="29.5" rx="11.5" ry="4.4" fill="#c4533f"/></svg>
          <div>
            <div style={{ fontWeight: 700, letterSpacing: '.12em', fontSize: '1.15rem', color: 'var(--a-maroon)' }}>AMBADY</div>
            <div style={{ fontSize: 8, letterSpacing: '.26em', textTransform: 'uppercase', color: 'var(--a-forest)' }}>Landscape OS · powered by RINPO</div>
          </div>
        </div>
        <h2 className="serif" style={{ fontSize: '1.8rem', marginTop: 16 }}>Welcome back</h2>
        <p className="muted" style={{ fontSize: '.86rem', marginTop: 4, marginBottom: 22 }}>
          {remote ? 'Sign in with your admin account.' : 'Local adapter mode — admin passcode required. Not multi-tenant RBAC.'}
        </p>
        {remote ? (
          <>
            <div className="field" style={{ marginBottom: 10 }}>
              <label>Email</label>
              <input className="inp" type="email" value={email} autoFocus onChange={e => { setEmail(e.target.value); setErr(false); }} placeholder="admin@example.com" autoComplete="username" />
            </div>
            <div className="field" style={{ marginBottom: 6 }}>
              <label>Password</label>
              <input className="inp" type="password" value={pass} onChange={e => { setPass(e.target.value); setErr(false); }} placeholder="Your password" autoComplete="current-password" />
            </div>
          </>
        ) : (
          <div className="field" style={{ marginBottom: 6 }}>
            <label>Passcode</label>
            <input className="inp" type="password" value={pass} autoFocus onChange={e => { setPass(e.target.value); setErr(false); }} placeholder="Enter admin passcode" autoComplete="current-password" />
          </div>
        )}
        {err && <p style={{ color: 'var(--a-red)', fontSize: '.8rem' }}>{remote ? 'Invalid email or password.' : 'Incorrect passcode.'}</p>}
        <button className="btn btn-primary" type="submit" disabled={loading} style={{ width: '100%', marginTop: 16 }}>{loading ? 'Signing in…' : 'Sign in'}</button>
      </form>
    </div>
  );
}

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