// app.jsx — real client-side router for Survey TOM.
// Replaces the design-canvas wrapper from `Survey TOM.html` with a live app
// that talks to the Express + Better Auth backend.
//
// Routes:
//   /            → MarketingLanding
//   /login       → AuthScreen mode=login
//   /register    → AuthScreen mode=register
//   /app/*       → authenticated AdminApp shell (dashboard, growth, insight, …)
//   /survey/:slug → public mobile responder flow (read survey from API)
//   /preview     → links to the static design-canvas HTML for reference

const { useState: useStateApp, useEffect: useEffectApp } = React;
const api = window.api; // shared client from /api.js

// ─── Tiny route helper ────────────────────────────────────────────────
function useRoute() {
  const [path, setPath] = useStateApp(window.location.pathname);
  useEffectApp(() => {
    const onPop = () => setPath(window.location.pathname);
    window.addEventListener('popstate', onPop);
    return () => window.removeEventListener('popstate', onPop);
  }, []);
  const navigate = (to) => {
    if (to !== window.location.pathname) {
      window.history.pushState({}, '', to);
      setPath(to);
    }
  };
  return [path, navigate];
}

// ─── Screens ──────────────────────────────────────────────────────────
function MarketingScreen({ navigate }) {
  return (
    <MarketingLanding
      onGoLogin={() => navigate('/login')}
      onGoRegister={() => navigate('/register')}
    />
  );
}

function AuthRoute({ mode, navigate, onAuthed }) {
  const [error, setError] = useStateApp(null);
  const [busy, setBusy] = useStateApp(false);

  async function handleSubmit(values) {
    setError(null);
    setBusy(true);
    try {
      if (values.mode === 'login') {
        await api.signIn({ email: values.email, password: values.password });
      } else {
        await api.signUp({
          email: values.email,
          password: values.password,
          name: values.name || values.email.split('@')[0],
          businessName: values.businessName || undefined,
          industryCategory: values.industryCategory || undefined,
        });
      }
      onAuthed();
    } catch (err) {
      setError(err.message || 'Tidak bisa memproses permintaan.');
    } finally {
      setBusy(false);
    }
  }

  return (
    <AuthScreen
      mode={mode}
      onSwitch={(next) => navigate(next === 'login' ? '/login' : '/register')}
      onSubmit={handleSubmit}
      error={error}
      busy={busy}
    />
  );
}

// Authed admin shell — same as AdminApp from app-shell.jsx but with sign-out
// and a strip showing the user's real campaigns from the backend.
function AdminShell({ user, workspaces, activeWorkspace, onWorkspaceSwitch, onUserRefresh, onSignOut }) {
  const [view, setView] = useStateApp('dash');
  const [campaigns, setCampaigns] = useStateApp([]);
  // Active campaign id when view === 'edit-campaign'. Null otherwise.
  const [editingCampaignId, setEditingCampaignId] = useStateApp(null);

  const openCampaignEditor = (id) => { setEditingCampaignId(id); setView('edit-campaign'); };

  const refreshCampaigns = React.useCallback(() => {
    api
      .listCampaigns()
      .then((r) => setCampaigns(r.campaigns || []))
      .catch(() => setCampaigns([]));
  }, []);

  // Refetch campaigns whenever the active workspace changes — campaigns are
  // workspace-scoped on the backend now.
  useEffectApp(() => {
    refreshCampaigns();
  }, [refreshCampaigns, activeWorkspace?.id]);

  const handlePublished = (campaign, action) => {
    refreshCampaigns();
    if (action === 'goto-dashboard') setView('dash');
  };

  return (
    <div style={{ display: 'flex', height: '100vh', overflow: 'hidden', background: 'var(--bg)' }}>
      <Sidebar
        active={view}
        onNav={setView}
        userOverride={user}
        workspaces={workspaces}
        activeWorkspace={activeWorkspace}
        onWorkspaceSwitch={onWorkspaceSwitch}
        onSignOut={onSignOut}
      />
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
        <PulseBar campaigns={campaigns} activeWorkspace={activeWorkspace} onNew={() => setView('builder')} />
        <div style={{ flex: 1, overflow: 'auto' }} className="scroll">
          {view === 'dash' && <AdminDashboard key={activeWorkspace?.id} onNew={() => setView('builder')} onEditCampaign={openCampaignEditor} />}
          {view === 'edit-campaign' && editingCampaignId && (
            <CampaignEditor
              key={editingCampaignId}
              campaignId={editingCampaignId}
              onBack={() => { setView('dash'); setEditingCampaignId(null); refreshCampaigns(); }}
              onSaved={refreshCampaigns}
            />
          )}
          {view === 'growth' && <GrowthTracker />}
          {view === 'insight' && <AIInsightView />}
          {view === 'launch' && <LaunchSuite />}
          {view === 'builder' && <CampaignBuilder key={activeWorkspace?.id} onPublished={handlePublished} />}
          {(view === 'brand' || view === 'members') && (
            <BrandManager
              key={`${activeWorkspace?.id}:${view}`}
              user={user}
              activeWorkspace={activeWorkspace}
              initialTab={view === 'members' ? 'members' : 'brands'}
              onWorkspacesChange={onUserRefresh}
            />
          )}
          {view === 'settings' && (
            <SettingsView
              key={activeWorkspace?.id}
              user={user}
              activeWorkspace={activeWorkspace}
              workspaces={workspaces}
              onUserRefresh={onUserRefresh}
              onWorkspaceDeleted={() => {
                // Clear stored active workspace, then refresh — App will pick
                // the user's first remaining workspace as the new active one.
                api.setActiveWorkspace('');
                onUserRefresh();
                setView('dash');
              }}
            />
          )}
          {view === 'landing' && <LandingCustomizer />}
          {view === 'reward' && (window.RewardsView ? <window.RewardsView /> : null)}
          {view === 'responses' && (window.ResponsesView ? <window.ResponsesView /> : null)}
          {view === 'super' && user?.role === 'super_admin' && (window.SuperAdminView ? <window.SuperAdminView /> : null)}
        </div>
      </div>
    </div>
  );
}

// Slim status bar shown above every authed view. Replaces the old chip-list
// of campaign names (visually noisy) with a compact summary:
//   • Live pulse + count of active campaigns
//   • Workspace plan badge
//   • Quick-jump button to start a new study
function PulseBar({ campaigns, activeWorkspace, onNew }) {
  if (!campaigns || !activeWorkspace) return null;

  const active = campaigns.filter((c) => c.status === 'active').length;
  const total = campaigns.length;
  const isAgency = activeWorkspace.plan === 'agency';

  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 14, flexShrink: 0,
      padding: '8px 18px', background: 'var(--surface)',
      borderBottom: '1px solid var(--line)',
    }}>
      {/* Live pulse */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <span style={{
          position: 'relative', width: 8, height: 8,
        }}>
          <span style={{
            position: 'absolute', inset: 0, borderRadius: '50%',
            background: active > 0 ? 'oklch(0.62 0.16 155)' : 'var(--ink-4)',
            animation: active > 0 ? 'pulse 1.8s ease-in-out infinite' : 'none',
          }} />
          <span style={{
            position: 'absolute', inset: 1.5, borderRadius: '50%',
            background: active > 0 ? 'oklch(0.62 0.16 155)' : 'var(--ink-4)',
          }} />
        </span>
        <span style={{ fontSize: 12.5, fontWeight: 600 }}>
          {active > 0 ? (
            <>
              {active} campaign aktif
              {total > active && (
                <span style={{ fontWeight: 400, color: 'var(--ink-3)' }}> · {total} total</span>
              )}
            </>
          ) : total > 0 ? (
            <span style={{ color: 'var(--ink-3)' }}>{total} campaign · belum ada yang aktif</span>
          ) : (
            <span style={{ color: 'var(--ink-3)' }}>Belum ada campaign — buat yang pertama →</span>
          )}
        </span>
      </div>

      {/* Workspace plan badge */}
      <span className={`badge ${isAgency ? 'badge-primary' : ''}`} style={{ fontSize: 10.5, textTransform: 'capitalize' }}>
        {activeWorkspace.plan}
      </span>

      {/* CTA */}
      <button
        className="btn btn-soft"
        onClick={onNew}
        style={{ marginLeft: 'auto', padding: '6px 12px', fontSize: 12.5, whiteSpace: 'nowrap' }}
      >
        <I.Plus size={13} /> Riset Baru
      </button>
    </div>
  );
}

// Public responder flow — reuses MobileFlow but loads the actual survey.
// The .phone-host wrapper applies a media query that strips the phone frame
// on real mobile viewports (<480px) so the survey renders full-screen.
function ResponderFlow({ slug }) {
  return (
    <div className="phone-host">
      <MobileFlow slug={slug} />
    </div>
  );
}

// ─── Root ─────────────────────────────────────────────────────────────
function App() {
  const [path, navigate] = useRoute();
  const [user, setUser] = useStateApp(undefined); // undefined = loading
  const [workspaces, setWorkspaces] = useStateApp([]);
  const [activeWorkspaceId, setActiveWorkspaceIdRaw] = useStateApp(() => api.getActiveWorkspace());
  const [, forceTick] = useStateApp(0);

  function setActiveWorkspaceId(id) {
    api.setActiveWorkspace(id);
    setActiveWorkspaceIdRaw(id);
  }

  function refreshMe() {
    return api.me().then((r) => {
      setUser(r.user);
      const ws = r.workspaces || [];
      setWorkspaces(ws);
      // Reconcile activeWorkspaceId against the list returned by the server.
      // Falls back to the first workspace if the stored id was deleted or
      // belonged to a different account.
      const stored = api.getActiveWorkspace();
      const valid = ws.find((w) => w.id === stored);
      if (!valid && ws[0]) {
        api.setActiveWorkspace(ws[0].id);
        setActiveWorkspaceIdRaw(ws[0].id);
      } else if (valid) {
        setActiveWorkspaceIdRaw(valid.id);
      }
    });
  }

  useEffectApp(() => {
    refreshMe().catch(() => setUser(null));
  }, []);

  // Redirect rules
  useEffectApp(() => {
    if (user === undefined) return;
    if (path.startsWith('/app') && !user) navigate('/login');
    if ((path === '/login' || path === '/register') && user) navigate('/app');
  }, [user, path]);

  const activeWorkspace = workspaces.find((w) => w.id === activeWorkspaceId) ?? workspaces[0] ?? null;

  if (user === undefined) {
    return (
      <div style={{ display: 'grid', placeItems: 'center', height: '100vh', color: 'var(--ink-3)', fontSize: 14 }}>
        Memuat…
      </div>
    );
  }

  // Routing
  if (path === '/' || path === '') {
    return <MarketingScreen navigate={navigate} />;
  }
  if (path === '/login') {
    return <AuthRoute mode="login" navigate={navigate} onAuthed={() => refreshMe().then(() => navigate('/app'))} />;
  }
  if (path === '/register') {
    return <AuthRoute mode="register" navigate={navigate} onAuthed={() => refreshMe().then(() => navigate('/app'))} />;
  }
  if (path.startsWith('/app')) {
    if (!user) return null; // redirect already queued
    return (
      <AdminShell
        user={user}
        workspaces={workspaces}
        activeWorkspace={activeWorkspace}
        onWorkspaceSwitch={(id) => { setActiveWorkspaceId(id); /* trigger remounts */ forceTick((n) => n + 1); }}
        onUserRefresh={refreshMe}
        onSignOut={async () => {
          try { await api.signOut(); } catch {}
          api.setActiveWorkspace('');
          setUser(null);
          setWorkspaces([]);
          navigate('/');
        }}
      />
    );
  }
  if (path.startsWith('/survey/')) {
    const slug = path.slice('/survey/'.length);
    return <ResponderFlow slug={slug} />;
  }

  // 404
  return (
    <div style={{ display: 'grid', placeItems: 'center', height: '100vh', textAlign: 'center', padding: 20 }}>
      <div>
        <div className="mono" style={{ fontSize: 13, color: 'var(--ink-3)' }}>404</div>
        <h1 style={{ fontSize: 28, fontWeight: 700, margin: '8px 0' }}>Halaman tidak ditemukan</h1>
        <button className="btn btn-primary" onClick={() => navigate('/')}>Kembali ke beranda</button>
      </div>
    </div>
  );
}

// Babel-standalone processes <script type="text/babel"> tags only AFTER
// DOMContentLoaded — so registering a DOMContentLoaded listener here would
// never fire. Run the bootstrap inline.
(function bootstrap() {
  window.RewardsView = window.RewardsView || (() => null);
  window.ResponsesView = window.ResponsesView || (() => null);

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