/* The workspace: who is signed in, which organization, which module, which
   view. URL carries org and module (?org=&m=) so a link opens the same
   place; ?demo=1 opens the demo organization; ?delegate=<token> opens the
   delegate page for a data request. */

function AppPage() {
  const params = new URLSearchParams(window.location.search);
  // Pinned at first render: the URL sync below rewrites the query string, and
  // a signed-in user's re-render must not lose the page they opened.
  const [delegate] = React.useState(() => params.get('delegate') || '');
  const [request] = React.useState(() => params.get('request') || '');
  const [analysisId] = React.useState(() => params.get('analysis') || '');
  const [token, setToken] = React.useState(readUserToken());
  const [me, setMe] = React.useState(null);
  const [orgId, setOrgId] = React.useState(params.get('org') || (params.get('demo') ? '__demo' : ''));
  const [orgData, setOrgData] = React.useState(null);
  const [moduleId, setModuleId] = React.useState(params.get('m') || 'stack');
  const [view, setView] = React.useState(() => { try { return localStorage.getItem('lojo.view') || 'exec'; } catch (e) { return 'exec'; } });
  const [error, setError] = React.useState('');
  const [newOrg, setNewOrg] = React.useState(false);
  const [off, setOff] = React.useState(false);

  const signOut = React.useCallback(() => { writeUserToken(''); setToken(''); setMe(null); setOrgData(null); }, []);

  // Who am I (also accepts the team/agency tokens stored by the other pages).
  React.useEffect(() => {
    const t = token || (function () { try { return sessionStorage.getItem('lojo.admin.token') || sessionStorage.getItem('lojo.agency.token') || ''; } catch (e) { return ''; } })();
    if (!t) { setMe(null); return; }
    lojo(t, { module: 'auth', action: 'me' }).then((d) => {
      if (d.ok) { setMe(d); if (t !== token) setToken(t); if (!orgId && d.orgs && d.orgs.length) setOrgId(d.orgs[0].id); if (!orgId && !(d.orgs || []).length && d.actor.actor_type === 'user') setNewOrg(true); }
      else if (d.error === 'feature-off') setOff(true);
      else if (d.status === 401 || d.status === 404) { if (t === token) signOut(); }
    });
  }, [token]);

  // Resolve the demo id and load the organization.
  const realOrgId = orgId === '__demo' ? (me && me.demo_org) || 'demo-meridian' : orgId;
  const load = React.useCallback(async () => {
    if (!realOrgId || realOrgId === '__new') { setOrgData(null); return; }
    // The demo is built on first request; wait for it before reading it.
    if (orgId === '__demo') await lojo('', { module: 'demo', action: 'info' });
    const d = await lojo(token, { module: 'org', action: 'get', org: realOrgId });
    if (d.ok) { setOrgData(d); setError(''); }
    else if (d.error === 'feature-off') setOff(true);
    else setError((d.message || 'Could not open that organization.') + (d.detail ? '\n\n' + String(d.detail).slice(-1200) : ''));
  }, [realOrgId, token]);
  React.useEffect(() => { load(); }, [load]);

  React.useEffect(() => {
    if (delegate || request || analysisId) return;
    const q = new URLSearchParams();
    if (orgId === '__demo') q.set('demo', '1'); else if (orgId && orgId !== '__new') q.set('org', orgId);
    if (moduleId && moduleId !== 'stack') q.set('m', moduleId);
    try { window.history.replaceState({}, '', window.location.pathname + (q.toString() ? '?' + q.toString() : '')); } catch (e) { /* fine */ }
  }, [orgId, moduleId]);
  const changeView = (v) => { setView(v); try { localStorage.setItem('lojo.view', v); } catch (e) { /* fine */ } };

  if (delegate) return <DelegatePage token={delegate} />;
  if (request) return <InquiryPage initialModule={request} />;
  if (analysisId) return <AnalysisPage id={analysisId} />;
  if (off) return <div className="wrap" style={{ padding: '90px var(--s6)', color: 'var(--fg-muted)', maxWidth: 640, lineHeight: 1.6 }}>
    <Wordmark size={16} /><h1 className="display" style={{ fontSize: 28, margin: '18px 0 8px' }}>The workspace is not switched on here yet.</h1>
    Set <span className="mono">LOJO_FEATURE_PLATFORM=1</span> on this deployment. Nothing about the AI visibility reports changes either way.</div>;
  if (!token && orgId !== '__demo') return <SignIn demoOrg="demo-meridian" onIn={(d) => { setToken(d.token); setMe({ ...d, actor: { actor_type: 'user', ...d.user, user_id: d.user.id } }); if (d.org) setOrgId(d.org.id); else if (d.orgs && d.orgs.length) setOrgId(d.orgs[0].id); else setNewOrg(true); }} />;

  const orgs = (me && me.orgs) || [];
  const org = orgData && orgData.org;
  const modules = (orgData && orgData.modules) || (me && me.modules) || [];
  const readOnly = !!(orgData && orgData.read_only);
  const role = (orgData && orgData.role) || '';
  const ctx = { token, org: realOrgId, role, flags: (orgData && orgData.flags) || [], readOnly, view, reload: load, me, orgData, setModule: setModuleId };
  const current = modules.find((m) => m.id === moduleId);

  const onOrg = (id) => { if (id === '__new') { setNewOrg(true); return; } setNewOrg(false); setOrgId(id); setModuleId('stack'); };

  return (
    <div className="app-shell">
      <AppTop me={me} org={org} orgs={orgs} modules={modules} moduleId={moduleId} onModule={setModuleId} onOrg={onOrg} view={view} onView={changeView} onSignOut={signOut} readOnly={readOnly} />
      <main className="app-main">
        {newOrg || orgId === '__new' ? <NewOrg token={token} onCreated={(d) => { setMe((m) => ({ ...(m || {}), orgs: d.orgs })); setNewOrg(false); setOrgId(d.org.id); }} onCancel={() => setNewOrg(false)} canCancel={orgs.length > 0} /> :
         error ? <div className="empty" style={{ whiteSpace: 'pre-wrap', fontFamily: error.includes('Traceback') ? 'var(--font-mono)' : undefined, fontSize: error.includes('Traceback') ? 12 : undefined, textAlign: 'left' }}>{error}</div> :
         !org ? <div style={{ color: 'var(--fg-subtle)' }}>Loading…</div> :
         moduleId === 'org' ? <OrgModule ctx={ctx} /> :
         current && current.status === 'preview' ? <ModulePreview m={current} /> :
         moduleId === 'execute' ? <ExecuteModule ctx={ctx} /> :
         <StackModule ctx={ctx} />}
      </main>
    </div>);
}

function NewOrg({ token, onCreated, onCancel, canCancel }) {
  const [f, setF] = React.useState({ name: '', industry: '', size_band: '', description: '' });
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState('');
  const submit = async (e) => {
    e.preventDefault(); setBusy(true); setError('');
    const d = await lojo(token, { module: 'org', action: 'create', name: f.name, profile: { industry: f.industry, size_band: f.size_band, description: f.description } });
    setBusy(false);
    if (!d.ok) { setError(d.message || 'Could not create it.'); return; }
    onCreated(d);
  };
  return (
    <div style={{ maxWidth: 560 }}>
      <div className="overline" style={{ marginBottom: 8 }}>New organization</div>
      <h1 className="display" style={{ fontSize: 30, margin: '0 0 8px' }}>Who is this workspace for?</h1>
      <p style={{ color: 'var(--fg-muted)', fontSize: 14.5, lineHeight: 1.6, margin: '0 0 20px' }}>You become its owner. Everything inside is isolated to this organization and its members.</p>
      <form onSubmit={submit}>
        <Field label="Organization name"><Input value={f.name} onChange={(e) => setF({ ...f, name: e.target.value })} required /></Field>
        <div className="app-grid cols-2">
          <Field label="Industry"><Input value={f.industry} onChange={(e) => setF({ ...f, industry: e.target.value })} placeholder="e.g. Specialty retail" /></Field>
          <Field label="Headcount band"><Select value={f.size_band} onChange={(v) => setF({ ...f, size_band: v })} options={[['', 'Choose'], '1–25', '25–100', '100–250', '250–1,000', '1,000+']} /></Field>
        </div>
        <Field label="What the business does (one or two sentences)"><textarea className="app-input" rows={3} value={f.description} onChange={(e) => setF({ ...f, description: e.target.value })} /></Field>
        {error && <div className="flash warn">{error}</div>}
        <div style={{ display: 'flex', gap: 10 }}>
          <button className="btn btn-primary" disabled={busy}>{busy ? 'Creating…' : 'Create organization'}</button>
          {canCancel && <button type="button" className="app-btn" onClick={onCancel}>Cancel</button>}
        </div>
      </form>
    </div>);
}

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