/* ELEV8 ATS - app root: routing, toasts, Ask AI / ⌘K wiring, Tweaks. */

const DSm = window.Stand8DesignSystem_b5c975;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "density": "comfortable",
  "appearance": "light",
  "accent": "#5215FC",
  "font": "Geist",
  "selectionTint": "Daybreak",
  "sidebarLabels": true
}/*EDITMODE-END*/;

const ACCENTS = {
  '#4F46E5': { hover: '#4338CA', tint: '#EEF0FE', soft: '#A5B4FC', softTint: '#DDE3FE', softWash: '#EEF2FF', softText: '#4644B8' },
  '#5215FC': { hover: '#4310D4', tint: '#EFEBFF', soft: '#ABB1FF', softTint: '#DBDDFF', softWash: '#EFF0FF', softText: '#4E14EE' },
  '#2563EB': { hover: '#1D4ED8', tint: '#EAF1FE', soft: '#93C5FD', softTint: '#D8E6FE', softWash: '#EFF6FF', softText: '#1D5BC9' },
  '#0D9488': { hover: '#0F766E', tint: '#E6F6F4', soft: '#5EEAD4', softTint: '#C6F1EA', softWash: '#EFFBF9', softText: '#0F766E' },
  '#E11D48': { hover: '#BE123C', tint: '#FFE4E6', soft: '#FDA4AF', softTint: '#FECDD3', softWash: '#FFF1F2', softText: '#9F1239' },
  '#D97706': { hover: '#B45309', tint: '#FEF3C7', soft: '#FCD34D', softTint: '#FDE68A', softWash: '#FFFBEB', softText: '#92400E' },
  '#059669': { hover: '#047857', tint: '#D1FAE5', soft: '#6EE7B7', softTint: '#A7F3D0', softWash: '#ECFDF5', softText: '#065F46' },
};

// Named accent themes shown in the in-app Appearance control (key = the accent hex).
const THEMES = [
  { key: '#5215FC', name: 'Cobalt' },
  { key: '#4F46E5', name: 'Indigo' },
  { key: '#2563EB', name: 'Blue' },
  { key: '#0D9488', name: 'Teal' },
  { key: '#E11D48', name: 'Rose' },
  { key: '#D97706', name: 'Amber' },
  { key: '#059669', name: 'Emerald' },
];

function pageLabel(page) {
  if (page === 'home') return 'Home';
  for (const g of NAV_GROUPS) {
    const hit = g.items.find((i) => i.id === page);
    if (hit) return hit.label;
  }
  return 'This module';
}

function jobSectionForRoute(id, requested) {
  const resolved = window.jobById ? window.jobById(id) : null;
  const status = resolved ? resolved.status : 'open';
  if (requested) return window.E8Workspace.jobPolicy.resolveSection(status, requested, null);
  const persona = window.e8ActivePersona ? window.e8ActivePersona() : window.E8DATA.user;
  return window.E8Workspace.jobDefaultSection(persona.name, status);
}

function App() {
  const route = useRoute();
  const [t, setTweak] = useTweaks(React.useMemo(() => {
    const d = { ...TWEAK_DEFAULTS };
    try {
      const a = window.localStorage.getItem('e8-appearance'); if (a) d.appearance = a;
      const c = window.localStorage.getItem('e8-accent'); if (c) d.accent = c;
    } catch (e) {}
    return d;
  }, []));
  const [toasts, setToasts] = React.useState([]);
  const [askOpen, setAskOpen] = React.useState(false);
  const [cmdOpen, setCmdOpen] = React.useState(false);
  const [navOpen, setNavOpen] = React.useState(false);
  const [workspaceOpen, setWorkspaceOpen] = React.useState(false);
  const [workspaceTab, setWorkspaceTab] = React.useState('focus');
  const [createOpen, setCreateOpen] = React.useState(false);
  const [mobileAction, setMobileAction] = React.useState(null);
  const mobileActionCtx = React.useMemo(() => ({ setAction: setMobileAction }), []);
  const [capture, setCapture] = React.useState(null);
  const captureCtx = React.useMemo(() => ({ open: setCapture }), []);

  /* R98: global creation host. Any surface (topbar buttons, CMDK, mobile CreateSheet) opens the
     shared creation dialogs via window.e8OpenCreate('submission' | 'engagement' | 'candidate'). */
  const [creating, setCreating] = React.useState(null);
  React.useEffect(() => {
    window.e8OpenCreate = (kind, opts) => setCreating({ kind, opts: opts || {} });
    return () => { delete window.e8OpenCreate; };
  }, []);
  const CreateDlg = creating && ({
    submission: window.NewSubmissionDialog,
    engagement: window.NewEngagementDialog,
    candidate: window.NewCandidateDialog,
  })[creating.kind];

  /* R99: the structured requisition form host. Any surface opens it via
     window.e8OpenReqForm({ jobId?, prefill? }) - blank for a new req, jobId+prefill to edit. */
  const [reqForm, setReqForm] = React.useState(null);
  React.useEffect(() => {
    window.e8OpenReqForm = (opts) => setReqForm(opts || {});
    return () => { delete window.e8OpenReqForm; };
  }, []);

  /* R109 T3: the human-reviewed merge host. The "possible duplicates" queue + the record flag open it via
     window.e8OpenMerge(survivorId, mergedId). This is the ONLY merge path - nothing auto-merges. */
  const [merge, setMerge] = React.useState(null);
  React.useEffect(() => {
    window.e8OpenMerge = (aId, bId) => setMerge({ aId, bId });
    return () => { delete window.e8OpenMerge; };
  }, []);
  React.useEffect(() => { if (merge && !window.MergeReviewDialog) setMerge(null); }, [merge]);
  /* Unknown kind (or a dialog script that failed to load) would otherwise leave `creating`
     set with nothing rendered - clear it so the host self-heals. */
  React.useEffect(() => { if (creating && !CreateDlg) setCreating(null); }, [creating, CreateDlg]);
  /* Self-heal if the requisition-form script failed to load. */
  React.useEffect(() => { if (reqForm && !window.RequisitionForm) setReqForm(null); }, [reqForm]);

  /* Close the mobile sheets whenever the route changes. */
  React.useEffect(() => { setNavOpen(false); setCreateOpen(false); }, [route.page, route.id, route.sub]);
  React.useEffect(() => {
    const open = (event) => {
      setWorkspaceTab((event && event.detail && event.detail.tab) || 'focus');
      setWorkspaceOpen(true);
    };
    window.addEventListener('e8-open-workspace', open);
    return () => window.removeEventListener('e8-open-workspace', open);
  }, []);
  React.useEffect(() => {
    if (route.page !== 'home' && window.E8HomePlanner) window.E8HomePlanner.cancel();
  }, [route.page]);

  const showToast = React.useCallback((message, action, onAction) => {
    const id = Date.now() + Math.random();
    setToasts((ts) => [...ts.slice(-2), { id, message, action, onAction }]);
    setTimeout(() => setToasts((ts) => ts.filter((x) => x.id !== id)), 5200);
  }, []);

  React.useEffect(() => {
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') { e.preventDefault(); setCmdOpen((v) => !v); }
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'j') { e.preventDefault(); setAskOpen((v) => !v); }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  /* Badging API: surface the unread conversation count on the installed app icon.
     R78: recomputes live off the event bus (reads the persisted comms overlay). */
  React.useEffect(() => {
    const compute = () => {
      try {
        const unread = window.E8Comms
          ? window.E8Comms.unreadCount()
          : (((window.E8DATA || {}).conversations) || []).filter((c) => c.unread).length;
        if (navigator.setAppBadge) { if (unread) navigator.setAppBadge(unread); else if (navigator.clearAppBadge) navigator.clearAppBadge(); }
      } catch (e) {}
    };
    compute();
    return window.E8Events ? window.E8Events.subscribe(['comms:changed', 'queue:changed'], compute) : undefined;
  }, []);

  /* R80: notification actions execute on the spine (E8Notify.exec) and report back here. */
  React.useEffect(() => (
    window.E8Events
      ? window.E8Events.subscribe(['notify:executed'], (e) => {
          if (e.remote) return; // the acting tab owns the toast
          const p = e.payload || {};
          showToast(p.message || 'Done', p.route ? 'Open' : undefined, p.route ? () => navigate(p.route) : undefined);
        })
      : undefined
  ), [showToast]);

  /* Web Share Target: if the app was launched from the OS share sheet, turn the shared content into a candidate draft. */
  React.useEffect(() => {
    try {
      const p = new URLSearchParams(window.location.search);
      const shared = p.get('share_url') || p.get('share_text') || p.get('share_title');
      if (shared) showToast('Shared to ELEV8: "' + String(shared).slice(0, 48) + '" - drafting a candidate', 'Open Candidates', () => navigate('candidates'));
    } catch (e) {}
  }, [showToast]);

  /* Tweaks: accent + selection tint + sidebar labels via CSS overrides */
  React.useEffect(() => {
    let st = document.getElementById('e8-tweak-css');
    if (!st) { st = document.createElement('style'); st.id = 'e8-tweak-css'; document.head.appendChild(st); }
    const a = ACCENTS[t.accent] || ACCENTS['#5215FC'];
    const fontStack = `'${t.font || 'Geist'}', 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif`;
    st.textContent = [
      `.elev8 { --font-body: ${fontStack}; --font-display: ${fontStack}; }`,
      /* --ui-ring / --ui-accent-tint-2 are NOT injected here: their product.css (light) and
         app.css dark-block definitions are color-mix on var(--ui-accent), so they already
         track every accent switch via the var indirection. */
      `:root { --ui-accent: ${t.accent}; --ui-accent-hover: ${a.hover}; --ui-accent-tint: ${a.tint};`,
      `  --ui-daybreak: ${a.soft}; --ui-daybreak-tint: ${a.softTint}; --ui-daybreak-wash: ${a.softWash}; --ui-daybreak-text: ${a.softText};`,
      `  --ui-focus-ring: 0 0 0 2px #FFFFFF, 0 0 0 4px ${t.accent}; }`,
      t.selectionTint === 'Neutral' ? ':root { --ui-daybreak-wash: #F2F2F4; }' : '',
      t.sidebarLabels ? '' : '.e8-side-group-label { display: none; } .e8-side-group { margin-top: 6px; }',
    ].join('\n');
    try { window.localStorage.setItem('e8-accent', t.accent); } catch (e) {}
  }, [t.accent, t.font, t.selectionTint, t.sidebarLabels]);

  /* Appearance: light / dark / system. Sets data-theme on <html>, persists, and follows the OS when 'system'. */
  React.useEffect(() => {
    const root = document.documentElement;
    const apply = () => {
      const dark = t.appearance === 'system'
        ? (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches)
        : t.appearance === 'dark';
      root.setAttribute('data-theme', dark ? 'dark' : 'light');
      const meta = document.querySelector('meta[name="theme-color"]');
      if (meta) meta.setAttribute('content', dark ? '#0F0F14' : '#F7F7F9');
    };
    apply();
    try { window.localStorage.setItem('e8-appearance', t.appearance); } catch (e) {}
    if (t.appearance === 'system' && window.matchMedia) {
      const mq = window.matchMedia('(prefers-color-scheme: dark)');
      const onCh = () => apply();
      mq.addEventListener('change', onCh);
      return () => mq.removeEventListener('change', onCh);
    }
  }, [t.appearance]);

  /* Global density: data-density on <html> drives :root[data-density="compact"] token overrides
     (--ui-row-h / --ui-cell-px in product.css). The DataTable density prop keeps working independently. */
  React.useEffect(() => {
    document.documentElement.setAttribute('data-density', t.density || 'comfortable');
  }, [t.density]);

  const themeCtl = { appearance: t.appearance, accent: t.accent, themes: THEMES, setAppearance: (v) => setTweak('appearance', v), setAccent: (v) => setTweak('accent', v) };
  const ctx = { showToast, density: t.density, theme: themeCtl };

  /* R107: the candidate self-service portal (#/portal/:candId) is a chrome-free full-screen surface -
     it renders OUTSIDE the app shell, so no sidebar / topbar / mobile tab bar / cmdk / Ask AI ever
     appears. Every other route falls through to the normal chrome below, unchanged. Placed after all
     hooks + ctx so the appearance/accent/density effects still run for the portal (dark mode works). */
  if (isPortalRoute(route)) {
    return (
      <E8Ctx.Provider value={ctx}>
        <div className="e8-cportal-root">
          <CandidatePortal id={route.id} sub={route.sub} />
        </div>
        <DSm.ToastStack>
          {toasts.map((x) => (
            <DSm.Toast
              key={x.id}
              icon="check_circle"
              message={x.message}
              action={x.action}
              onAction={() => { x.onAction && x.onAction(); setToasts((ts) => ts.filter((y) => y.id !== x.id)); }}
            />
          ))}
        </DSm.ToastStack>
      </E8Ctx.Provider>
    );
  }

  let screen;
  const p = route.page;
  if (p === 'home') screen = <HomeScreen />;
  else if (p === 'today') screen = <TodayScreen />;
  else if (p === 'tasks') screen = <TasksScreen />;
  else if (p === 'dashboard') {
    screen = (
      <React.Fragment>
        <Topbar crumbs={[{ label: 'Dashboard' }]} />
        <div className="e8-content"><DashboardScreen /></div>
      </React.Fragment>
    );
  } else if (p === 'applicants') screen = <ApplicantsScreen segment={route.id || 'new'} />;
  else if (p === 'candidates') screen = <CandidatesScreen />;
  else if (p === 'duplicates') screen = <DuplicatesScreen />;
  else if (p === 'candidate') screen = <CandidateDetailScreen key={'cand-' + route.id} id={route.id} q={route.query && route.query.q} />;
  else if (p === 'jobs') screen = <JobsScreen tab={route.id || 'open'} />;
  else if (p === 'requisitions') screen = <JobsScreen tab="intake" />;
  else if (p === 'job') screen = <JobDetailScreen key={'job-' + route.id} id={route.id} sub={jobSectionForRoute(route.id, route.sub)} />;
  else if (p === 'submissions') screen = <SubmissionsScreen tab={route.id || 'active'} />;
  else if (p === 'voice' && route.id) screen = <CallResultScreen key={'call-' + route.id} id={route.id} />;
  else if (p === 'voice') screen = <VoiceOpsScreen />;
  else if (p === 'engagements') screen = <EngagementsScreen view="overview" />;
  else if (p === 'engagement') screen = <ManagedEngagementDetail id={route.id} />;
  else if (p === 'renewals') screen = <EngagementsScreen view="renewals" />;
  else if (p === 'casestudies') screen = <EngagementsScreen view="casestudies" />;
  else if (p === 'clients') screen = <ClientsScreen />;
  else if (p === 'client') screen = <ClientDetailScreen id={route.id} sub={route.sub} />;
  else if (p === 'contacts') screen = <ContactsScreen />;
  else if (p === 'contact') screen = <ContactDetailScreen id={route.id} sub={route.sub} />;
  else if (p === 'sequences' && route.id === 'new') screen = <SequenceBuilder key="seq-new" />;
  else if (p === 'sequences' && route.id && route.sub === 'edit') screen = <SequenceBuilder key={'seq-' + route.id} id={route.id} />;
  else if (p === 'sequences') screen = <SequencesScreen />;
  else if (p === 'sequence') screen = <SequenceDetail key={'seqd-' + route.id} id={route.id} sub={route.sub} />;
  else if (p === 'inbox') screen = <MessagesScreen convoId={route.id} />;
  else if (p === 'approvals') screen = <ApprovalsScreen />;
  else if (p === 'notes') screen = <NotesScreen />;
  else if (p === 'agents') screen = <AgentsScreen />;
  else if (p === 'matching') screen = <AgentsScreen focus="matching" />;
  else if (p === 'workfloweditor') screen = <WorkflowEditorScreen />;
  else if (p === 'reports') screen = <ReportsScreen />;
  else if (p === 'commissions') screen = <CommissionsScreen />;
  else if (p === 'time') screen = <TimeHub />;
  else if (p === 'consultants') screen = <ConsultantsScreen key={'cons-' + (route.id || 'billing')} segment={route.id} />;
  else if (p === 'consultant') screen = <ConsultantDetailScreen id={route.id} />;
  else if (p === 'care') screen = <EngagementsScreen view="care" />;
  else if (p === 'csms') screen = <CsmsScreen />;
  else if (p === 'csm') screen = <CsmDetailScreen key={'csm-' + route.id} id={route.id} />;
  else if (p === 'rates') screen = <RateLibraryScreen />;
  else if (p === 'audit') screen = <AuditLogScreen />;
  else if (p === 'syncqueue') screen = <SyncQueueScreen />;
  else if (p === 'system') screen = <SystemScreen />;
  else if (p === 'fields') screen = <FieldsScreen />;
  else if (p === 'stages') screen = <StagesScreen />;
  else if (p === 'workflows') screen = <WorkflowsScreen />;
  else if (p === 'forms') screen = <FormsScreen />;
  else if (p === 'enrichment') screen = <EnrichHubScreen />;
  else if (p === 'templates' && route.id) screen = <TemplateEditor key={route.id} id={route.id} />;
  else if (p === 'templates') screen = <TemplatesHub />;
  else {
    screen = (
      <React.Fragment>
        <Topbar crumbs={[{ label: pageLabel(p) }]} />
        <div className="e8-content"><ComingSoon label={pageLabel(p)} /></div>
      </React.Fragment>
    );
  }

  return (
    <E8Ctx.Provider value={ctx}>
     <MobileActionCtx.Provider value={mobileActionCtx}>
      <CaptureCtx.Provider value={captureCtx}>
      <div className={'e8-app' + (route.page === 'home' ? ' e8-home-app' : '')}>
        <MobileBar action={mobileAction} onMenu={() => setNavOpen(true)} onCmdK={() => setCmdOpen(true)} onAskAI={() => setAskOpen(true)} />
        <Sidebar route={route} theme={themeCtl} onAskAI={() => setAskOpen(true)} onCmdK={() => setCmdOpen(true)} />
        <InboxShortcut route={route} />
        <main className="e8-main">{screen}</main>
        <AskAIPanel open={askOpen} route={route} onClose={() => setAskOpen(false)} />
        <MobileTabBar route={route} menuOpen={navOpen} onCreate={() => setCreateOpen(true)} onMore={() => setNavOpen(true)} />
        <MobileMenu open={navOpen} onClose={() => setNavOpen(false)} route={route} theme={themeCtl} onAskAI={() => setAskOpen(true)} onCmdK={() => setCmdOpen(true)} />
        <CreateSheet open={createOpen} onClose={() => setCreateOpen(false)} />
        <CaptureOverlay cfg={capture} onClose={() => setCapture(null)} />
      </div>

      {cmdOpen ? <CommandPalette onClose={() => setCmdOpen(false)} /> : null}
      <WorkspaceCustomizer open={workspaceOpen} initialTab={workspaceTab} onClose={() => setWorkspaceOpen(false)} />

      {CreateDlg ? <CreateDlg onClose={() => setCreating(null)} {...creating.opts} /> : null}

      {reqForm && window.RequisitionForm ? <window.RequisitionForm jobId={reqForm.jobId} prefill={reqForm.prefill} onClose={() => setReqForm(null)} /> : null}

      {merge && window.MergeReviewDialog ? <window.MergeReviewDialog aId={merge.aId} bId={merge.bId} onClose={() => setMerge(null)} /> : null}

      <DSm.ToastStack>
        {toasts.map((x) => (
          <DSm.Toast
            key={x.id}
            icon="check_circle"
            message={x.message}
            action={x.action}
            onAction={() => { x.onAction && x.onAction(); setToasts((ts) => ts.filter((y) => y.id !== x.id)); }}
          />
        ))}
      </DSm.ToastStack>

      <TweaksPanel>
        <TweakSection label="Style" />
        <TweakRadio label="Appearance" value={t.appearance} options={[{ value: 'light', label: 'Light' }, { value: 'dark', label: 'Dark' }, { value: 'system', label: 'Auto' }]} onChange={(v) => setTweak('appearance', v)} />
        <TweakColor label="Accent" value={t.accent} options={['#5215FC', '#4F46E5', '#2563EB', '#0D9488', '#E11D48', '#D97706', '#059669']} onChange={(v) => setTweak('accent', v)} />
        <TweakRadio label="Typeface" value={t.font} options={['Geist', 'Inter', 'Instrument Sans']} onChange={(v) => setTweak('font', v)} />
        <TweakSection label="Table" />
        <TweakRadio label="Row density" value={t.density} options={['comfortable', 'compact']} onChange={(v) => setTweak('density', v)} />
        <TweakRadio label="Selected row tint" value={t.selectionTint} options={['Daybreak', 'Neutral']} onChange={(v) => setTweak('selectionTint', v)} />
        <TweakSection label="Navigation" />
        <TweakToggle label="Sidebar group labels" value={t.sidebarLabels} onChange={(v) => setTweak('sidebarLabels', v)} />
      </TweaksPanel>
      </CaptureCtx.Provider>
     </MobileActionCtx.Provider>
    </E8Ctx.Provider>
  );
}

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