// ---------- App entry ----------

function App() {
  const session = React.useMemo(() => getSession(), []);
  const isAdmin = session && session.role === "admin";
  const allowedClientViews = React.useMemo(
    () => (session?.role === "client" ? getSessionAllowedViews(session) : CLIENT_ALLOWED_VIEWS),
    [session]
  );
  const defaultClientView = React.useMemo(
    () => (allowedClientViews.has("dashboard") ? "dashboard" : (Array.from(allowedClientViews)[0] || "dashboard")),
    [allowedClientViews]
  );

  const [active, setActive] = React.useState("dashboard");
  const [mode, setMode] = React.useState(() =>
    isAdmin ? (localStorage.getItem(VKEYS.MODE) || "dev") : "client"
  );
  const [theme, setTheme] = React.useState(() =>
    localStorage.getItem(VKEYS.THEME) || "light"
  );
  const [cpOpen, setCpOpen] = React.useState(false);
  const [navOpen, setNavOpen] = React.useState(false);

  const [assistants, setAssistants] = React.useState(() => loadAssistants());
  const [clients, setClients] = React.useState(() => loadClients());
  const [callLogs, setCallLogs] = React.useState([]);
  const [logsLoaded, setLogsLoaded] = React.useState(false);
  const safeClients = React.useMemo(
    () => (Array.isArray(clients) ? clients.filter((client) => client && typeof client === "object") : []),
    [clients]
  );

  React.useEffect(() => {
    if (!session) window.location.replace("/login.html");
  }, [session]);

  React.useEffect(() => {
    fetchAssistantsFromServer().then((list) => setAssistants(list));
  }, []);

  React.useEffect(() => {
    fetchClientsFromServer().then((list) => setClients(list));
  }, []);

  React.useEffect(() => {
    voxApiOptional("/logs", [])
      .then((data) => {
        const logs = Array.isArray(data) ? data : (data.logs || data.calls || []);
        setCallLogs(logs);
      })
      .finally(() => setLogsLoaded(true));
  }, []);

  React.useEffect(() => {
    localStorage.setItem(VKEYS.MODE, mode);
    document.body.classList.toggle("client-mode", mode === "client");
  }, [mode]);

  React.useEffect(() => {
    localStorage.setItem(VKEYS.THEME, theme);
    document.body.classList.toggle("dark", theme === "dark");
  }, [theme]);

  React.useEffect(() => {
    window.__openCP = () => setCpOpen(true);
    return () => { delete window.__openCP; };
  }, []);

  React.useEffect(() => {
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && (e.key === "k" || e.key === "K")) {
        e.preventDefault();
        setCpOpen((open) => !open);
      } else if (e.key === "Escape") {
        setCpOpen(false);
        setNavOpen(false);
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  const visible = (mode === "client" && !allowedClientViews.has(active)) ? defaultClientView : active;
  const visibleLabel = VIEW_LABELS[visible] || "Dashboard";
  const workspaceName = session?.companyName || session?.organizationKey || (isAdmin ? "Xandrix Workspace" : "Client Workspace");

  function navigate(id) {
    setActive(id);
    setCpOpen(false);
    setNavOpen(false);
  }

  React.useEffect(() => {
    window.__navigate = navigate;
    return () => {
      if (window.__navigate === navigate) delete window.__navigate;
    };
  }, []);

  const viewSummary = React.useMemo(() => {
    const summaries = {
      dashboard: isAdmin
        ? `Track ${assistants.length} assistants, ${clients.length} clients, and today's operating picture from one place.`
        : "See how your assistants, campaigns, and call outcomes are performing without extra noise.",
      analytics: isAdmin
        ? "Compare performance by assistant, client, and structured output quality."
        : "Review saved reporting views, trends, and customer-specific operational signals.",
      billing: isAdmin
        ? "Monitor wallet usage, internal cost posture, and account-level spend."
        : "Stay ahead of wallet balance, invoice timing, and projected usage.",
      assistants: isAdmin
        ? "Design prompts, tools, structured outputs, and quick tests in one workflow."
        : "Review the assistants assigned to your workspace and understand how they behave.",
      voice: "Compare voices and tune delivery before changes reach live calls.",
      calls: "Operate outbound calling and keep telephony actions easy to reach.",
      sip: "Configure SIP routing and connection details with clearer operational context.",
      asterisk: "Inspect lower-level call routing and runtime state when deeper debugging is needed.",
      logs: isAdmin
        ? "Inspect inbound and outbound sessions with routing context, recordings, outcomes, and billing detail."
        : "Review inbound conversations, outcomes, transcripts, and recordings from one workspace panel.",
      blast: isAdmin
        ? "Launch campaigns with fewer hidden steps and more confidence in the setup."
        : "Prepare, launch, and review campaigns with a cleaner handoff from setup to reporting.",
      clients: "Manage account access, limits, pricing, and assistant assignments for each customer.",
      tools: "Manage the external actions your assistants can invoke during calls.",
      automations: "Coordinate event-driven workflows connected to call outcomes and handoffs.",
      n8n: "Keep workflow automation within reach for developer-only orchestration work.",
      system: "Review platform-level configuration and operating guardrails.",
    };
    return summaries[visible] || "Move through the workspace with more context and less friction.";
  }, [visible, isAdmin, assistants.length, clients.length]);

  const focusPills = React.useMemo(() => {
    if (visible === "dashboard") {
      return [
        `${callLogs.length} calls loaded`,
        `${assistants.length} assistants`,
        `${clients.length} clients`,
      ];
    }
    if (visible === "assistants") {
      return [
        `${assistants.filter((item) => item.status !== "paused").length} active`,
        isAdmin ? "Prompt and tooling builder" : "Assigned workspace assistants",
      ];
    }
    if (visible === "logs") {
      return [
        `${callLogs.length} sessions`,
        logsLoaded ? "Call data ready" : "Loading call data",
      ];
    }
    if (visible === "clients") {
      return [
        `${safeClients.length} accounts`,
        `${safeClients.filter((client) => client.isLocked).length} locked`,
      ];
    }
    return [
      isAdmin ? "Developer workspace" : "Client workspace",
      visibleLabel,
    ];
  }, [visible, callLogs.length, assistants, safeClients, isAdmin, logsLoaded, visibleLabel]);

  if (!session) return null;

  const renderView = () => {
    switch (visible) {
      case "dashboard": return <DashboardView mode={mode} callLogs={callLogs} assistants={assistants} clients={safeClients} allowedViews={allowedClientViews} />;
      case "analytics": return <AnalyticsView mode={mode} callLogs={callLogs} assistants={assistants} clients={safeClients} />;
      case "billing": return <BillingView mode={mode} clients={safeClients} />;
      case "assistants": return <AssistantsView mode={mode} assistants={assistants} setAssistants={setAssistants} clients={safeClients} setClients={setClients} />;
      case "voice": return <VoiceStudioView />;
      case "calls": return <TelephonyView callLogs={callLogs} assistants={assistants} />;
      case "phone-numbers": return <PhoneNumbersView assistants={assistants} />;
      case "sip": return <SipView />;
      case "asterisk": return <AsteriskView assistants={assistants} />;
      case "logs": return <LogsView mode={mode} callLogs={callLogs} assistants={assistants} clients={safeClients} />;
      case "blast": return <BlastView assistants={assistants} session={session} />;
      case "ptp": return <PtpView />;
      case "clients": return <ClientsView clients={safeClients} assistants={assistants} setClients={setClients} mode={mode} />;
      case "tools": return <ToolsView />;
      case "automations": return <AutomationsView />;
      case "n8n": return <N8nView />;
      case "kb-gaps": return <KbGapsView />;
      case "asr-corrections": return <AsrCorrectionsView />;
      case "system": return <SystemView />;
      default: return <DashboardView mode={mode} callLogs={callLogs} assistants={assistants} clients={safeClients} allowedViews={allowedClientViews} />;
    }
  };

  const crumbs = mode === "client"
    ? [session.name, visibleLabel]
    : ["Workspace", visibleLabel];

  return (
    <div className="app">
      <Sidebar
        active={visible}
        onNavigate={navigate}
        mode={mode}
        assistants={assistants}
        clients={safeClients}
        callLogs={callLogs}
        session={session}
        allowedViews={allowedClientViews}
        navOpen={navOpen}
        onCloseNav={() => setNavOpen(false)}
        workspaceName={workspaceName}
      />
      <div className="main">
        <Topbar
          crumbs={crumbs}
          mode={mode}
          setMode={isAdmin ? setMode : (() => {})}
          theme={theme}
          setTheme={setTheme}
          onOpenCP={() => setCpOpen(true)}
          onOpenNav={() => setNavOpen(true)}
          session={session}
          workspaceName={workspaceName}
          viewLabel={visibleLabel}
          viewSummary={viewSummary}
          focusPills={focusPills}
        />
        <div className="content">
          <div className="content-inner">
            {renderView()}
          </div>
        </div>
      </div>
      <CommandPalette open={cpOpen} onClose={() => setCpOpen(false)} onNavigate={navigate} />
    </div>
  );
}

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