// MCP Manager View - Redesigned with Sectioned Layout
// Comprehensive MCP management for Claude and Codex with clear section separation

// ============================================================
// CONSTANTS & CONFIGURATION
// ============================================================

const CCW_MCP_TOOLS = [
  { name: 'write_file', desc: 'Write/create files', core: true },
  { name: 'edit_file', desc: 'Edit/replace content', core: true },
  { name: 'codex_lens', desc: 'Code index & search', core: true },
  { name: 'smart_search', desc: 'Quick regex/NL search', core: true },
  { name: 'session_manager', desc: 'Workflow sessions', core: false },
  { name: 'generate_module_docs', desc: 'Generate docs', core: false },
  { name: 'update_module_claude', desc: 'Update CLAUDE.md', core: false },
  { name: 'cli_executor', desc: 'Gemini/Qwen/Codex CLI', core: false },
];

const MCP_CATEGORIES = [
  'Development Tools',
  'Data & APIs',
  'Files & Storage',
  'AI & ML',
  'DevOps',
  'Custom'
];

// Get currently enabled tools from installed config (Claude)
function getCcwEnabledTools() {
  const currentPath = projectPath;
  const projectData = mcpAllProjects[currentPath] || {};
  const ccwConfig = projectData.mcpServers?.['ccw-tools'];
  if (ccwConfig?.env?.CCW_ENABLED_TOOLS) {
    const val = ccwConfig.env.CCW_ENABLED_TOOLS;
    if (val.toLowerCase() === 'all') return CCW_MCP_TOOLS.map(t => t.name);
    return val.split(',').map(t => t.trim());
  }
  return CCW_MCP_TOOLS.filter(t => t.core).map(t => t.name);
}

// Get currently enabled tools from Codex config
function getCcwEnabledToolsCodex() {
  const ccwConfig = codexMcpServers?.['ccw-tools'];
  if (ccwConfig?.env?.CCW_ENABLED_TOOLS) {
    const val = ccwConfig.env.CCW_ENABLED_TOOLS;
    if (val.toLowerCase() === 'all') return CCW_MCP_TOOLS.map(t => t.name);
    return val.split(',').map(t => t.trim());
  }
  return CCW_MCP_TOOLS.filter(t => t.core).map(t => t.name);
}

// ============================================================
// MODAL DIALOG COMPONENT
// ============================================================

function showMcpEditorModal(options = {}) {
  const {
    mode = 'create',
    serverName = '',
    serverConfig = {},
    template = null,
    cliMode = currentCliMode, // 'claude' or 'codex'
    installTargets = cliMode === 'codex' ? ['codex'] : ['project', 'global']
  } = options;

  const isView = mode === 'view';
  const isEdit = mode === 'edit';
  const title = isView ? t('mcp.viewServer') : isEdit ? t('mcp.editServer') : t('mcp.createServer');

  const initialName = serverName || template?.name || '';
  const initialDesc = template?.description || '';
  const initialCategory = template?.category || 'Development Tools';
  const initialConfig = serverConfig || template?.serverConfig || {
    command: '',
    args: [],
    env: {},
    url: '',
    cwd: ''
  };

  const modalHtml = `
    <div class="fixed inset-0 bg-black/50 flex items-center justify-center z-50" id="mcpEditorModal" style="backdrop-filter: blur(4px);">
      <div class="bg-card border border-border rounded-xl shadow-2xl w-full max-w-3xl max-h-[90vh] overflow-hidden flex flex-col">
        <div class="flex items-center justify-between px-6 py-4 border-b border-border bg-gradient-to-r from-primary/5 to-transparent">
          <div class="flex items-center gap-3">
            <div class="w-10 h-10 rounded-lg bg-primary/10 flex items-center justify-center">
              <i data-lucide="${isView ? 'eye' : isEdit ? 'edit-3' : 'plus-circle'}" class="w-5 h-5 text-primary"></i>
            </div>
            <div>
              <h2 class="text-lg font-bold text-foreground">${title}</h2>
              <p class="text-xs text-muted-foreground">${cliMode === 'codex' ? 'Codex MCP Server' : 'Claude MCP Server'}</p>
            </div>
          </div>
          <button onclick="closeMcpEditorModal()" class="text-muted-foreground hover:text-foreground transition-colors">
            <i data-lucide="x" class="w-5 h-5"></i>
          </button>
        </div>

        <div class="flex-1 overflow-y-auto px-6 py-4">
          <div class="space-y-4 mb-6">
            <div>
              <label class="block text-sm font-medium text-foreground mb-1.5">${t('mcp.serverName')}</label>
              <input type="text" id="mcpModalName" value="${initialName}" ${isView ? 'disabled' : ''}
                     placeholder="my-mcp-server"
                     class="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/50 disabled:opacity-50 disabled:cursor-not-allowed" />
            </div>

            ${!isView && cliMode !== 'codex' ? `
            <div>
              <label class="block text-sm font-medium text-foreground mb-1.5">${t('mcp.description')} (${t('mcp.optional')})</label>
              <input type="text" id="mcpModalDesc" value="${initialDesc}" placeholder="Brief description"
                     class="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/50" />
            </div>
            ` : ''}
          </div>

          <div class="mb-4">
            <div class="flex items-center gap-2 border-b border-border">
              <button class="px-4 py-2 text-sm font-medium border-b-2 border-primary text-primary"
                      onclick="switchMcpServerType('stdio')" id="mcpTypeStdio" ${isView ? 'disabled' : ''}>
                <i data-lucide="terminal" class="w-4 h-4 inline mr-1.5"></i>
                STDIO (Command)
              </button>
              <button class="px-4 py-2 text-sm font-medium border-b-2 border-transparent text-muted-foreground hover:text-foreground"
                      onclick="switchMcpServerType('http')" id="mcpTypeHttp" ${isView ? 'disabled' : ''}>
                <i data-lucide="globe" class="w-4 h-4 inline mr-1.5"></i>
                HTTP (URL)
              </button>
            </div>
          </div>

          <div id="mcpStdioConfig" class="space-y-4">
            <div>
              <label class="block text-sm font-medium text-foreground mb-1.5">${t('mcp.command')}</label>
              <input type="text" id="mcpModalCommand" value="${initialConfig.command || ''}" ${isView ? 'disabled' : ''}
                     placeholder="node" class="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/50 disabled:opacity-50 disabled:cursor-not-allowed font-mono text-sm" />
            </div>
            <div>
              <label class="block text-sm font-medium text-foreground mb-1.5">${t('mcp.args')} (${t('mcp.optional')})</label>
              <textarea id="mcpModalArgs" ${isView ? 'disabled' : ''} rows="3" placeholder='["/path/to/server.js"]'
                        class="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/50 disabled:opacity-50 disabled:cursor-not-allowed font-mono text-sm">${JSON.stringify(initialConfig.args || [], null, 2)}</textarea>
            </div>
            <div>
              <label class="block text-sm font-medium text-foreground mb-1.5">${t('mcp.env')} (${t('mcp.optional')})</label>
              <textarea id="mcpModalEnv" ${isView ? 'disabled' : ''} rows="4" placeholder='{"API_KEY": "your-key"}'
                        class="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/50 disabled:opacity-50 disabled:cursor-not-allowed font-mono text-sm">${JSON.stringify(initialConfig.env || {}, null, 2)}</textarea>
            </div>
            <div>
              <label class="block text-sm font-medium text-foreground mb-1.5">${t('mcp.cwd')} (${t('mcp.optional')})</label>
              <input type="text" id="mcpModalCwd" value="${initialConfig.cwd || ''}" ${isView ? 'disabled' : ''}
                     placeholder="/path/to/working/directory" class="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/50 disabled:opacity-50 disabled:cursor-not-allowed font-mono text-sm" />
            </div>
          </div>

          <div id="mcpHttpConfig" class="space-y-4 hidden">
            <div>
              <label class="block text-sm font-medium text-foreground mb-1.5">${t('mcp.url')}</label>
              <input type="text" id="mcpModalUrl" value="${initialConfig.url || ''}" ${isView ? 'disabled' : ''}
                     placeholder="https://api.example.com/mcp" class="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/50 disabled:opacity-50 disabled:cursor-not-allowed font-mono text-sm" />
            </div>
            <div>
              <label class="block text-sm font-medium text-foreground mb-1.5">${t('mcp.httpHeaders')} (${t('mcp.optional')})</label>
              <textarea id="mcpModalHttpHeaders" ${isView ? 'disabled' : ''} rows="4" placeholder='{"Authorization": "Bearer token"}'
                        class="w-full px-3 py-2 bg-background border border-border rounded-lg text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/50 disabled:opacity-50 disabled:cursor-not-allowed font-mono text-sm">${JSON.stringify(initialConfig.http_headers || initialConfig.httpHeaders || {}, null, 2)}</textarea>
            </div>
          </div>

          ${!isView && cliMode !== 'codex' ? `
          <div class="mt-6 pt-6 border-t border-border">
            <label class="flex items-center gap-2 cursor-pointer">
              <input type="checkbox" id="mcpModalSaveTemplate" class="w-4 h-4 rounded border-border text-primary focus:ring-2 focus:ring-primary/50" />
              <span class="text-sm font-medium text-foreground">${t('mcp.saveAsTemplate')}</span>
            </label>
          </div>
          ` : ''}
        </div>

        <div class="flex items-center justify-between px-6 py-4 border-t border-border bg-muted/30">
          ${!isView ? `
          <div class="flex items-center gap-2">
            <span class="text-sm font-medium text-foreground">${t('mcp.installTo')}:</span>
            <select id="mcpModalTarget" class="px-3 py-1.5 bg-background border border-border rounded-lg text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-primary/50">
              ${installTargets.map(target => {
                const labels = {
                  project: 'Project (.mcp.json)',
                  global: 'Global (~/.claude.json)',
                  codex: 'Codex (~/.codex/config.toml)'
                };
                return `<option value="${target}">${labels[target]}</option>`;
              }).join('')}
            </select>
          </div>
          ` : '<div></div>'}

          <div class="flex items-center gap-2">
            <button onclick="closeMcpEditorModal()" class="px-4 py-2 text-sm font-medium text-foreground hover:bg-muted rounded-lg transition-colors">
              ${isView ? t('mcp.close') : t('mcp.cancel')}
            </button>
            ${!isView ? `
            <button onclick="saveMcpFromModal('${cliMode}')" class="px-4 py-2 text-sm font-medium bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors flex items-center gap-2">
              <i data-lucide="save" class="w-4 h-4"></i>
              ${isEdit ? t('mcp.update') : t('mcp.install')}
            </button>
            ` : ''}
          </div>
        </div>
      </div>
    </div>
  `;

  const existingModal = document.getElementById('mcpEditorModal');
  if (existingModal) existingModal.remove();
  document.body.insertAdjacentHTML('beforeend', modalHtml);
  if (typeof lucide !== 'undefined') lucide.createIcons();
  if (initialConfig.url) switchMcpServerType('http');
}

function switchMcpServerType(type) {
  const stdioConfig = document.getElementById('mcpStdioConfig');
  const httpConfig = document.getElementById('mcpHttpConfig');
  const stdioBtn = document.getElementById('mcpTypeStdio');
  const httpBtn = document.getElementById('mcpTypeHttp');

  if (type === 'stdio') {
    stdioConfig.classList.remove('hidden');
    httpConfig.classList.add('hidden');
    stdioBtn.classList.add('border-primary', 'text-primary');
    stdioBtn.classList.remove('border-transparent', 'text-muted-foreground');
    httpBtn.classList.remove('border-primary', 'text-primary');
    httpBtn.classList.add('border-transparent', 'text-muted-foreground');
  } else {
    stdioConfig.classList.add('hidden');
    httpConfig.classList.remove('hidden');
    httpBtn.classList.add('border-primary', 'text-primary');
    httpBtn.classList.remove('border-transparent', 'text-muted-foreground');
    stdioBtn.classList.remove('border-primary', 'text-primary');
    stdioBtn.classList.add('border-transparent', 'text-muted-foreground');
  }
}

function closeMcpEditorModal() {
  const modal = document.getElementById('mcpEditorModal');
  if (modal) modal.remove();
}

async function saveMcpFromModal(cliMode) {
  const name = document.getElementById('mcpModalName').value.trim();
  const desc = document.getElementById('mcpModalDesc')?.value.trim() || '';
  const target = document.getElementById('mcpModalTarget')?.value || (cliMode === 'codex' ? 'codex' : 'project');
  const saveAsTemplate = document.getElementById('mcpModalSaveTemplate')?.checked || false;

  if (!name) {
    showToast(t('mcp.error'), t('mcp.nameRequired'), 'error');
    return;
  }

  const isStdio = !document.getElementById('mcpStdioConfig').classList.contains('hidden');
  let serverConfig = {};

  if (isStdio) {
    const command = document.getElementById('mcpModalCommand').value.trim();
    if (!command) {
      showToast(t('mcp.error'), t('mcp.commandRequired'), 'error');
      return;
    }
    serverConfig.command = command;

    const argsText = document.getElementById('mcpModalArgs').value.trim();
    if (argsText) {
      try {
        serverConfig.args = JSON.parse(argsText);
        if (!Array.isArray(serverConfig.args)) throw new Error('Args must be an array');
      } catch (e) {
        showToast(t('mcp.error'), t('mcp.invalidArgsJson'), 'error');
        return;
      }
    }

    const envText = document.getElementById('mcpModalEnv').value.trim();
    if (envText) {
      try {
        serverConfig.env = JSON.parse(envText);
        if (typeof serverConfig.env !== 'object' || Array.isArray(serverConfig.env)) throw new Error('Env must be an object');
      } catch (e) {
        showToast(t('mcp.error'), t('mcp.invalidEnvJson'), 'error');
        return;
      }
    }

    const cwd = document.getElementById('mcpModalCwd').value.trim();
    if (cwd) serverConfig.cwd = cwd;
  } else {
    const url = document.getElementById('mcpModalUrl').value.trim();
    if (!url) {
      showToast(t('mcp.error'), t('mcp.urlRequired'), 'error');
      return;
    }
    serverConfig.url = url;

    const headersText = document.getElementById('mcpModalHttpHeaders').value.trim();
    if (headersText) {
      try {
        const headers = JSON.parse(headersText);
        if (typeof headers !== 'object' || Array.isArray(headers)) throw new Error('Headers must be an object');
        serverConfig.http_headers = headers;
      } catch (e) {
        showToast(t('mcp.error'), t('mcp.invalidHeadersJson'), 'error');
        return;
      }
    }
  }

  if (saveAsTemplate && cliMode !== 'codex') {
    try {
      await fetch('/api/mcp-templates', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name, description: desc, serverConfig, category: 'Custom' })
      });
    } catch (error) {
      console.error('Error saving template:', error);
    }
  }

  try {
    let endpoint = '';
    let body = {};

    if (cliMode === 'codex') {
      endpoint = '/api/codex-mcp-add';
      body = { serverName: name, serverConfig };
    } else {
      if (target === 'global') {
        endpoint = '/api/mcp-add-global-server';
        body = { serverName: name, serverConfig };
      } else {
        endpoint = '/api/mcp-copy-server';
        body = { projectPath, serverName: name, serverConfig, configType: 'mcp' };
      }
    }

    const res = await fetch(endpoint, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body)
    });

    const data = await res.json();

    if (data.success || data.serverName) {
      showToast(t('mcp.success'), t('mcp.serverInstalled'), 'success');
      closeMcpEditorModal();
      await loadMcpConfig();
      renderMcpManager();
    } else {
      showToast(t('mcp.error'), data.error || 'Installation failed', 'error');
    }
  } catch (error) {
    console.error('Error installing MCP server:', error);
    showToast(t('mcp.error'), error.message, 'error');
  }
}

// ============================================================
// MAIN RENDER FUNCTION
// ============================================================

async function renderMcpManager() {
  const container = document.getElementById('mainContent');
  if (!container) return;

  const statsGrid = document.getElementById('statsGrid');
  const searchInput = document.getElementById('searchInput');
  if (statsGrid) statsGrid.style.display = 'none';
  if (searchInput) searchInput.parentElement.style.display = 'none';

  if (!mcpConfig) await loadMcpConfig();
  await loadMcpTemplates();

  const currentPath = projectPath;
  const projectData = mcpAllProjects[currentPath] || {};
  const projectServers = projectData.mcpServers || {};
  const disabledServers = projectData.disabledMcpServers || [];
  const codexServers = codexMcpServers || {};
  const isClaude = currentCliMode === 'claude';

  // Section 1: Project Available (Enterprise + Global + Project-specific)
  const projectAvailable = [];

  if (isClaude) {
    // Enterprise servers
    for (const [name, config] of Object.entries(mcpEnterpriseServers || {})) {
      projectAvailable.push({ name, config, source: 'enterprise', enabled: true, canRemove: false, canToggle: false });
    }
    // Global servers
    for (const [name, config] of Object.entries(mcpUserServers || {})) {
      if (!mcpEnterpriseServers?.[name]) {
        projectAvailable.push({ name, config, source: 'global', enabled: !disabledServers.includes(name), canRemove: false, canToggle: true });
      }
    }
    // Project servers
    for (const [name, config] of Object.entries(projectServers)) {
      if (!mcpEnterpriseServers?.[name] && !mcpUserServers?.[name]) {
        projectAvailable.push({ name, config, source: 'project', enabled: !disabledServers.includes(name), canRemove: true, canToggle: true });
      }
    }
  } else {
    // Codex servers
    for (const [name, config] of Object.entries(codexServers)) {
      projectAvailable.push({ name, config, source: 'codex', enabled: config.enabled !== false, canRemove: true, canToggle: true });
    }
  }

  // Section 2: Global Management (for Claude only)
  const globalManagement = isClaude ? Object.entries(mcpUserServers || {}) : [];

  // Section 3: Other Projects (for Claude only)
  const allAvailableServers = isClaude ? getAllAvailableMcpServers() : {};
  const currentProjectServerNames = Object.keys(projectServers);
  const otherProjects = isClaude ? Object.entries(allAvailableServers).filter(([name, info]) => !currentProjectServerNames.includes(name) && !info.isGlobal) : [];

  // Section 4: Cross-CLI servers (Available from other CLI)
  const crossCliServers = [];
  if (isClaude) {
    // Show Codex servers when in Claude mode
    for (const [name, config] of Object.entries(codexServers)) {
      // Check if already exists in Claude (project or global)
      const existsInClaude = currentProjectServerNames.includes(name) || mcpUserServers?.[name];
      if (!existsInClaude) {
        crossCliServers.push({ name, config, fromCli: 'codex' });
      }
    }
  } else {
    // Show Claude servers when in Codex mode
    // Collect all Claude servers (global + project)
    const allClaudeServers = { ...mcpUserServers, ...projectServers };
    for (const [name, config] of Object.entries(allClaudeServers)) {
      // Check if already exists in Codex
      const existsInCodex = codexServers[name];
      if (!existsInCodex) {
        crossCliServers.push({ name, config, fromCli: 'claude' });
      }
    }
  }

  container.innerHTML = `
    <div class="mcp-manager">
      <!-- CLI Mode Toggle -->
      <div class="mcp-cli-toggle mb-6">
        <div class="flex items-center justify-between bg-card border border-border rounded-lg p-4">
          <div class="flex items-center gap-3">
            <span class="text-sm font-medium text-foreground">${t('mcp.cliMode')}</span>
            <div class="flex items-center bg-muted rounded-lg p-1">
              <button class="cli-mode-btn px-4 py-2 text-sm font-medium rounded-md transition-all ${isClaude ? 'bg-primary text-primary-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'}"
                      onclick="setCliMode('claude')">
                <i data-lucide="bot" class="w-4 h-4 inline mr-1.5"></i>
                Claude
              </button>
              <button class="cli-mode-btn px-4 py-2 text-sm font-medium rounded-md transition-all ${!isClaude ? 'shadow-sm' : 'text-muted-foreground hover:text-foreground'}"
                      onclick="setCliMode('codex')"
                      style="${!isClaude ? 'background-color: #f97316; color: white;' : ''}">
                <i data-lucide="code-2" class="w-4 h-4 inline mr-1.5"></i>
                Codex
              </button>
            </div>
          </div>
          <div class="flex items-center gap-3">
            <button onclick="renderMcpTemplates()" class="px-4 py-2 text-sm font-medium bg-muted hover:bg-muted/80 text-foreground rounded-lg transition-colors flex items-center gap-2">
              <i data-lucide="bookmark" class="w-4 h-4"></i>
              ${t('mcp.templates')}
            </button>
            <button onclick="showMcpEditorModal({ mode: 'create', cliMode: '${currentCliMode}' })"
                    class="px-4 py-2 text-sm font-medium ${isClaude ? 'bg-primary hover:bg-primary/90 text-primary-foreground' : 'bg-orange-500 hover:bg-orange-600 text-white'} rounded-lg transition-colors flex items-center gap-2">
              <i data-lucide="plus-circle" class="w-4 h-4"></i>
              ${t('mcp.newServer')}
            </button>
          </div>
        </div>
      </div>

      <!-- Section 1: Current Project Available -->
      <div class="mcp-section mb-6">
        <div class="flex items-center justify-between mb-4">
          <h2 class="text-lg font-semibold text-foreground flex items-center gap-2">
            <i data-lucide="folder-check" class="w-5 h-5"></i>
            ${isClaude ? t('mcp.projectAvailable') : 'Codex Global MCP Servers'}
            <span class="text-sm text-muted-foreground font-normal">(${projectAvailable.length})</span>
          </h2>
        </div>
        <div class="space-y-3">
          ${projectAvailable.length === 0 ? `
            <div class="bg-card border border-dashed border-border rounded-lg p-8 text-center">
              <i data-lucide="inbox" class="w-12 h-12 text-muted-foreground mx-auto mb-3"></i>
              <p class="text-sm text-muted-foreground">${isClaude ? t('mcp.noMcpServers') : 'No Codex MCP servers configured'}</p>
            </div>
          ` : projectAvailable.map(server => renderMcpServerCard(server, isClaude ? 'claude' : 'codex')).join('')}
        </div>
      </div>

      ${isClaude ? `
      <!-- Section 2: Global Management -->
      ${globalManagement.length > 0 ? `
      <div class="mcp-section mb-6">
        <div class="flex items-center justify-between mb-4">
          <h2 class="text-lg font-semibold text-foreground flex items-center gap-2">
            <i data-lucide="globe" class="w-5 h-5"></i>
            ${t('mcp.user')}
            <span class="text-sm text-muted-foreground font-normal">(${globalManagement.length})</span>
          </h2>
        </div>
        <div class="space-y-3">
          ${globalManagement.map(([name, config]) => renderMcpServerCard({ name, config, source: 'global-manage', enabled: true, canRemove: true, canToggle: false }, 'claude')).join('')}
        </div>
      </div>
      ` : ''}

      <!-- Section 3: Other Projects -->
      ${otherProjects.length > 0 ? `
      <div class="mcp-section mb-6">
        <div class="flex items-center justify-between mb-4">
          <h2 class="text-lg font-semibold text-foreground flex items-center gap-2">
            <i data-lucide="folder-open" class="w-5 h-5"></i>
            ${t('mcp.availableOther')}
            <span class="text-sm text-muted-foreground font-normal">(${otherProjects.length})</span>
          </h2>
        </div>
        <div class="space-y-3">
          ${otherProjects.map(([name, info]) => renderMcpServerCardAvailable(name, info)).join('')}
        </div>
      </div>
      ` : ''}

      <!-- Section 4: Cross-CLI Servers -->
      ${crossCliServers.length > 0 ? `
      <div class="mcp-section mb-6">
        <div class="flex items-center justify-between mb-4">
          <h2 class="text-lg font-semibold text-foreground flex items-center gap-2">
            ${isClaude ? `
              <i data-lucide="circle-dashed" class="w-5 h-5 text-orange-500"></i>
              ${t('mcp.claude.copyFromCodex')}
            ` : `
              <i data-lucide="circle" class="w-5 h-5 text-blue-500"></i>
              ${t('mcp.codex.copyFromClaude')}
            `}
            <span class="text-sm text-muted-foreground font-normal">(${crossCliServers.length})</span>
          </h2>
        </div>
        <div class="space-y-3">
          ${crossCliServers.map(server => renderCrossCliServerCard(server, isClaude)).join('')}
        </div>
      </div>
      ` : ''}
      ` : ''}
    </div>
  `;

  if (typeof lucide !== 'undefined') lucide.createIcons();
}

function renderMcpServerCard(server, cliMode) {
  const { name, config, source, enabled, canRemove, canToggle } = server;

  const sourceInfo = {
    enterprise: { icon: 'shield', color: 'purple', label: 'Enterprise' },
    global: { icon: 'globe', color: 'green', label: 'Global' },
    'global-manage': { icon: 'globe', color: 'green', label: 'Global' },
    project: { icon: 'folder', color: 'blue', label: 'Project' },
    codex: { icon: 'code-2', color: 'orange', label: 'Codex' }
  };

  const info = sourceInfo[source] || sourceInfo.project;
  const isStdio = !!config.command;
  const isHttp = !!config.url;

  return `
    <div class="bg-card border border-border rounded-lg p-4 hover:shadow-md transition-all ${!enabled ? 'opacity-60' : ''}">
      <div class="flex items-start justify-between gap-4">
        <div class="flex items-start gap-3 flex-1 min-w-0">
          <div class="shrink-0 w-10 h-10 rounded-lg bg-${info.color}-500/10 flex items-center justify-center">
            <i data-lucide="${info.icon}" class="w-5 h-5 text-${info.color}-500"></i>
          </div>
          <div class="flex-1 min-w-0">
            <div class="flex items-center gap-2 mb-1">
              <h3 class="font-semibold text-foreground truncate">${name}</h3>
              <span class="inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-${info.color}-500/10 text-${info.color}-600 dark:text-${info.color}-400">
                ${info.label}
              </span>
              ${enabled ? `
                <span class="inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-success/10 text-success">
                  <i data-lucide="check" class="w-3 h-3"></i>
                  Enabled
                </span>
              ` : `
                <span class="inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-muted text-muted-foreground">
                  <i data-lucide="x" class="w-3 h-3"></i>
                  Disabled
                </span>
              `}
            </div>
            <div class="text-sm text-muted-foreground space-y-1">
              ${isStdio ? `
                <div class="flex items-center gap-2">
                  <i data-lucide="terminal" class="w-3 h-3"></i>
                  <code class="text-xs">${config.command} ${(config.args || []).slice(0, 2).join(' ')}</code>
                </div>
              ` : ''}
              ${isHttp ? `
                <div class="flex items-center gap-2">
                  <i data-lucide="globe" class="w-3 h-3"></i>
                  <code class="text-xs truncate">${config.url}</code>
                </div>
              ` : ''}
            </div>
          </div>
        </div>
        <div class="flex items-center gap-2">
          ${canToggle ? `
            <button onclick="toggleMcpServer('${name}', '${cliMode}', ${!enabled})" class="p-2 rounded-lg hover:bg-muted transition-colors" title="${enabled ? 'Disable' : 'Enable'}">
              <i data-lucide="${enabled ? 'toggle-right' : 'toggle-left'}" class="w-4 h-4 text-${enabled ? 'success' : 'muted-foreground'}"></i>
            </button>
          ` : ''}
          <button onclick="showMcpEditorModal({ mode: 'view', serverName: '${name}', serverConfig: ${JSON.stringify(config).replace(/"/g, '&quot;')}, cliMode: '${cliMode}' })" class="p-2 rounded-lg hover:bg-muted transition-colors">
            <i data-lucide="eye" class="w-4 h-4 text-foreground"></i>
          </button>
          ${canRemove && source !== 'global-manage' ? `
            <button onclick="showMcpEditorModal({ mode: 'edit', serverName: '${name}', serverConfig: ${JSON.stringify(config).replace(/"/g, '&quot;')}, cliMode: '${cliMode}' })" class="p-2 rounded-lg hover:bg-muted transition-colors">
              <i data-lucide="edit-3" class="w-4 h-4 text-foreground"></i>
            </button>
          ` : ''}
          ${canRemove ? `
            <button onclick="deleteMcpServer('${name}', '${source}', '${cliMode}')" class="p-2 rounded-lg hover:bg-destructive/10 transition-colors">
              <i data-lucide="trash-2" class="w-4 h-4 text-destructive"></i>
            </button>
          ` : ''}
        </div>
      </div>
    </div>
  `;
}

function renderMcpServerCardAvailable(name, info) {
  return `
    <div class="bg-card border border-dashed border-border rounded-lg p-4 hover:shadow-md hover:border-solid transition-all">
      <div class="flex items-start justify-between gap-4">
        <div class="flex items-start gap-3 flex-1">
          <div class="shrink-0 w-10 h-10 rounded-lg bg-muted flex items-center justify-center">
            <i data-lucide="folder" class="w-5 h-5 text-muted-foreground"></i>
          </div>
          <div class="flex-1">
            <div class="flex items-center gap-2 mb-1">
              <h3 class="font-semibold text-foreground">${name}</h3>
              <span class="text-xs px-2 py-0.5 bg-muted rounded-full text-muted-foreground">${t('mcp.available')}</span>
            </div>
            <p class="text-xs text-muted-foreground">${t('mcp.from')} ${info.projectName || info.source}</p>
          </div>
        </div>
        <button onclick="installServerFromOther('${name}', ${JSON.stringify(info.config).replace(/"/g, '&quot;')})" class="px-3 py-1.5 text-sm font-medium bg-primary hover:bg-primary/90 text-primary-foreground rounded-lg transition-colors">
          ${t('mcp.addToProject')}
        </button>
      </div>
    </div>
  `;
}

function renderCrossCliServerCard(server, isClaude) {
  const { name, config, fromCli } = server;
  const isStdio = !!config.command;
  const isHttp = !!config.url;

  // Use solid circle for Claude, dashed circle for Codex
  const icon = fromCli === 'codex' ? 'circle-dashed' : 'circle';
  const iconColor = fromCli === 'codex' ? 'orange' : 'blue';
  const targetCli = isClaude ? 'project' : 'codex';
  const buttonText = isClaude ? t('mcp.codex.copyToClaude') : t('mcp.claude.copyToCodex');

  return `
    <div class="bg-card border border-dashed border-${iconColor}-200 dark:border-${iconColor}-800 rounded-lg p-4 hover:shadow-md hover:border-solid transition-all">
      <div class="flex items-start justify-between gap-4">
        <div class="flex items-start gap-3 flex-1 min-w-0">
          <div class="shrink-0 w-10 h-10 rounded-full bg-${iconColor}-50 dark:bg-${iconColor}-950/30 flex items-center justify-center">
            <i data-lucide="${icon}" class="w-5 h-5 text-${iconColor}-500"></i>
          </div>
          <div class="flex-1 min-w-0">
            <div class="flex items-center gap-2 mb-1">
              <h3 class="font-semibold text-foreground truncate">${name}</h3>
              <span class="inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full bg-${iconColor}-50 dark:bg-${iconColor}-950/30 text-${iconColor}-600 dark:text-${iconColor}-400">
                <i data-lucide="${icon}" class="w-3 h-3"></i>
                ${fromCli === 'codex' ? 'Codex' : 'Claude'}
              </span>
            </div>
            <div class="text-sm text-muted-foreground space-y-1">
              ${isStdio ? `
                <div class="flex items-center gap-2">
                  <i data-lucide="terminal" class="w-3 h-3"></i>
                  <code class="text-xs truncate">${config.command} ${(config.args || []).slice(0, 2).join(' ')}</code>
                </div>
              ` : ''}
              ${isHttp ? `
                <div class="flex items-center gap-2">
                  <i data-lucide="globe" class="w-3 h-3"></i>
                  <code class="text-xs truncate">${config.url}</code>
                </div>
              ` : ''}
            </div>
          </div>
        </div>
        <button onclick="copyCrossCliServer('${name}', ${JSON.stringify(config).replace(/"/g, '&quot;')}, '${fromCli}', '${targetCli}')" class="px-3 py-1.5 text-sm font-medium bg-${iconColor}-500 hover:bg-${iconColor}-600 text-white rounded-lg transition-colors flex items-center gap-1.5">
          <i data-lucide="copy" class="w-3.5 h-3.5"></i>
          ${buttonText}
        </button>
      </div>
    </div>
  `;
}

async function copyCrossCliServer(name, config, fromCli, targetCli) {
  try {
    let endpoint, body;

    if (targetCli === 'codex') {
      // Copy from Claude to Codex
      endpoint = '/api/codex-mcp-add';
      body = { serverName: name, serverConfig: config };
    } else if (targetCli === 'project') {
      // Copy from Codex to Claude project
      endpoint = '/api/mcp-copy-server';
      body = { projectPath, serverName: name, serverConfig: config, configType: 'mcp' };
    } else if (targetCli === 'global') {
      // Copy to Claude global
      endpoint = '/api/mcp-add-global-server';
      body = { serverName: name, serverConfig: config };
    }

    const res = await fetch(endpoint, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body)
    });

    const data = await res.json();
    if (data.success) {
      const targetName = targetCli === 'codex' ? 'Codex' : 'Claude';
      showToast(t('mcp.success'), `${t('mcp.serverInstalled')} (${targetName})`, 'success');
      await loadMcpConfig();
      renderMcpManager();
    } else {
      showToast(t('mcp.error'), data.error, 'error');
    }
  } catch (error) {
    showToast(t('mcp.error'), error.message, 'error');
  }
}

async function installServerFromOther(name, config) {
  try {
    const res = await fetch('/api/mcp-copy-server', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ projectPath, serverName: name, serverConfig: config, configType: 'mcp' })
    });
    const data = await res.json();
    if (data.success) {
      showToast(t('mcp.success'), t('mcp.serverInstalled'), 'success');
      await loadMcpConfig();
      renderMcpManager();
    } else {
      showToast(t('mcp.error'), data.error, 'error');
    }
  } catch (error) {
    showToast(t('mcp.error'), error.message, 'error');
  }
}

async function toggleMcpServer(serverName, cliMode, enable) {
  try {
    let endpoint = cliMode === 'codex' ? '/api/codex-mcp-toggle' : '/api/mcp-toggle';
    let body = cliMode === 'codex' ? { serverName, enabled: enable } : { projectPath, serverName, enable };

    const res = await fetch(endpoint, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body)
    });

    const data = await res.json();
    if (data.success || data.serverName) {
      showToast(t('mcp.success'), enable ? t('mcp.serverEnabled') : t('mcp.serverDisabled'), 'success');
      await loadMcpConfig();
      renderMcpManager();
    } else {
      showToast(t('mcp.error'), data.error, 'error');
    }
  } catch (error) {
    showToast(t('mcp.error'), error.message, 'error');
  }
}

async function deleteMcpServer(serverName, source, cliMode) {
  if (!confirm(`Are you sure you want to delete "${serverName}"?`)) return;

  try {
    let endpoint = '';
    let body = {};

    if (cliMode === 'codex') {
      endpoint = '/api/codex-mcp-remove';
      body = { serverName };
    } else if (source === 'global-manage') {
      endpoint = '/api/mcp-remove-global-server';
      body = { serverName };
    } else if (source === 'project') {
      endpoint = '/api/mcp-remove-server';
      body = { projectPath, serverName };
    } else {
      endpoint = '/api/mcp-remove-global-server';
      body = { serverName };
    }

    const res = await fetch(endpoint, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body)
    });

    const data = await res.json();
    if (data.success || data.removed) {
      showToast(t('mcp.success'), t('mcp.serverDeleted'), 'success');
      await loadMcpConfig();
      renderMcpManager();
    } else {
      showToast(t('mcp.error'), data.error, 'error');
    }
  } catch (error) {
    showToast(t('mcp.error'), error.message, 'error');
  }
}

async function renderMcpTemplates() {
  const container = document.getElementById('mainContent');
  if (!container) return;

  if (!mcpTemplates || mcpTemplates.length === 0) await loadMcpTemplates();
  const categories = [...new Set(mcpTemplates.map(t => t.category || 'Custom'))];

  container.innerHTML = `
    <div class="mcp-templates-view">
      <div class="flex items-center justify-between mb-6">
        <div>
          <button onclick="renderMcpManager()" class="text-sm text-primary hover:underline flex items-center gap-1 mb-2">
            <i data-lucide="arrow-left" class="w-4 h-4"></i>
            ${t('mcp.backToManager')}
          </button>
          <h1 class="text-2xl font-bold text-foreground">${t('mcp.templates')}</h1>
        </div>
      </div>
      <div class="space-y-6">
        ${categories.map(category => {
          const templates = mcpTemplates.filter(t => (t.category || 'Custom') === category);
          return `
            <div>
              <h2 class="text-lg font-semibold text-foreground mb-3">${category} (${templates.length})</h2>
              <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                ${templates.map(template => `
                  <div class="bg-card border border-border rounded-lg p-4 hover:shadow-md transition-all">
                    <h3 class="font-semibold text-foreground mb-2">${template.name}</h3>
                    <p class="text-sm text-muted-foreground mb-4">${template.description || 'No description'}</p>
                    <div class="flex gap-2">
                      <button onclick="showMcpEditorModal({ mode: 'create', template: ${JSON.stringify(template).replace(/"/g, '&quot;')} })" class="flex-1 px-3 py-2 text-sm bg-primary hover:bg-primary/90 text-primary-foreground rounded-lg">Install</button>
                      <button onclick="deleteTemplate('${template.name}')" class="px-3 py-2 text-sm bg-destructive/10 hover:bg-destructive/20 text-destructive rounded-lg">Delete</button>
                    </div>
                  </div>
                `).join('')}
              </div>
            </div>
          `;
        }).join('')}
      </div>
    </div>
  `;

  if (typeof lucide !== 'undefined') lucide.createIcons();
}

async function deleteTemplate(name) {
  if (!confirm(`Delete template "${name}"?`)) return;
  try {
    const res = await fetch(`/api/mcp-templates/${encodeURIComponent(name)}`, { method: 'DELETE' });
    const data = await res.json();
    if (data.success) {
      showToast(t('mcp.success'), t('mcp.templateDeleted'), 'success');
      await loadMcpTemplates();
      renderMcpTemplates();
    }
  } catch (error) {
    showToast(t('mcp.error'), error.message, 'error');
  }
}

function showToast(title, message, type = 'info') {
  console.log(`[${type.toUpperCase()}] ${title}: ${message}`);
  if (typeof window.showNotification === 'function') {
    window.showNotification(title, message, type);
  } else {
    alert(`${title}\n${message}`);
  }
}

async function loadMcpTemplates() {
  try {
    const res = await fetch('/api/mcp-templates');
    const data = await res.json();
    if (data.success) mcpTemplates = data.templates || [];
  } catch (error) {
    console.error('Error loading MCP templates:', error);
    mcpTemplates = [];
  }
}

window.renderMcpManager = renderMcpManager;
window.renderMcpTemplates = renderMcpTemplates;
window.showMcpEditorModal = showMcpEditorModal;
window.closeMcpEditorModal = closeMcpEditorModal;
window.saveMcpFromModal = saveMcpFromModal;
window.switchMcpServerType = switchMcpServerType;
window.toggleMcpServer = toggleMcpServer;
window.deleteMcpServer = deleteMcpServer;
window.deleteTemplate = deleteTemplate;
window.installServerFromOther = installServerFromOther;
