import {
  ActivityIcon,
  ArchiveRestoreIcon,
  ArrowLeftIcon,
  BarChart3Icon,
  BotIcon,
  FlaskConicalIcon,
  HistoryIcon,
  type LucideIcon,
  MonitorIcon,
  PanelLeftIcon,
  RefreshCcwIcon,
  ShieldCheckIcon,
  SlidersHorizontalIcon,
  UserRoundCogIcon,
  UsersRoundIcon,
  WifiIcon,
  WrenchIcon,
} from "lucide-react";
import { type CSSProperties, type ReactNode, useCallback, useEffect, useState } from "react";
import { includeDevelopmentSettings } from "../../app/settingsPageAvailability";
import { useAppStore } from "../../app/store";
import type { SettingsPageId } from "../../app/types";
import { Button } from "../../components/ui/button";
import { isPackagedDesktopApp } from "../../lib/desktopCommands";
import { type DesktopPlatformInfo, getDesktopPlatformInfo } from "../../lib/desktopPlatform";
import { onDesktopRailCommand } from "../../lib/desktopRailCommands";
import { useAdaptiveLayout } from "../../lib/useAdaptiveLayout";
import { cn } from "../../lib/utils";
import { InlineErrorBoundary } from "../CrashReportingErrorBoundary";
import { AdaptiveRailSurface } from "../layout/AdaptiveRailSurface";
import { BackupPage } from "./pages/BackupPage";
import { DesktopPage } from "./pages/DesktopPage";
import { DeveloperPage } from "./pages/DeveloperPage";
import { FeatureFlagsPage } from "./pages/FeatureFlagsPage";
import { PrivacyTelemetryPage } from "./pages/PrivacyTelemetryPage";
import { RemoteAccessPage } from "./pages/RemoteAccessPage";
import {
  ChatsSettingsPage,
  DefaultsSettingsPage,
  ModelsSettingsPage,
  ProfileMemorySettingsPage,
  ToolAccessSettingsPage,
} from "./pages/SettingsIntentPages";
import { SubagentsPage } from "./pages/SubagentsPage";
import { UpdatesPage } from "./pages/UpdatesPage";
import { UsagePage } from "./pages/UsagePage";
import { SettingsChromeProvider, type SettingsChromeState } from "./SettingsChromeContext";

type SettingsPageDefinition = {
  id: SettingsPageId;
  label: string;
  icon: LucideIcon;
  render: () => ReactNode;
};

const SETTINGS_PAGE_META: Record<SettingsPageId, { title: string; description: string }> = {
  models: {
    title: "Models",
    description: "Provider health, model defaults, and subagent routing.",
  },
  subagents: {
    title: "Subagents",
    description: "Specialized child-agent profiles and scoped tool access.",
  },
  toolAccess: {
    title: "Tool Access",
    description: "Connect external tools and data sources.",
  },
  desktop: {
    title: "Desktop",
    description: "Menu bar, tray, and quick chat controls for the desktop app.",
  },
  defaults: {
    title: "Behavior",
    description: "Defaults for models, tools, and behavior everywhere.",
  },
  profileMemory: {
    title: "Profile & Memory",
    description: "How Cowork should understand you and what it should remember.",
  },
  remoteAccess: {
    title: "Remote access",
    description: "Pair a phone to this folder or chat over the relay when the app is open.",
  },
  backup: {
    title: "Backups",
    description: "Recovery snapshots and restore points for chat sessions.",
  },
  chats: {
    title: "Chats",
    description: "Archived chat history, restore actions, and retention.",
  },
  usage: {
    title: "Usage",
    description: "Token usage and estimated cost across sessions.",
  },
  privacyTelemetry: {
    title: "Privacy & Telemetry",
    description: "Optional crash reports, product analytics, and AI trace consent.",
  },
  experiments: {
    title: "Experiments",
    description: "Enable or disable experimental capabilities.",
  },
  diagnostics: {
    title: "Diagnostics",
    description: "Debug visibility, runtime checks, and advanced output handling.",
  },
  updates: {
    title: "Updates",
    description: "App version and restart-based updates.",
  },
  providers: {
    title: "Models",
    description: "Provider health, model defaults, and subagent routing.",
  },
  openAiNativeConnectors: {
    title: "Tool Access",
    description: "Connect external tools and data sources.",
  },
  mcp: {
    title: "Tool Access",
    description: "Connect external tools and data sources.",
  },
  workspaces: {
    title: "Behavior",
    description: "Defaults for models, tools, and behavior everywhere.",
  },
  memory: {
    title: "Profile & Memory",
    description: "How Cowork should understand you and what it should remember.",
  },
  featureFlags: {
    title: "Experiments",
    description: "Enable or disable experimental capabilities.",
  },
  developer: {
    title: "Diagnostics",
    description: "Debug visibility, runtime checks, and advanced output handling.",
  },
  archivedChats: {
    title: "Chats",
    description: "Archived chat history, restore actions, and retention.",
  },
};

// Legacy settings page ids that no longer appear in the nav but may still
// arrive via deep links or persisted state. Map them to their canonical id so
// lookups land on the right page instead of silently falling back to "models".
export const SETTINGS_PAGE_ALIASES: Partial<Record<SettingsPageId, SettingsPageId>> = {
  providers: "models",
  openAiNativeConnectors: "toolAccess",
  mcp: "toolAccess",
  workspaces: "defaults",
  memory: "profileMemory",
  featureFlags: "experiments",
  developer: "diagnostics",
  archivedChats: "chats",
};

export function getSettingsGroups(
  remoteAccessAvailable: boolean,
  opts: { includeDevelopmentPages?: boolean } = {},
): Array<{
  label: string;
  pages: SettingsPageDefinition[];
}> {
  const includeDevelopmentPages = opts.includeDevelopmentPages ?? true;
  return [
    {
      label: "Models & tools",
      pages: [
        { id: "models", label: "Models", icon: BotIcon, render: () => <ModelsSettingsPage /> },
        {
          id: "subagents",
          label: "Subagents",
          icon: UsersRoundIcon,
          render: () => <SubagentsPage />,
        },
        {
          id: "toolAccess",
          label: "Tool Access",
          icon: WrenchIcon,
          render: () => <ToolAccessSettingsPage />,
        },
      ],
    },
    {
      label: "Workspace",
      pages: [
        {
          id: "defaults",
          label: "Behavior",
          icon: SlidersHorizontalIcon,
          render: () => <DefaultsSettingsPage />,
        },
        {
          id: "profileMemory",
          label: "Profile & Memory",
          icon: UserRoundCogIcon,
          render: () => <ProfileMemorySettingsPage />,
        },
        ...(remoteAccessAvailable
          ? [
              {
                id: "remoteAccess",
                label: "Remote access",
                icon: WifiIcon,
                render: () => <RemoteAccessPage />,
              } satisfies SettingsPageDefinition,
            ]
          : []),
      ],
    },
    {
      label: "History & Data",
      pages: [
        { id: "backup", label: "Backups", icon: ArchiveRestoreIcon, render: () => <BackupPage /> },
        { id: "chats", label: "Chats", icon: HistoryIcon, render: () => <ChatsSettingsPage /> },
        { id: "usage", label: "Usage", icon: BarChart3Icon, render: () => <UsagePage /> },
      ],
    },
    {
      label: "App",
      pages: [
        {
          id: "privacyTelemetry",
          label: "Privacy & Telemetry",
          icon: ShieldCheckIcon,
          render: () => <PrivacyTelemetryPage />,
        },
        { id: "desktop", label: "Desktop", icon: MonitorIcon, render: () => <DesktopPage /> },
        { id: "updates", label: "Updates", icon: RefreshCcwIcon, render: () => <UpdatesPage /> },
      ],
    },
    {
      label: "Advanced",
      pages: [
        ...(includeDevelopmentPages
          ? [
              {
                id: "experiments",
                label: "Experiments",
                icon: FlaskConicalIcon,
                render: () => <FeatureFlagsPage />,
              } satisfies SettingsPageDefinition,
            ]
          : []),
        {
          id: "diagnostics",
          label: "Diagnostics",
          icon: ActivityIcon,
          render: () => <DeveloperPage />,
        },
      ],
    },
  ];
}

export function getSettingsDragZoneStyle(
  sidebarWidth: number,
  platformInfo: DesktopPlatformInfo,
): CSSProperties | undefined {
  if (platformInfo.sidebarTitlebandMode === "native") {
    return { "--settings-sidebar-width": `${sidebarWidth}px` } as CSSProperties;
  }
  return undefined;
}

function SettingsNavigation({
  activePage,
  onSelectPage,
  onBack,
  settingsGroups,
}: {
  activePage: SettingsPageId;
  onSelectPage: (page: SettingsPageId) => void;
  onBack: () => void;
  settingsGroups: Array<{
    label: string;
    pages: SettingsPageDefinition[];
  }>;
}) {
  const currentWorkspace = useAppStore((s) =>
    s.workspaces.find((w) => w.id === s.selectedWorkspaceId),
  );
  const perWorkspaceSettings = useAppStore((s) => s.perWorkspaceSettings);

  return (
    <>
      <div className="shrink-0 settings-shell__nav-header border-b border-border/50">
        <div className="settings-shell__nav-titleband">
          <div className="settings-shell__nav-titleband-drag-zone" aria-hidden="true" />
          <div className="settings-shell__nav-titleband-row px-3 flex items-center">
            <button
              className="settings-shell__back-button flex h-9 w-full items-center justify-start gap-2 rounded-md px-2.5 text-left text-[13px] font-medium app-text-secondary transition-colors duration-150 hover:bg-foreground/[0.045] hover:text-foreground"
              type="button"
              onClick={onBack}
            >
              <ArrowLeftIcon className="h-4 w-4 shrink-0" />
              Back
            </button>
          </div>
        </div>
        {perWorkspaceSettings && currentWorkspace ? (
          <div
            className="app-type-caption truncate px-4 pb-3 app-text-secondary"
            title={currentWorkspace.name}
          >
            {currentWorkspace.name}
          </div>
        ) : null}
      </div>

      <nav
        className="min-h-0 flex-1 overflow-y-auto px-2.5 py-2 pb-4"
        aria-label="Settings sections"
      >
        <div className="flex flex-col gap-3">
          {settingsGroups.map((group) => (
            <div key={group.label} className="flex min-w-0 flex-col">
              <div className="app-type-label mb-1 px-2 py-1.5 uppercase tracking-[0.08em] app-text-muted">
                {group.label}
              </div>
              <div className="flex flex-col gap-0.5">
                {group.pages.map((page) => {
                  const Icon = page.icon;
                  return (
                    <button
                      key={page.id}
                      className={cn(
                        "settings-shell__nav-button flex w-full items-center gap-2.5 rounded-lg px-2.5 py-2 text-left text-[13px] transition-colors duration-150",
                        activePage === page.id
                          ? "settings-shell__nav-button--active font-semibold text-foreground"
                          : "font-medium app-text-secondary hover:bg-foreground/[0.045] hover:text-foreground",
                      )}
                      type="button"
                      onClick={() => onSelectPage(page.id)}
                    >
                      <Icon
                        className={cn(
                          "size-4 shrink-0",
                          activePage === page.id
                            ? "text-[var(--text-settings-nav-active-icon)]"
                            : "text-muted-foreground",
                        )}
                      />
                      <span className="min-w-0 truncate">{page.label}</span>
                    </button>
                  );
                })}
              </div>
            </div>
          ))}
        </div>
      </nav>
    </>
  );
}

export function SettingsShell() {
  const desktopFeatureFlags = useAppStore((s) => s.desktopFeatureFlags);
  const remoteAccessAvailable = desktopFeatureFlags.remoteAccess === true;
  const packaged = useAppStore((s) => s.updateState.packaged);
  const settingsPage = useAppStore((s) => s.settingsPage);
  const setSettingsPage = useAppStore((s) => s.setSettingsPage);
  const closeSettings = useAppStore((s) => s.closeSettings);
  const sidebarWidth = useAppStore((s) => s.sidebarWidth);
  const [navigationOpen, setNavigationOpen] = useState(false);
  const adaptiveLayout = useAdaptiveLayout({
    contextSidebarCollapsed: true,
    hasContextSidebar: false,
    leftSidebarWidth: sidebarWidth,
    rightSidebarMaximumWidth: 0,
    rightSidebarMinimumWidth: 0,
    rightSidebarWidth: 0,
    sidebarCollapsed: false,
  });
  const effectiveSidebarWidth = adaptiveLayout.leftOverlay
    ? Math.max(160, Math.min(440, sidebarWidth))
    : adaptiveLayout.leftWidth;
  const navigationActive =
    adaptiveLayout.leftInline || (adaptiveLayout.leftOverlay && navigationOpen);
  useEffect(
    () =>
      onDesktopRailCommand((command) => {
        if (command !== "toggle-sidebar") return;
        if (adaptiveLayout.leftOverlay) {
          setNavigationOpen((open) => !open);
        }
      }),
    [adaptiveLayout.leftOverlay],
  );
  const settingsGroups = getSettingsGroups(remoteAccessAvailable, {
    includeDevelopmentPages: includeDevelopmentSettings(packaged || isPackagedDesktopApp()),
  });
  const settingsPages = settingsGroups.flatMap((group) => group.pages);
  const resolvedSettingsPage = SETTINGS_PAGE_ALIASES[settingsPage] ?? settingsPage;
  const activePage =
    settingsPages.find((page) => page.id === resolvedSettingsPage) ?? settingsPages[0];
  const meta = SETTINGS_PAGE_META[activePage.id];

  const [pageChrome, setPageChromeState] = useState<SettingsChromeState>({});
  const handleChromeChange = useCallback((next: SettingsChromeState) => {
    setPageChromeState(next);
  }, []);
  const handleSelectPage = useCallback(
    (page: SettingsPageId) => {
      setSettingsPage(page);
      if (adaptiveLayout.leftOverlay) {
        setNavigationOpen(false);
      }
    },
    [adaptiveLayout.leftOverlay, setSettingsPage],
  );
  const platformInfo = getDesktopPlatformInfo();
  const settingsDragZoneStyle = getSettingsDragZoneStyle(
    adaptiveLayout.leftInline ? adaptiveLayout.leftWidth : 0,
    platformInfo,
  );
  const isMacos = platformInfo.platform === "macos";

  const isBackupPage = activePage.id === "backup";
  const navigationToggle = adaptiveLayout.leftOverlay ? (
    <Button
      aria-expanded={navigationOpen}
      aria-label={navigationOpen ? "Close settings navigation" : "Open settings navigation"}
      className="app-native-no-drag shrink-0"
      onClick={() => setNavigationOpen((open) => !open)}
      size="icon-sm"
      type="button"
      variant="ghost"
    >
      <PanelLeftIcon aria-hidden="true" />
    </Button>
  ) : null;

  return (
    <div
      className="settings-shell relative grid h-full min-h-0 min-w-0 bg-transparent"
      data-layout-tier={adaptiveLayout.tier}
      style={
        {
          "--settings-sidebar-width": `${effectiveSidebarWidth}px`,
          gridTemplateColumns: adaptiveLayout.leftInline
            ? `${adaptiveLayout.leftWidth}px minmax(0, 1fr)`
            : "minmax(0, 1fr)",
        } as CSSProperties
      }
    >
      {platformInfo.sidebarTitlebandMode === "native" ? (
        <div
          className="settings-shell__titleband-fill absolute inset-x-0 top-0"
          style={settingsDragZoneStyle}
          aria-hidden="true"
        />
      ) : null}
      <div
        className="settings-shell__drag-zone absolute inset-x-0 top-0"
        style={settingsDragZoneStyle}
        aria-hidden="true"
      />
      <AdaptiveRailSurface
        active={navigationActive}
        className="settings-shell__nav app-left-sidebar-pane flex h-full min-h-0 min-w-0 flex-col border-r border-border/50"
        label="Settings navigation"
        onClose={() => setNavigationOpen(false)}
        overlay={adaptiveLayout.leftOverlay}
        side="left"
        width={effectiveSidebarWidth}
      >
        <SettingsNavigation
          activePage={activePage.id}
          onSelectPage={handleSelectPage}
          onBack={closeSettings}
          settingsGroups={settingsGroups}
        />
      </AdaptiveRailSurface>

      <main className="settings-shell__main app-main-content flex min-h-0 min-w-0 flex-col">
        <SettingsChromeProvider onChromeChange={handleChromeChange}>
          <div
            className={cn(
              "flex min-h-0 min-w-0 flex-1 flex-col",
              isBackupPage ? "overflow-hidden" : "",
            )}
          >
            <header
              className={cn(
                "settings-shell__page-header shrink-0 backdrop-blur-sm",
                isMacos
                  ? isBackupPage
                    ? ""
                    : "sticky top-0 z-10"
                  : cn(
                      "px-5 max-[719px]:px-4",
                      isBackupPage ? "pb-3 pt-4" : "sticky top-0 z-10 py-4",
                    ),
              )}
            >
              {isMacos ? (
                <>
                  <div className="settings-shell__page-titleband">
                    <div className="settings-shell__page-titleband-row flex flex-col gap-3 px-5 max-[719px]:px-4 sm:flex-row sm:items-end sm:justify-between">
                      <div className="flex min-w-0 items-center gap-2">
                        {navigationToggle}
                        <h1 className="min-w-0 text-xl font-semibold tracking-tight text-foreground">
                          {meta.title}
                        </h1>
                      </div>
                      {pageChrome.headerActions ? (
                        <div className="settings-shell__header-actions flex shrink-0 flex-wrap items-center justify-end gap-2">
                          {pageChrome.headerActions}
                        </div>
                      ) : null}
                    </div>
                  </div>
                  <div
                    className={cn(
                      "settings-shell__page-intro px-5 max-[719px]:px-4",
                      isBackupPage ? "pb-3 pt-3" : "pb-4 pt-3",
                    )}
                  >
                    <p className="max-w-xl text-sm leading-relaxed text-muted-foreground">
                      {meta.description}
                    </p>
                  </div>
                </>
              ) : (
                <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
                  <div className="min-w-0 space-y-1">
                    <div className="flex min-w-0 items-center gap-2">
                      {navigationToggle}
                      <h1 className="min-w-0 text-xl font-semibold tracking-tight text-foreground">
                        {meta.title}
                      </h1>
                    </div>
                    <p className="max-w-xl text-sm leading-relaxed text-muted-foreground">
                      {meta.description}
                    </p>
                  </div>
                  {pageChrome.headerActions ? (
                    <div className="settings-shell__header-actions flex shrink-0 flex-wrap items-center justify-end gap-2 sm:pt-0.5">
                      {pageChrome.headerActions}
                    </div>
                  ) : null}
                </div>
              )}
            </header>

            <div className="settings-shell__scroll min-h-0 min-w-0 flex-1 overflow-y-auto">
              <div
                className={cn(
                  "settings-shell__content w-full",
                  isBackupPage
                    ? "flex min-h-0 flex-1 flex-col max-[719px]:px-4 max-[719px]:pb-4 min-[720px]:px-5 min-[720px]:pb-6"
                    : "max-[719px]:p-4 min-[720px]:px-5 min-[720px]:pb-6 min-[720px]:pt-4",
                )}
              >
                <div
                  data-settings-page={activePage.id}
                  className={cn(isBackupPage ? "flex min-h-0 flex-1 flex-col" : "")}
                >
                  <InlineErrorBoundary label="This settings page couldn't be rendered.">
                    {activePage.render()}
                  </InlineErrorBoundary>
                </div>
              </div>
            </div>
          </div>
        </SettingsChromeProvider>
      </main>
    </div>
  );
}
