import { useState, useEffect, useCallback, useMemo } from 'react';
import { useOutletContext } from 'react-router-dom';
import {
  Tabs,
  Card,
  Collapse,
  Dropdown,
  Form,
  Input,
  Select,
  Switch,
  Button,
  Space,
  Spin,
  Tag,
  Tree,
  Modal,
  Badge,
  Typography,
  Tooltip,
  message,
  Result,
  Grid,
  theme,
} from 'antd';
import type { TreeDataNode } from 'antd';
import type { TreeProps } from 'antd';
import {
  SaveOutlined,
  BuildOutlined,
  CheckCircleOutlined,
  CloseCircleOutlined,
  PlusOutlined,
  DeleteOutlined,
  EditOutlined,
  FolderOutlined,
  FileOutlined,
  LinkOutlined,
  LoadingOutlined,
  WarningOutlined,
  HolderOutlined,
} from '@ant-design/icons';
import Editor from '@monaco-editor/react';
import { parseDocument, Document } from 'yaml';
import type { ScalarTag } from 'yaml';
import { api } from '@/lib/api';
import { useAuthStore } from '@/stores/auth.store';
import type { AppOutletContext } from '@/components/AppLayout';
import type { MkDocsConfigResponse, MkDocsBuildResult, FileNode, DocsStatus, DocsConfig, Campaign } from '@/types/api';

const { Text } = Typography;

// --- Constants ---

const MATERIAL_COLORS = [
  'red', 'pink', 'purple', 'deep purple', 'indigo', 'blue', 'light blue',
  'cyan', 'teal', 'green', 'light green', 'lime', 'yellow', 'amber',
  'orange', 'deep orange', 'brown', 'grey', 'blue grey', 'black', 'white',
];

const FEATURE_CATEGORIES: Record<string, string[]> = {
  Navigation: [
    'navigation.tabs', 'navigation.tabs.sticky', 'navigation.sections',
    'navigation.expand', 'navigation.indexes', 'navigation.footer',
    'navigation.path', 'navigation.prune', 'navigation.top',
    'navigation.tracking', 'navigation.instant', 'navigation.instant.prefetch',
    'navigation.instant.progress',
  ],
  Content: [
    'content.action.edit', 'content.action.view', 'content.code.annotate',
    'content.code.copy', 'content.tooltips', 'content.tabs.link',
  ],
  Search: ['search.highlight', 'search.share', 'search.suggest'],
  'Table of Contents': ['toc.follow', 'toc.integrate'],
  Header: ['header.autohide'],
  Announcements: ['announce.dismiss'],
};

// --- YAML Helpers ---

const pythonNameTag: ScalarTag = {
  identify: () => false,
  tag: '!python/name',
  collection: undefined as never,
  resolve: (str: string) => str,
};

const pythonObjectTag: ScalarTag = {
  identify: () => false,
  tag: '!python/object',
  collection: undefined as never,
  resolve: (str: string) => str,
};

/** Custom tag handling for !!python/name: etc. */
function parseYamlConfig(content: string): Document {
  return parseDocument(content, {
    customTags: (tags) => [
      ...tags,
      pythonNameTag,
      pythonObjectTag,
    ],
    keepSourceTokens: true,
  });
}

function serializeYamlDoc(doc: Document): string {
  return doc.toString({
    lineWidth: 0,
  });
}

/** Set a deeply nested value in a YAML document */
function setYamlValue(doc: Document, path: string, value: unknown): void {
  const parts = path.split('.');
  // Use doc.setIn for deep paths
  doc.setIn(parts, value);
}

// --- Nav Tree Helpers ---

interface NavNode {
  id: string;
  label: string;
  type: 'section' | 'page' | 'link';
  path?: string;
  children?: NavNode[];
}

let navIdCounter = 0;
function nextNavId(): string {
  return `nav-${++navIdCounter}`;
}

/** Parse mkdocs nav YAML array into NavNode tree */
function parseNavItems(items: unknown[]): NavNode[] {
  const nodes: NavNode[] = [];
  for (const item of items) {
    if (typeof item === 'string') {
      // Simple page reference: "path.md"
      nodes.push({ id: nextNavId(), label: item, type: 'page', path: item });
    } else if (typeof item === 'object' && item !== null) {
      const obj = item as Record<string, unknown>;
      for (const [label, value] of Object.entries(obj)) {
        if (typeof value === 'string') {
          // "Label: path.md" or "Label: https://..."
          const isLink = value.startsWith('http://') || value.startsWith('https://');
          nodes.push({ id: nextNavId(), label, type: isLink ? 'link' : 'page', path: value });
        } else if (Array.isArray(value)) {
          // Section: "Label: [children]"
          nodes.push({ id: nextNavId(), label, type: 'section', children: parseNavItems(value) });
        }
      }
    }
  }
  return nodes;
}

/** Convert NavNode tree back to mkdocs nav YAML format */
function serializeNavItems(nodes: NavNode[]): unknown[] {
  return nodes.map((node) => {
    if (node.type === 'section' && node.children) {
      return { [node.label]: serializeNavItems(node.children) };
    }
    if (node.path) {
      return { [node.label]: node.path };
    }
    return node.label;
  });
}

/** Convert NavNode tree to Ant Design TreeDataNode */
function navNodesToTreeData(nodes: NavNode[]): TreeDataNode[] {
  return nodes.map((node) => ({
    key: node.id,
    title: node.label,
    icon: node.type === 'section' ? <FolderOutlined /> : node.type === 'link' ? <LinkOutlined /> : <FileOutlined />,
    isLeaf: node.type !== 'section',
    children: node.children ? navNodesToTreeData(node.children) : undefined,
  }));
}

/** Find a NavNode by id in the tree */
function findNavNode(nodes: NavNode[], id: string): NavNode | null {
  for (const node of nodes) {
    if (node.id === id) return node;
    if (node.children) {
      const found = findNavNode(node.children, id);
      if (found) return found;
    }
  }
  return null;
}

/** Remove a NavNode by id from the tree (returns new tree) */
function removeNavNode(nodes: NavNode[], id: string): NavNode[] {
  return nodes.filter((node) => {
    if (node.id === id) return false;
    if (node.children) {
      node.children = removeNavNode(node.children, id);
    }
    return true;
  });
}

/** Collect all .md file paths from the file tree */
function collectMdPaths(nodes: FileNode[], prefix = ''): string[] {
  const paths: string[] = [];
  for (const node of nodes) {
    const fullPath = prefix ? `${prefix}/${node.name}` : node.name;
    if (node.isDirectory && node.children) {
      paths.push(...collectMdPaths(node.children, fullPath));
    } else if (node.name.endsWith('.md')) {
      paths.push(fullPath);
    }
  }
  return paths;
}

/** Collect all page paths referenced in the nav tree */
function collectNavPaths(nodes: NavNode[]): string[] {
  const paths: string[] = [];
  for (const node of nodes) {
    if (node.type === 'page' && node.path && !node.path.startsWith('http')) {
      paths.push(node.path);
    }
    if (node.children) {
      paths.push(...collectNavPaths(node.children));
    }
  }
  return paths;
}

/** Collect all http/https URLs from nav nodes (links) */
function collectNavLinkUrls(nodes: NavNode[]): string[] {
  const urls: string[] = [];
  for (const node of nodes) {
    if (node.path && node.path.startsWith('http')) urls.push(node.path);
    if (node.children) urls.push(...collectNavLinkUrls(node.children));
  }
  return urls;
}


// ===========================================
// Main Component
// ===========================================

export default function MkDocsSettingsPage() {
  const { setPageHeader } = useOutletContext<AppOutletContext>();
  const { user } = useAuthStore();
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;
  const { token } = theme.useToken();
  const [messageApi, contextHolder] = message.useMessage();

  const isSuperAdmin = user?.role === 'SUPER_ADMIN';

  // Shared state
  const [rawYaml, setRawYaml] = useState('');
  const [originalYaml, setOriginalYaml] = useState('');
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);

  // Settings tab state
  const [settingsForm] = Form.useForm();
  const [features, setFeatures] = useState<string[]>([]);
  const [settingsDirty, setSettingsDirty] = useState(false);
  const [settingsSaving, setSettingsSaving] = useState(false);

  // Nav tab state
  const [navNodes, setNavNodes] = useState<NavNode[]>([]);
  const [navDirty, setNavDirty] = useState(false);
  const [navSaving, setNavSaving] = useState(false);
  const [navModalOpen, setNavModalOpen] = useState(false);
  const [navModalType, setNavModalType] = useState<'section' | 'page' | 'link'>('page');
  const [navModalLabel, setNavModalLabel] = useState('');
  const [navModalPath, setNavModalPath] = useState('');
  const [navModalParentId, setNavModalParentId] = useState<string | null>(null);
  const [navEditId, setNavEditId] = useState<string | null>(null);
  const [fileTree, setFileTree] = useState<FileNode[]>([]);
  const [expandedNavKeys, setExpandedNavKeys] = useState<React.Key[]>([]);
  const [campaigns, setCampaigns] = useState<Campaign[]>([]);

  // YAML editor tab state
  const [editorYaml, setEditorYaml] = useState('');
  const [editorDirty, setEditorDirty] = useState(false);
  const [editorSaving, setEditorSaving] = useState(false);


  // Build tab state
  const [docsStatus, setDocsStatus] = useState<DocsStatus | null>(null);
  const [docsConfig, setDocsConfig] = useState<DocsConfig | null>(null);
  const [building, setBuilding] = useState(false);
  const [buildResult, setBuildResult] = useState<MkDocsBuildResult | null>(null);
  const [buildTimestamp, setBuildTimestamp] = useState<string | null>(null);

  // --- Data Loading ---

  const loadConfig = useCallback(async () => {
    setLoading(true);
    setError(false);
    try {
      const [configRes, filesRes, campaignsRes] = await Promise.all([
        api.get<MkDocsConfigResponse>('/docs/mkdocs-config'),
        api.get<FileNode[]>('/docs/files'),
        api.get('/campaigns/public', { params: { limit: 50 } }).catch(() => ({ data: { campaigns: [] } })),
      ]);
      const content = configRes.data.content;
      setRawYaml(content);
      setOriginalYaml(content);
      setEditorYaml(content);
      setFileTree(filesRes.data);
      setCampaigns(campaignsRes.data.campaigns);

      // Parse for settings tab
      syncSettingsFromYaml(content);
      // Parse for nav tab
      syncNavFromYaml(content);
    } catch {
      setError(true);
    } finally {
      setLoading(false);
    }
  }, []);

  const syncSettingsFromYaml = useCallback((content: string) => {
    try {
      const doc = parseYamlConfig(content);
      const json = doc.toJSON() as Record<string, unknown>;
      const themeObj = json.theme as Record<string, unknown> | undefined;
      const palette = themeObj?.palette as Record<string, unknown>[] | Record<string, unknown> | undefined;
      const font = themeObj?.font as Record<string, unknown> | undefined;

      // Palette can be array (toggle) or single object
      const firstPalette = Array.isArray(palette) ? palette[0] : palette;

      settingsForm.setFieldsValue({
        site_name: json.site_name ?? '',
        site_description: json.site_description ?? '',
        site_url: json.site_url ?? '',
        site_author: json.site_author ?? '',
        primary: (firstPalette?.primary as string) ?? 'indigo',
        accent: (firstPalette?.accent as string) ?? 'indigo',
        scheme: (firstPalette?.scheme as string) ?? 'default',
        text_font: (font?.text as string) ?? '',
        code_font: (font?.code as string) ?? '',
        logo: (themeObj?.logo as string) ?? '',
        favicon: (themeObj?.favicon as string) ?? '',
      });

      const featuresList = (themeObj?.features as string[]) || [];
      setFeatures(featuresList);
      setSettingsDirty(false);
    } catch {
      // If parsing fails, don't update settings
    }
  }, [settingsForm]);

  const syncNavFromYaml = useCallback((content: string) => {
    try {
      const doc = parseYamlConfig(content);
      const json = doc.toJSON() as Record<string, unknown>;
      const nav = json.nav as unknown[];
      if (Array.isArray(nav)) {
        navIdCounter = 0;
        setNavNodes(parseNavItems(nav));
      }
      setNavDirty(false);
    } catch {
      // If parsing fails, don't update nav
    }
  }, []);

  useEffect(() => { loadConfig(); }, [loadConfig]);

  // Page header
  useEffect(() => {
    setPageHeader({ title: 'Docs Settings' });
    return () => setPageHeader(null);
  }, [setPageHeader]);


  // --- Settings Tab: Save ---

  const saveSettings = useCallback(async () => {
    if (!isSuperAdmin) return;
    setSettingsSaving(true);
    try {
      const values = settingsForm.getFieldsValue();
      const doc = parseYamlConfig(rawYaml);
      const json = doc.toJSON() as Record<string, unknown>;

      // Update top-level fields
      if (values.site_name !== undefined) setYamlValue(doc, 'site_name', values.site_name);
      if (values.site_description !== undefined) setYamlValue(doc, 'site_description', values.site_description);
      if (values.site_url !== undefined) setYamlValue(doc, 'site_url', values.site_url);
      if (values.site_author !== undefined) setYamlValue(doc, 'site_author', values.site_author);

      // Update theme palette
      const themeObj = json.theme as Record<string, unknown> | undefined;
      const palette = themeObj?.palette;
      if (Array.isArray(palette) && palette.length > 0) {
        // Update both palette entries for toggle mode
        setYamlValue(doc, 'theme.palette.0.primary', values.primary);
        setYamlValue(doc, 'theme.palette.0.accent', values.accent);
        setYamlValue(doc, 'theme.palette.0.scheme', values.scheme);
        if (palette.length > 1) {
          setYamlValue(doc, 'theme.palette.1.primary', values.primary);
          setYamlValue(doc, 'theme.palette.1.accent', values.accent);
        }
      } else {
        setYamlValue(doc, 'theme.palette.primary', values.primary);
        setYamlValue(doc, 'theme.palette.accent', values.accent);
        setYamlValue(doc, 'theme.palette.scheme', values.scheme);
      }

      // Update fonts
      if (values.text_font) setYamlValue(doc, 'theme.font.text', values.text_font);
      if (values.code_font) setYamlValue(doc, 'theme.font.code', values.code_font);

      // Update logo/favicon
      if (values.logo) setYamlValue(doc, 'theme.logo', values.logo);
      if (values.favicon) setYamlValue(doc, 'theme.favicon', values.favicon);

      // Update features
      setYamlValue(doc, 'theme.features', features);

      const newYaml = serializeYamlDoc(doc);
      await api.put('/docs/mkdocs-config', { content: newYaml });
      setRawYaml(newYaml);
      setOriginalYaml(newYaml);
      setEditorYaml(newYaml);
      setSettingsDirty(false);
      messageApi.success('Settings saved');
    } catch (err: unknown) {
      const msg = (err as { response?: { data?: { error?: { message?: string } } } })?.response?.data?.error?.message || 'Failed to save settings';
      messageApi.error(msg);
    } finally {
      setSettingsSaving(false);
    }
  }, [isSuperAdmin, settingsForm, rawYaml, features, messageApi]);

  // --- Nav Tab: Save ---

  const saveNav = useCallback(async () => {
    if (!isSuperAdmin) return;
    setNavSaving(true);
    try {
      const doc = parseYamlConfig(rawYaml);
      const navYaml = serializeNavItems(navNodes);
      setYamlValue(doc, 'nav', navYaml);
      const newYaml = serializeYamlDoc(doc);
      await api.put('/docs/mkdocs-config', { content: newYaml });
      setRawYaml(newYaml);
      setOriginalYaml(newYaml);
      setEditorYaml(newYaml);
      setNavDirty(false);
      messageApi.success('Navigation saved');
    } catch (err: unknown) {
      const msg = (err as { response?: { data?: { error?: { message?: string } } } })?.response?.data?.error?.message || 'Failed to save navigation';
      messageApi.error(msg);
    } finally {
      setNavSaving(false);
    }
  }, [isSuperAdmin, rawYaml, navNodes, messageApi]);

  // --- YAML Editor Tab: Save ---

  const saveEditor = useCallback(async () => {
    if (!isSuperAdmin) return;
    setEditorSaving(true);
    try {
      // Validate first
      parseYamlConfig(editorYaml);
      await api.put('/docs/mkdocs-config', { content: editorYaml });
      setRawYaml(editorYaml);
      setOriginalYaml(editorYaml);
      setEditorDirty(false);
      // Sync other tabs
      syncSettingsFromYaml(editorYaml);
      syncNavFromYaml(editorYaml);
      messageApi.success('Config saved');
    } catch (err: unknown) {
      const msg = (err as { response?: { data?: { error?: { message?: string } } } })?.response?.data?.error?.message
        || (err as Error)?.message
        || 'Failed to save config';
      messageApi.error(msg);
    } finally {
      setEditorSaving(false);
    }
  }, [isSuperAdmin, editorYaml, messageApi, syncSettingsFromYaml, syncNavFromYaml]);

  // Ctrl+S for YAML editor
  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if ((e.ctrlKey || e.metaKey) && e.key === 's') {
        e.preventDefault();
        if (editorDirty) saveEditor();
      }
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, [editorDirty, saveEditor]);

  // --- Build Tab ---

  const checkStatus = useCallback(async () => {
    try {
      const [statusRes, configRes] = await Promise.all([
        api.get<DocsStatus>('/docs/status'),
        api.get<DocsConfig>('/docs/config'),
      ]);
      setDocsStatus(statusRes.data);
      setDocsConfig(configRes.data);
    } catch {
      // ignore
    }
  }, []);

  const triggerBuild = useCallback(async () => {
    if (!isSuperAdmin) return;
    setBuilding(true);
    setBuildResult(null);
    try {
      const res = await api.post<MkDocsBuildResult>('/docs/build');
      setBuildResult(res.data);
      setBuildTimestamp(new Date().toLocaleString());
      if (res.data.success) {
        messageApi.success(`Build succeeded in ${(res.data.duration / 1000).toFixed(1)}s`);
      } else {
        messageApi.error('Build failed');
      }
    } catch {
      messageApi.error('Build request failed');
    } finally {
      setBuilding(false);
    }
  }, [isSuperAdmin, messageApi]);

  useEffect(() => { checkStatus(); }, [checkStatus]);

  // --- Feature Toggle Handler ---

  const toggleFeature = useCallback((feature: string, enabled: boolean) => {
    setFeatures((prev) => {
      if (enabled) {
        return [...prev, feature];
      }
      return prev.filter((f) => f !== feature);
    });
    setSettingsDirty(true);
  }, []);

  // --- Nav Handlers ---

  const handleNavDrop: TreeProps['onDrop'] = useCallback((info: Parameters<NonNullable<TreeProps['onDrop']>>[0]) => {
    const dropKey = info.node.key as string;
    const dragKey = info.dragNode.key as string;
    const dropPos = info.node.pos.split('-');
    const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);

    setNavNodes((prev) => {
      const data = JSON.parse(JSON.stringify(prev)) as NavNode[];

      // Find and remove dragged node
      const dragNode = findNavNode(data, dragKey);
      if (!dragNode) return prev;
      const newData = removeNavNode(data, dragKey);

      // Find drop target
      const insertInto = (nodes: NavNode[]): boolean => {
        for (let i = 0; i < nodes.length; i++) {
          const node = nodes[i];
          if (!node) continue;
          if (node.id === dropKey) {
            if (!info.dropToGap && node.type === 'section') {
              // Drop into section
              if (!node.children) node.children = [];
              node.children.unshift(dragNode);
              return true;
            }
            if (dropPosition === -1) {
              nodes.splice(i, 0, dragNode);
              return true;
            }
            nodes.splice(i + 1, 0, dragNode);
            return true;
          }
          if (node.children && insertInto(node.children)) return true;
        }
        return false;
      };

      insertInto(newData);
      return newData;
    });
    setNavDirty(true);
  }, []);

  const openNavModal = useCallback((type: 'section' | 'page' | 'link', parentId: string | null = null) => {
    setNavModalType(type);
    setNavModalLabel('');
    setNavModalPath('');
    setNavModalParentId(parentId);
    setNavEditId(null);
    setNavModalOpen(true);
  }, []);

  const openNavEdit = useCallback((nodeId: string) => {
    const node = findNavNode(navNodes, nodeId);
    if (!node) return;
    setNavModalType(node.type);
    setNavModalLabel(node.label);
    setNavModalPath(node.path || '');
    setNavModalParentId(null);
    setNavEditId(nodeId);
    setNavModalOpen(true);
  }, [navNodes]);

  const handleNavModalOk = useCallback(() => {
    if (!navModalLabel.trim()) return;

    if (navEditId) {
      // Edit existing
      setNavNodes((prev) => {
        const data = JSON.parse(JSON.stringify(prev)) as NavNode[];
        const node = findNavNode(data, navEditId);
        if (node) {
          node.label = navModalLabel;
          node.path = navModalPath || undefined;
        }
        return data;
      });
    } else {
      // Add new
      const newNode: NavNode = {
        id: nextNavId(),
        label: navModalLabel,
        type: navModalType,
        path: navModalType !== 'section' ? navModalPath : undefined,
        children: navModalType === 'section' ? [] : undefined,
      };

      setNavNodes((prev) => {
        if (navModalParentId) {
          const data = JSON.parse(JSON.stringify(prev)) as NavNode[];
          const parent = findNavNode(data, navModalParentId);
          if (parent && parent.type === 'section') {
            if (!parent.children) parent.children = [];
            parent.children.push(newNode);
          }
          return data;
        }
        return [...prev, newNode];
      });
    }

    setNavDirty(true);
    setNavModalOpen(false);
  }, [navModalLabel, navModalPath, navModalType, navModalParentId, navEditId]);

  const deleteNavNode = useCallback((nodeId: string) => {
    setNavNodes((prev) => removeNavNode([...prev], nodeId));
    setNavDirty(true);
  }, []);

  /** Quick-add an orphaned file to the nav root */
  const addOrphanToNav = useCallback((filePath: string) => {
    // Derive a label from the filename: "blog/posts/1.md" → "1"
    const filename = filePath.split('/').pop() || filePath;
    const label = filename.replace(/\.md$/, '').replace(/[-_]/g, ' ');
    const newNode: NavNode = {
      id: nextNavId(),
      label,
      type: 'page',
      path: filePath,
    };
    setNavNodes((prev) => [...prev, newNode]);
    setNavDirty(true);
    messageApi.success(`Added "${label}" to navigation`);
  }, [messageApi]);

  /** Quick-add an orphaned file into a specific section */
  const addOrphanToSection = useCallback((filePath: string, sectionId: string) => {
    const filename = filePath.split('/').pop() || filePath;
    const label = filename.replace(/\.md$/, '').replace(/[-_]/g, ' ');
    const newNode: NavNode = {
      id: nextNavId(),
      label,
      type: 'page',
      path: filePath,
    };
    setNavNodes((prev) => {
      const data = JSON.parse(JSON.stringify(prev)) as NavNode[];
      const parent = findNavNode(data, sectionId);
      if (parent && parent.type === 'section') {
        if (!parent.children) parent.children = [];
        parent.children.push(newNode);
      }
      return data;
    });
    setNavDirty(true);
    messageApi.success(`Added "${label}" to section`);
  }, [messageApi]);

  /** Get section nodes for the "Add to section" dropdown */
  const sectionNodes = useMemo(() => {
    const sections: { id: string; label: string }[] = [];
    const collect = (nodes: NavNode[], prefix = '') => {
      for (const node of nodes) {
        if (node.type === 'section') {
          sections.push({ id: node.id, label: prefix + node.label });
          if (node.children) collect(node.children, prefix + node.label + ' / ');
        }
      }
    };
    collect(navNodes);
    return sections;
  }, [navNodes]);

  // --- Campaign links ---

  const campaignBaseUrl = useMemo(() => {
    const hostname = window.location.hostname;
    if (hostname.endsWith('.cmlite.org')) return 'https://app.cmlite.org';
    return window.location.origin;
  }, []);

  const navLinkUrls = useMemo(() => new Set(collectNavLinkUrls(navNodes)), [navNodes]);

  const addCampaignToNav = useCallback((campaign: Campaign) => {
    const newNode: NavNode = {
      id: nextNavId(),
      label: campaign.title,
      type: 'link',
      path: `${campaignBaseUrl}/campaign/${campaign.slug}`,
    };
    setNavNodes((prev) => [...prev, newNode]);
    setNavDirty(true);
    messageApi.success(`Added "${campaign.title}" to navigation`);
  }, [campaignBaseUrl, messageApi]);

  const addCampaignToSection = useCallback((campaign: Campaign, sectionId: string) => {
    const newNode: NavNode = {
      id: nextNavId(),
      label: campaign.title,
      type: 'link',
      path: `${campaignBaseUrl}/campaign/${campaign.slug}`,
    };
    setNavNodes((prev) => {
      const data = JSON.parse(JSON.stringify(prev)) as NavNode[];
      const parent = findNavNode(data, sectionId);
      if (parent && parent.type === 'section') {
        if (!parent.children) parent.children = [];
        parent.children.push(newNode);
      }
      return data;
    });
    setNavDirty(true);
    messageApi.success(`Added "${campaign.title}" to section`);
  }, [campaignBaseUrl, messageApi]);

  // --- Orphaned files ---

  const orphanedFiles = useMemo(() => {
    const allMdFiles = collectMdPaths(fileTree);
    const navPaths = collectNavPaths(navNodes);
    return allMdFiles.filter((f) => !navPaths.includes(f));
  }, [fileTree, navNodes]);

  // --- Available .md files for file picker ---
  const mdFiles = useMemo(() => collectMdPaths(fileTree), [fileTree]);

  // --- Render ---

  if (isMobile) {
    return (
      <Result status="info" title="Desktop Required" subTitle="MkDocs settings requires a desktop browser." />
    );
  }

  if (loading) {
    return <div style={{ textAlign: 'center', padding: 80 }}><Spin size="large" /></div>;
  }

  if (error) {
    return (
      <Result
        status="error"
        title="Cannot Load Config"
        subTitle="Failed to read mkdocs.yml. Make sure the API has access to the mkdocs directory."
        extra={<Button type="primary" onClick={loadConfig}>Retry</Button>}
      />
    );
  }

  const navTreeData = navNodesToTreeData(navNodes);

  return (
    <>
      {contextHolder}
      <Tabs
        defaultActiveKey="settings"
        items={[
          {
            key: 'settings',
            label: 'Settings',
            children: (
              <div style={{ maxWidth: 900 }}>
                <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: 16, gap: 8 }}>
                  <Button
                    type="primary"
                    icon={<SaveOutlined />}
                    onClick={saveSettings}
                    loading={settingsSaving}
                    disabled={!settingsDirty || !isSuperAdmin}
                  >
                    Save Settings
                  </Button>
                  <Tooltip title="Build static site">
                    <Button
                      icon={building ? <LoadingOutlined /> : <BuildOutlined />}
                      onClick={triggerBuild}
                      loading={building}
                      disabled={!isSuperAdmin}
                    >
                      Build
                    </Button>
                  </Tooltip>
                </div>
                <Card title="Site Info" size="small" style={{ marginBottom: 16 }}>
                  <Form
                    form={settingsForm}
                    layout="vertical"
                    onValuesChange={() => setSettingsDirty(true)}
                    size="small"
                  >
                    <Form.Item label="Site Name" name="site_name">
                      <Input />
                    </Form.Item>
                    <Form.Item label="Site Description" name="site_description">
                      <Input />
                    </Form.Item>
                    <Form.Item label="Site URL" name="site_url">
                      <Input />
                    </Form.Item>
                    <Form.Item label="Site Author" name="site_author">
                      <Input />
                    </Form.Item>
                  </Form>
                </Card>

                <Card title="Theme" size="small" style={{ marginBottom: 16 }}>
                  <Form
                    form={settingsForm}
                    layout="vertical"
                    onValuesChange={() => setSettingsDirty(true)}
                    size="small"
                  >
                    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 16 }}>
                      <Form.Item label="Primary Color" name="primary">
                        <Select options={MATERIAL_COLORS.map((c) => ({ label: c, value: c }))} />
                      </Form.Item>
                      <Form.Item label="Accent Color" name="accent">
                        <Select options={MATERIAL_COLORS.map((c) => ({ label: c, value: c }))} />
                      </Form.Item>
                      <Form.Item label="Color Scheme" name="scheme">
                        <Select options={[
                          { label: 'Slate (Dark)', value: 'slate' },
                          { label: 'Default (Light)', value: 'default' },
                        ]} />
                      </Form.Item>
                    </div>
                    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
                      <Form.Item label="Text Font" name="text_font">
                        <Input placeholder="e.g. Inter" />
                      </Form.Item>
                      <Form.Item label="Code Font" name="code_font">
                        <Input placeholder="e.g. JetBrains Mono" />
                      </Form.Item>
                    </div>
                    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
                      <Form.Item label="Logo Path" name="logo">
                        <Input placeholder="e.g. assets/logo.png" />
                      </Form.Item>
                      <Form.Item label="Favicon Path" name="favicon">
                        <Input placeholder="e.g. assets/favicon.png" />
                      </Form.Item>
                    </div>
                  </Form>
                </Card>

                <Card title="Feature Toggles" size="small" style={{ marginBottom: 16 }}>
                  {Object.entries(FEATURE_CATEGORIES).map(([category, featureList]) => (
                    <div key={category} style={{ marginBottom: 16 }}>
                      <Text strong style={{ display: 'block', marginBottom: 8 }}>{category}</Text>
                      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '4px 24px' }}>
                        {featureList.map((feature) => (
                          <div key={feature} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '4px 0' }}>
                            <Switch
                              size="small"
                              checked={features.includes(feature)}
                              onChange={(checked) => toggleFeature(feature, checked)}
                              disabled={!isSuperAdmin}
                            />
                            <Text style={{ fontSize: 13 }}>{feature}</Text>
                          </div>
                        ))}
                      </div>
                    </div>
                  ))}
                </Card>

                {isSuperAdmin && (
                  <Card
                    title={<span style={{ color: token.colorError }}>Danger Zone</span>}
                    style={{ marginTop: 24, borderColor: token.colorError }}
                    size="small"
                  >
                    <Space direction="vertical" style={{ width: '100%' }}>
                      <Typography.Text type="secondary">
                        Reset all documentation content to a baseline template. A backup is created automatically.
                        Preserved: header config, analytics tracking, hooks, assets, stylesheets, blog.
                      </Typography.Text>
                      <Button
                        danger
                        onClick={() => {
                          Modal.confirm({
                            title: 'Reset Documentation Site',
                            content: (
                              <div>
                                <p>This will reset all documentation content to a baseline template.</p>
                                <p><strong>Preserved:</strong> header config, analytics, hooks, assets, stylesheets, blog.</p>
                                <p><strong>Deleted:</strong> all custom content pages.</p>
                                <p>A backup will be created automatically.</p>
                              </div>
                            ),
                            okText: 'Reset Site',
                            okButtonProps: { danger: true },
                            onOk: async () => {
                              try {
                                const { data } = await api.post('/docs/reset');
                                message.success(`Site reset complete. ${data.filesReset} files reset, ${data.filesPreserved} preserved.`);
                              } catch {
                                message.error('Failed to reset documentation site');
                              }
                            },
                          });
                        }}
                      >
                        Reset Site to Baseline
                      </Button>
                    </Space>
                  </Card>
                )}

              </div>
            ),
          },
          {
            key: 'navigation',
            label: (
              <span>
                Navigation
                {orphanedFiles.length > 0 && (
                  <Badge count={orphanedFiles.length} size="small" style={{ marginLeft: 8 }} title={`${orphanedFiles.length} orphaned files`} />
                )}
              </span>
            ),
            children: (
              <div style={{ maxWidth: 900 }}>
                <Space style={{ marginBottom: 16 }}>
                  <Button icon={<PlusOutlined />} onClick={() => openNavModal('section')} disabled={!isSuperAdmin}>
                    Add Section
                  </Button>
                  <Button icon={<FileOutlined />} onClick={() => openNavModal('page')} disabled={!isSuperAdmin}>
                    Add Page
                  </Button>
                  <Button icon={<LinkOutlined />} onClick={() => openNavModal('link')} disabled={!isSuperAdmin}>
                    Add Link
                  </Button>
                </Space>

                {orphanedFiles.length > 0 && (
                  <Collapse
                    size="small"
                    style={{ marginBottom: 16 }}
                    items={[{
                      key: 'orphans',
                      label: (
                        <Space>
                          <WarningOutlined style={{ color: token.colorWarning }} />
                          <Text type="warning">
                            {orphanedFiles.length} file{orphanedFiles.length !== 1 ? 's' : ''} not in navigation
                          </Text>
                        </Space>
                      ),
                      children: (
                        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
                          {orphanedFiles.map((filePath) => {
                            const filename = filePath.split('/').pop() || filePath;
                            const sectionMenuItems = sectionNodes.map((s) => ({
                              key: s.id,
                              label: s.label,
                              onClick: () => addOrphanToSection(filePath, s.id),
                            }));
                            return (
                              <Dropdown
                                key={filePath}
                                disabled={!isSuperAdmin}
                                menu={{
                                  items: [
                                    { key: 'root', label: 'Add to root', onClick: () => addOrphanToNav(filePath) },
                                    ...(sectionNodes.length > 0 ? [{ type: 'divider' as const, key: 'div' }] : []),
                                    ...sectionMenuItems,
                                  ],
                                }}
                                trigger={['click']}
                              >
                                <Tooltip title={filePath} mouseEnterDelay={0.3}>
                                  <Tag
                                    style={{
                                      cursor: isSuperAdmin ? 'pointer' : 'default',
                                      margin: 0,
                                      opacity: isSuperAdmin ? 1 : 0.5,
                                    }}
                                    icon={<PlusOutlined />}
                                  >
                                    {filename.length > 30 ? filename.slice(0, 27) + '...' : filename}
                                  </Tag>
                                </Tooltip>
                              </Dropdown>
                            );
                          })}
                        </div>
                      ),
                    }]}
                  />
                )}

                {campaigns.length > 0 && (
                  <Collapse
                    size="small"
                    style={{ marginBottom: 16 }}
                    items={[{
                      key: 'campaigns',
                      label: (() => {
                        const addedCount = campaigns.filter((c) => navLinkUrls.has(`${campaignBaseUrl}/campaign/${c.slug}`)).length;
                        const availableCount = campaigns.length - addedCount;
                        return (
                          <Space>
                            <LinkOutlined style={{ color: token.colorPrimary }} />
                            <Text>
                              Campaign Links ({availableCount} available, {addedCount} added)
                            </Text>
                          </Space>
                        );
                      })(),
                      children: (
                        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
                          {campaigns.map((campaign) => {
                            const campaignUrl = `${campaignBaseUrl}/campaign/${campaign.slug}`;
                            const isAdded = navLinkUrls.has(campaignUrl);
                            if (isAdded) {
                              return (
                                <Tooltip key={campaign.id} title={`/campaign/${campaign.slug}`} mouseEnterDelay={0.3}>
                                  <Tag
                                    icon={<CheckCircleOutlined />}
                                    color="success"
                                    style={{ margin: 0, opacity: 0.5, cursor: 'default' }}
                                  >
                                    {campaign.title.length > 30 ? campaign.title.slice(0, 27) + '...' : campaign.title}
                                  </Tag>
                                </Tooltip>
                              );
                            }
                            const sectionMenuItems = sectionNodes.map((s) => ({
                              key: s.id,
                              label: s.label,
                              onClick: () => addCampaignToSection(campaign, s.id),
                            }));
                            return (
                              <Dropdown
                                key={campaign.id}
                                disabled={!isSuperAdmin}
                                menu={{
                                  items: [
                                    { key: 'root', label: 'Add to root', onClick: () => addCampaignToNav(campaign) },
                                    ...(sectionNodes.length > 0 ? [{ type: 'divider' as const, key: 'div' }] : []),
                                    ...sectionMenuItems,
                                  ],
                                }}
                                trigger={['click']}
                              >
                                <Tooltip title={`/campaign/${campaign.slug}`} mouseEnterDelay={0.3}>
                                  <Tag
                                    icon={<PlusOutlined />}
                                    color="processing"
                                    style={{
                                      cursor: isSuperAdmin ? 'pointer' : 'default',
                                      margin: 0,
                                      opacity: isSuperAdmin ? 1 : 0.5,
                                    }}
                                  >
                                    {campaign.title.length > 30 ? campaign.title.slice(0, 27) + '...' : campaign.title}
                                  </Tag>
                                </Tooltip>
                              </Dropdown>
                            );
                          })}
                        </div>
                      ),
                    }]}
                  />
                )}

                <Card size="small" style={{ marginBottom: 16 }}>
                  <style>{`
                    .mkdocs-nav-tree .ant-tree-treenode {
                      width: 100% !important;
                    }
                    .mkdocs-nav-tree .ant-tree-node-content-wrapper {
                      overflow: hidden !important;
                      flex: 1 !important;
                      min-width: 0 !important;
                    }
                    .mkdocs-nav-tree .ant-tree-draggable-icon {
                      flex-shrink: 0;
                    }
                  `}</style>
                  {navNodes.length === 0 ? (
                    <Text type="secondary">No navigation items. Add sections or pages above.</Text>
                  ) : (
                    <Tree
                      className="mkdocs-nav-tree"
                      treeData={navTreeData}
                      showIcon
                      draggable={isSuperAdmin ? { icon: <HolderOutlined style={{ color: token.colorTextQuaternary }} /> } : false}
                      blockNode
                      expandedKeys={expandedNavKeys}
                      onExpand={(keys) => setExpandedNavKeys(keys)}
                      defaultExpandAll
                      onDrop={handleNavDrop}
                      titleRender={(nodeData) => {
                        const nodeId = nodeData.key as string;
                        const node = findNavNode(navNodes, nodeId);
                        return (
                          <div style={{ display: 'flex', alignItems: 'center', gap: 4, width: '100%', minWidth: 0 }}>
                            <Tooltip
                              title={node?.path && node.path.length > 40 ? node.path : undefined}
                              mouseEnterDelay={0.5}
                              placement="topLeft"
                            >
                              <span style={{ flex: 1, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', display: 'block' }}>
                                <Text strong={node?.type === 'section'} style={{ fontSize: 13 }}>
                                  {nodeData.title as string}
                                </Text>
                                {node?.path && (
                                  <Text type="secondary" style={{ fontSize: 11, marginLeft: 8 }}>
                                    {node.path}
                                  </Text>
                                )}
                              </span>
                            </Tooltip>
                            {isSuperAdmin && (
                              <Space size={2} style={{ flexShrink: 0, marginLeft: 4 }}>
                                {node?.type === 'section' && (
                                  <Tooltip title="Add child">
                                    <Button
                                      type="text"
                                      size="small"
                                      icon={<PlusOutlined />}
                                      onClick={(e) => { e.stopPropagation(); openNavModal('page', nodeId); }}
                                      style={{ width: 24, height: 24 }}
                                    />
                                  </Tooltip>
                                )}
                                <Tooltip title="Edit">
                                  <Button
                                    type="text"
                                    size="small"
                                    icon={<EditOutlined />}
                                    onClick={(e) => { e.stopPropagation(); openNavEdit(nodeId); }}
                                    style={{ width: 24, height: 24 }}
                                  />
                                </Tooltip>
                                <Tooltip title="Delete">
                                  <Button
                                    type="text"
                                    size="small"
                                    danger
                                    icon={<DeleteOutlined />}
                                    onClick={(e) => { e.stopPropagation(); deleteNavNode(nodeId); }}
                                    style={{ width: 24, height: 24 }}
                                  />
                                </Tooltip>
                              </Space>
                            )}
                          </div>
                        );
                      }}
                    />
                  )}
                </Card>

                <div style={{ display: 'flex', justifyContent: 'flex-end', padding: '16px 0', gap: 8 }}>
                  <Button
                    type="primary"
                    icon={<SaveOutlined />}
                    onClick={saveNav}
                    loading={navSaving}
                    disabled={!navDirty || !isSuperAdmin}
                  >
                    Save Navigation
                  </Button>
                  <Tooltip title="Build static site">
                    <Button
                      icon={building ? <LoadingOutlined /> : <BuildOutlined />}
                      onClick={triggerBuild}
                      loading={building}
                      disabled={!isSuperAdmin}
                    >
                      Build
                    </Button>
                  </Tooltip>
                </div>

                {/* Nav Add/Edit Modal */}
                <Modal
                  title={navEditId ? 'Edit Item' : `Add ${navModalType.charAt(0).toUpperCase() + navModalType.slice(1)}`}
                  open={navModalOpen}
                  onOk={handleNavModalOk}
                  onCancel={() => setNavModalOpen(false)}
                  okText={navEditId ? 'Update' : 'Add'}
                  destroyOnHidden
                >
                  <Form layout="vertical" size="small">
                    <Form.Item label="Label">
                      <Input
                        value={navModalLabel}
                        onChange={(e) => setNavModalLabel(e.target.value)}
                        placeholder="Display name"
                        autoFocus
                      />
                    </Form.Item>
                    {navModalType === 'page' && (
                      <Form.Item label="File Path">
                        <Select
                          showSearch
                          value={navModalPath || undefined}
                          onChange={(v) => setNavModalPath(v)}
                          placeholder="Select a .md file"
                          options={mdFiles.map((f) => ({ label: f, value: f }))}
                          filterOption={(input, option) =>
                            (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
                          }
                        />
                      </Form.Item>
                    )}
                    {navModalType === 'link' && (
                      <Form.Item label="URL">
                        <Input
                          value={navModalPath}
                          onChange={(e) => setNavModalPath(e.target.value)}
                          placeholder="https://..."
                        />
                      </Form.Item>
                    )}
                  </Form>
                </Modal>
              </div>
            ),
          },
          {
            key: 'yaml',
            label: (
              <span>
                YAML Editor
                {editorDirty && <Badge status="warning" style={{ marginLeft: 8 }} />}
              </span>
            ),
            children: (
              <div style={{ height: 'calc(100vh - 64px - 46px - 48px)', display: 'flex', flexDirection: 'column' }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '8px 0', flexShrink: 0 }}>
                  <Space>
                    {editorDirty && <Text type="warning">Modified</Text>}
                  </Space>
                  <Space>
                    <Button
                      type="primary"
                      icon={<SaveOutlined />}
                      onClick={saveEditor}
                      loading={editorSaving}
                      disabled={!editorDirty || !isSuperAdmin}
                    >
                      Save (Ctrl+S)
                    </Button>
                    <Tooltip title="Build static site">
                      <Button
                        icon={building ? <LoadingOutlined /> : <BuildOutlined />}
                        onClick={triggerBuild}
                        loading={building}
                        disabled={!isSuperAdmin}
                      >
                        Build
                      </Button>
                    </Tooltip>
                  </Space>
                </div>
                <div style={{ flex: 1, minHeight: 0, border: `1px solid ${token.colorBorderSecondary}`, borderRadius: 4 }}>
                  <Editor
                    language="yaml"
                    theme="vs-dark"
                    value={editorYaml}
                    onChange={(value) => {
                      const v = value ?? '';
                      setEditorYaml(v);
                      setEditorDirty(v !== originalYaml);
                    }}
                    options={{
                      minimap: { enabled: false },
                      wordWrap: 'on',
                      lineNumbers: 'on',
                      fontSize: 14,
                      scrollBeyondLastLine: false,
                      automaticLayout: true,
                      tabSize: 2,
                    }}
                  />
                </div>
              </div>
            ),
          },
          {
            key: 'header',
            label: 'Header',
            children: (
              <div style={{ maxWidth: 600, padding: '24px 0' }}>
                <Result
                  status="info"
                  title="Navigation Moved"
                  subTitle="The app-wide navigation bar is now configured in Settings > Navigation. The MkDocs header is automatically generated from the centralized navigation configuration."
                  extra={
                    <Button
                      type="primary"
                      onClick={() => window.location.href = '/app/settings?activeTab=navigation'}
                    >
                      Go to Settings &gt; Navigation
                    </Button>
                  }
                />
              </div>
            ),
          },
          {
            key: 'build',
            label: 'Build',
            children: (
              <div style={{ maxWidth: 700 }}>
                <Card title="MkDocs Status" size="small" style={{ marginBottom: 16 }}>
                  <Space direction="vertical">
                    <Space>
                      <Text>Dev Server:</Text>
                      {docsStatus?.mkdocs.online ? (
                        <Badge status="success" text="Online" />
                      ) : (
                        <Badge status="error" text="Offline" />
                      )}
                    </Space>
                    <Space>
                      <Text>Static Site:</Text>
                      {docsStatus?.siteServer?.online ? (
                        <Badge status="success" text="Online" />
                      ) : (
                        <Badge status="error" text="Offline" />
                      )}
                    </Space>
                  </Space>
                </Card>

                <Card title="Static Site Build" size="small" style={{ marginBottom: 16 }}>
                  <Space direction="vertical" style={{ width: '100%' }}>
                    <Text type="secondary">
                      Build a static version of the documentation site. The dev server auto-reloads on file changes;
                      this is for generating production-ready static files.
                    </Text>
                    <Space>
                      <Button
                        type="primary"
                        icon={building ? <LoadingOutlined /> : <BuildOutlined />}
                        onClick={triggerBuild}
                        loading={building}
                        disabled={!isSuperAdmin}
                      >
                        Build Static Site
                      </Button>
                      <Button
                        type="link"
                        onClick={() => window.open(`//${window.location.hostname}:${docsConfig?.mkdocsSitePort ?? 4004}`, '_blank')}
                      >
                        Open Static Site
                      </Button>
                    </Space>
                    {buildResult && (
                      <>
                        <Space>
                          {buildResult.success ? (
                            <Text type="success"><CheckCircleOutlined /> Build succeeded</Text>
                          ) : (
                            <Text type="danger"><CloseCircleOutlined /> Build failed</Text>
                          )}
                          <Text type="secondary">({(buildResult.duration / 1000).toFixed(1)}s)</Text>
                          {buildTimestamp && <Text type="secondary">at {buildTimestamp}</Text>}
                        </Space>
                        <pre
                          style={{
                            background: '#1a1a2e',
                            color: '#e0e0e0',
                            padding: 16,
                            borderRadius: 6,
                            fontSize: 12,
                            fontFamily: 'monospace',
                            maxHeight: 400,
                            overflow: 'auto',
                            whiteSpace: 'pre-wrap',
                            wordBreak: 'break-all',
                            margin: 0,
                          }}
                        >
                          {buildResult.output}
                        </pre>
                      </>
                    )}
                  </Space>
                </Card>
              </div>
            ),
          },
        ]}
      />
    </>
  );
}
