/* =====================================================================
   AI-COS Essential — Root app: auth session → shell (production)
   ===================================================================== */
/* Keeps one faulty screen from white-screening the whole app. */
class ErrorBoundary extends React.Component {
  constructor(p) { super(p); this.state = { err: null }; }
  static getDerivedStateFromError(err) { return { err }; }
  componentDidCatch(err) { try { console.error('Screen error:', err); } catch (e) {} }
  render() {
    if (this.state.err) return (
      <div className="page rise">
        <div className="card card-pad" style={{ textAlign: 'center', padding: 44 }}>
          <Icon name="alert" size={28} style={{ color: 'var(--warn)' }} />
          <div style={{ fontWeight: 750, fontSize: 15, marginTop: 10 }}>Something went wrong on this screen</div>
          <div className="faint" style={{ fontSize: 12.5, marginTop: 4 }}>The rest of the app is fine — go back and try again, or reload.</div>
          <div className="row" style={{ gap: 8, justifyContent: 'center', marginTop: 16 }}>
            <Btn variant="ghost" onClick={() => this.setState({ err: null })}>Try again</Btn>
            <Btn variant="primary" onClick={() => window.location.reload()}>Reload</Btn>
          </div>
        </div>
      </div>
    );
    return this.props.children;
  }
}

function ModuleHost({ active, ctx }) {
  const map = {
    dashboard: window.Dashboard,
    jobs: window.JobsModule,
    iso: window.ISOModule,
    cylinders: window.CylindersModule,
    certs: window.CertsModule,
    assets: window.AssetsModule,
    customers: window.CustomersModule,
    crm: window.CRMModule,
    qms: window.QMSModule,
    schedule: window.ScheduleModule,
    inventory: window.InventoryModule,
    finance: window.FinanceModule,
    documents: window.DocsModule,
    reports: window.ReportsModule,
    competency: window.CompetencyModule,
    users: window.UsersModule,
    admin: window.AdminModule,
  };
  const Comp = map[active];
  if (Comp) return <Comp key={active} {...ctx} />;
  return (
    <div className="page rise">
      <ModulePlaceholder icon="grid" title="Module" desc="This module is part of the AI-COS scope." points={[]} />
    </div>
  );
}

function App() {
  const [screen, setScreen] = useState('boot'); // boot | login | admin
  const [active, setActive] = useState('dashboard');
  const [notifOpen, setNotifOpen] = useState(false);
  const [jobId, setJobId] = useState(null);
  const [detail, setDetail] = useState(null);
  const [search, setSearch] = useState(null);
  const [, setTick] = useState(0);

  window.EDITION = 'essential'; // AI-COS Essential is the product — no editions

  useEffect(() => {
    window.__bump = () => setTick((t) => t + 1);
    window._openDetail = (type, data) => { setSearch(null); setDetail({ type, data }); document.querySelector('.content')?.scrollTo(0, 0); };
    window._search = (q) => { setDetail(null); setSearch(q); document.querySelector('.content')?.scrollTo(0, 0); };
    window._openJob = (id) => { setSearch(null); setDetail(null); setActive('jobs'); setJobId(id); };
    return () => { window.__bump = null; };
  }, []);

  // Resume a saved session: hydrate from the server, else fall back to login.
  useEffect(() => {
    if (window.CAL && CAL.token) {
      bootCAL()
        .then((d) => calSeedIfEmpty(d))
        .then(() => calLoadStaff())
        .then(() => setScreen('admin'))
        .catch(() => { calSignOut(); setScreen('login'); });
    } else setScreen('login');
  }, []);

  const navTo = (id) => { setActive(id); setJobId(null); setDetail(null); setSearch(null); document.querySelector('.content')?.scrollTo(0, 0); };
  window._navTo = navTo;
  const openJob = (id) => { setActive('jobs'); setJobId(id); setDetail(null); };
  const signOut = () => { calSignOut(); setScreen('login'); setActive('dashboard'); };

  const onEnter = () => {
    setScreen('boot');
    bootCAL()
      .then((d) => calSeedIfEmpty(d))
      .then(() => calLoadStaff())
      .then(() => setScreen('admin'))
      .catch(() => { calSignOut(); setScreen('login'); window.toast && window.toast('Could not load laboratory data — sign in again', 'bad'); });
  };

  if (screen === 'boot') return (
    <div style={{ height: '100vh', display: 'grid', placeItems: 'center', background: 'var(--bg)' }}>
      <div style={{ textAlign: 'center' }}>
        <BrandMark size={52} />
        <div style={{ marginTop: 14, fontWeight: 700, fontSize: 15 }}>AI-COS Essential</div>
        <div className="faint" style={{ fontSize: 12.5, marginTop: 4 }}>Loading laboratory data…</div>
      </div>
    </div>
  );
  if (screen === 'login') return <Login onEnter={onEnter} />;

  const navLabel = (window.DB.nav.flatMap((g) => g.items).find((i) => i.id === active) || {}).label
    || (active === 'users' ? 'Users & Settings' : active === 'customers' ? 'Customers' : 'Dashboard');
  const ctx = { onNav: navTo, openJob, jobId, setJobId, initialTab: active === 'customers' ? 'customers' : undefined };

  return (
    <div className="app">
      <Sidebar active={active} onNav={navTo} onLogout={signOut} />
      <div className="main">
        <Topbar title={navLabel} crumb={navLabel} onOpenNotif={() => setNotifOpen(true)} onNav={navTo} onLogout={signOut} />
        <div className="content">
          <ErrorBoundary key={active + ':' + (detail ? detail.type + ':' + ((detail.data && detail.data.id) || '') : '') + ':' + (search != null ? 's' : '')}>
            {search != null ? <SearchResults query={search} onBack={() => setSearch(null)} />
              : detail ? <RecordPage type={detail.type} data={detail.data} onBack={() => setDetail(null)} onNav={navTo} />
              : <ModuleHost active={active} ctx={ctx} />}
          </ErrorBoundary>
        </div>
      </div>
      <NotifPanel open={notifOpen} onClose={() => setNotifOpen(false)} onNav={navTo} />
      <ChangePasswordHost />
      <ToastHost />
      <FormHost />
    </div>
  );
}

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