<template>
  <div class="mcp-servers">
    <!-- 头部区域 -->
    <div class="header-section">
      <div class="header-content">
        <h3 class="title">MCP 服务器管理</h3>
        <p class="description">
          管理 MCP（Model Context Protocol）服务器配置。添加、编辑或删除 MCP 服务器以扩展 AI
          的能力。
        </p>
      </div>
      <a-button type="primary" @click="showAddModal" class="add-btn">
        <template #icon><PlusOutlined /></template>
        添加服务器
      </a-button>
    </div>

    <!-- 统计信息 -->
    <div class="stats-section" v-if="servers.length > 0">
      <span class="stats-text">
        已配置 {{ servers.length }} 个 MCP 服务器： HTTP: {{ httpCount }} · SSE: {{ sseCount }} ·
        StdIO: {{ stdioCount }}
      </span>
    </div>

    <!-- 主内容区域 -->
    <div class="content-section">
      <a-spin :spinning="loading">
        <div v-if="error" class="error-message">
          <a-alert type="error" :message="error" show-icon />
        </div>

        <div class="cards-container">
          <div v-if="servers.length === 0" class="empty-state">
            <a-empty description="暂无 MCP 服务器配置">
              <a-button type="primary" @click="showAddModal">添加服务器</a-button>
            </a-empty>
          </div>
          <div v-else class="server-cards-grid">
            <div
              v-for="server in servers"
              :key="server.name"
              class="server-card"
              :class="{ disabled: !server.enabled }"
            >
              <div class="card-header">
                <div class="server-info">
                  <span class="server-icon">{{ server.icon || '🔌' }}</span>
                  <div class="server-basic-info">
                    <h4 class="server-name" @click="showDetailModal(server)">{{ server.name }}</h4>
                    <div class="server-transport">
                      <a-tag size="small" class="transport-tag">
                        {{ server.transport }}
                      </a-tag>
                    </div>
                  </div>
                </div>
                <a-switch
                  :checked="server.enabled"
                  @change="handleToggleServer(server)"
                  :loading="toggleLoading === server.name"
                />
              </div>

              <div class="card-content">
                <div class="server-description">
                  {{ server.description || '暂无描述' }}
                </div>
              </div>

              <div class="card-actions">
                <a-tooltip title="查看详情">
                  <a-button
                    type="text"
                    size="small"
                    @click="showDetailModal(server)"
                    class="action-btn"
                  >
                    <EyeOutlined />
                    <span>详情</span>
                  </a-button>
                </a-tooltip>
                <a-tooltip title="测试连接">
                  <a-button
                    type="text"
                    size="small"
                    @click="handleTestServer(server)"
                    class="action-btn"
                    :loading="testLoading === server.name"
                  >
                    <ApiOutlined v-if="testLoading !== server.name" />
                    <span>测试</span>
                  </a-button>
                </a-tooltip>
                <a-tooltip title="编辑配置">
                  <a-button
                    type="text"
                    size="small"
                    @click="showEditModal(server)"
                    class="action-btn"
                  >
                    <EditOutlined />
                    <span>编辑</span>
                  </a-button>
                </a-tooltip>
                <a-tooltip
                  :title="server.created_by === 'system' ? '内置 MCP 无法删除' : '删除服务器'"
                >
                  <a-button
                    type="text"
                    size="small"
                    danger
                    :disabled="server.created_by === 'system'"
                    @click="confirmDeleteServer(server)"
                    class="action-btn"
                  >
                    <DeleteOutlined />
                    <span>删除</span>
                  </a-button>
                </a-tooltip>
              </div>
            </div>
          </div>
        </div>
      </a-spin>
    </div>

    <!-- 添加/编辑服务器模态框 -->
    <a-modal
      v-model:open="formModalVisible"
      :title="editMode ? '编辑 MCP 服务器' : '添加 MCP 服务器'"
      @ok="handleFormSubmit"
      :confirmLoading="formLoading"
      @cancel="formModalVisible = false"
      :maskClosable="false"
      width="560px"
      class="server-modal"
    >
      <!-- 模式切换 -->
      <div class="mode-switch">
        <a-radio-group v-model:value="formMode" button-style="solid" size="small">
          <a-radio-button value="form">表单模式</a-radio-button>
          <a-radio-button value="json">JSON 模式</a-radio-button>
        </a-radio-group>
      </div>

      <!-- 表单模式 -->
      <a-form v-if="formMode === 'form'" layout="vertical" class="server-form">
        <a-form-item label="服务器名称" required class="form-item">
          <a-input
            v-model:value="form.name"
            placeholder="请输入服务器名称（唯一标识）"
            :disabled="editMode"
          />
        </a-form-item>

        <a-form-item label="描述" class="form-item">
          <a-input v-model:value="form.description" placeholder="请输入服务器描述" />
        </a-form-item>

        <a-row :gutter="16">
          <a-col :span="12">
            <a-form-item label="传输类型" required class="form-item">
              <a-select v-model:value="form.transport">
                <a-select-option value="streamable_http">streamable_http</a-select-option>
                <a-select-option value="sse">sse</a-select-option>
                <a-select-option value="stdio">stdio</a-select-option>
              </a-select>
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item label="图标" class="form-item">
              <a-input v-model:value="form.icon" placeholder="输入 emoji，如 🧠" :maxlength="2" />
            </a-form-item>
          </a-col>
        </a-row>

        <!-- HTTP 类型 -->
        <template v-if="form.transport === 'streamable_http' || form.transport === 'sse'">
          <a-form-item label="服务器 URL" required class="form-item">
            <a-input v-model:value="form.url" placeholder="https://example.com/mcp" />
          </a-form-item>

          <a-form-item label="HTTP 请求头" class="form-item">
            <a-textarea
              v-model:value="form.headersText"
              placeholder='JSON 格式，如：{"Authorization": "Bearer xxx"}'
              :rows="3"
            />
          </a-form-item>

          <a-row :gutter="16">
            <a-col :span="12">
              <a-form-item label="HTTP 超时（秒）" class="form-item">
                <a-input-number
                  v-model:value="form.timeout"
                  :min="1"
                  :max="300"
                  style="width: 100%"
                />
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item label="SSE 读取超时（秒）" class="form-item">
                <a-input-number
                  v-model:value="form.sse_read_timeout"
                  :min="1"
                  :max="300"
                  style="width: 100%"
                />
              </a-form-item>
            </a-col>
          </a-row>
        </template>

        <!-- StdIO 类型 -->
        <template v-if="form.transport === 'stdio'">
          <a-form-item label="命令" required class="form-item">
            <a-input v-model:value="form.command" placeholder="例如：npx 或 /path/to/server" />
          </a-form-item>

          <a-form-item label="参数" class="form-item">
            <a-select
              v-model:value="form.args"
              mode="tags"
              placeholder="输入参数后回车添加，如：-m"
              style="width: 100%"
            />
          </a-form-item>
        </template>

        <a-form-item label="标签" class="form-item">
          <a-select
            v-model:value="form.tags"
            mode="tags"
            placeholder="输入标签后回车添加"
            style="width: 100%"
          />
        </a-form-item>
      </a-form>

      <!-- JSON 模式 -->
      <div v-else class="json-mode">
        <a-textarea
          v-model:value="jsonContent"
          :rows="15"
          placeholder='请输入 JSON 配置，格式如：
{
  "name": "my-server",
  "transport": "streamable_http",
  "url": "https://example.com/mcp",
  "description": "服务器描述",
  "headers": {"Authorization": "Bearer xxx"},
  "tags": ["工具", "AI"]
}'
          class="json-textarea"
        />
        <div class="json-actions">
          <a-button size="small" @click="formatJson">格式化</a-button>
          <a-button size="small" @click="parseJsonToForm">解析到表单</a-button>
        </div>
      </div>
    </a-modal>

    <!-- 服务器详情模态框 -->
    <McpServerDetailModal
      v-model:visible="detailModalVisible"
      :server="selectedServer"
      @update="handleServerUpdate"
    />
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { notification, Modal } from 'ant-design-vue'
import {
  PlusOutlined,
  EditOutlined,
  DeleteOutlined,
  EyeOutlined,
  ApiOutlined
} from '@ant-design/icons-vue'
import { mcpApi } from '@/apis/mcp_api'
import McpServerDetailModal from './McpServerDetailModal.vue'

// 状态
const loading = ref(false)
const error = ref(null)
const servers = ref([])
const toggleLoading = ref(null)
const testLoading = ref(null)

// 表单相关
const formModalVisible = ref(false)
const formLoading = ref(false)
const formMode = ref('form')
const editMode = ref(false)
const jsonContent = ref('')
const form = reactive({
  name: '',
  description: '',
  transport: 'streamable_http',
  url: '',
  command: '',
  args: [],
  headersText: '',
  timeout: null,
  sse_read_timeout: null,
  tags: [],
  icon: ''
})

// 详情模态框
const detailModalVisible = ref(false)
const selectedServer = ref(null)

// 计算属性
const httpCount = computed(
  () => servers.value.filter((s) => s.transport === 'streamable_http').length
)
const sseCount = computed(() => servers.value.filter((s) => s.transport === 'sse').length)
const stdioCount = computed(() => servers.value.filter((s) => s.transport === 'stdio').length)

// 获取服务器列表
const fetchServers = async () => {
  try {
    loading.value = true
    error.value = null
    const result = await mcpApi.getMcpServers()
    if (result.success) {
      servers.value = result.data || []
    } else {
      error.value = result.message || '获取服务器列表失败'
    }
  } catch (err) {
    console.error('获取服务器列表失败:', err)
    error.value = err.message || '获取服务器列表失败'
  } finally {
    loading.value = false
  }
}

// 显示添加模态框
const showAddModal = () => {
  editMode.value = false
  formMode.value = 'form'
  Object.assign(form, {
    name: '',
    description: '',
    transport: 'streamable_http',
    url: '',
    command: '',
    args: [],
    headersText: '',
    timeout: null,
    sse_read_timeout: null,
    tags: [],
    icon: ''
  })
  jsonContent.value = ''
  formModalVisible.value = true
}

// 显示编辑模态框
const showEditModal = (server) => {
  editMode.value = true
  formMode.value = 'form'
  Object.assign(form, {
    name: server.name,
    description: server.description || '',
    transport: server.transport,
    url: server.url || '',
    command: server.command || '',
    args: server.args || [],
    headersText: server.headers ? JSON.stringify(server.headers, null, 2) : '',
    timeout: server.timeout,
    sse_read_timeout: server.sse_read_timeout,
    tags: server.tags || [],
    icon: server.icon || ''
  })
  formModalVisible.value = true
}

// 显示详情模态框
const showDetailModal = (server) => {
  selectedServer.value = server
  detailModalVisible.value = true
}

// 处理表单提交
const handleFormSubmit = async () => {
  try {
    formLoading.value = true

    let data
    if (formMode.value === 'json') {
      try {
        data = JSON.parse(jsonContent.value)
      } catch {
        notification.error({ message: 'JSON 格式错误' })
        return
      }
    } else {
      // 解析 headers
      let headers = null
      if (form.headersText.trim()) {
        try {
          headers = JSON.parse(form.headersText)
        } catch {
          notification.error({ message: '请求头 JSON 格式错误' })
          return
        }
      }

      data = {
        name: form.name,
        description: form.description || null,
        transport: form.transport,
        url: form.url || null,
        command: form.command || null,
        args: form.args.length > 0 ? form.args : null,
        headers,
        timeout: form.timeout || null,
        sse_read_timeout: form.sse_read_timeout || null,
        tags: form.tags.length > 0 ? form.tags : null,
        icon: form.icon || null
      }
    }

    // 校验必填字段
    if (!data.name?.trim()) {
      notification.error({ message: '服务器名称不能为空' })
      return
    }
    if (!data.transport) {
      notification.error({ message: '请选择传输类型' })
      return
    }
    // HTTP 类型校验 URL
    if (['sse', 'streamable_http'].includes(data.transport)) {
      if (!data.url?.trim()) {
        notification.error({ message: 'HTTP 类型必须填写服务器 URL' })
        return
      }
    }
    // StdIO 类型校验 command
    if (data.transport === 'stdio') {
      if (!data.command?.trim()) {
        notification.error({ message: 'StdIO 类型必须填写命令' })
        return
      }
    }

    if (editMode.value) {
      const result = await mcpApi.updateMcpServer(data.name, data)
      if (result.success) {
        notification.success({ message: '服务器更新成功' })
      } else {
        notification.error({ message: result.message || '更新失败' })
        return
      }
    } else {
      const result = await mcpApi.createMcpServer(data)
      if (result.success) {
        notification.success({ message: '服务器创建成功' })
      } else {
        notification.error({ message: result.message || '创建失败' })
        return
      }
    }

    formModalVisible.value = false
    await fetchServers()
  } catch (err) {
    console.error('操作失败:', err)
    notification.error({ message: err.message || '操作失败' })
  } finally {
    formLoading.value = false
  }
}

// 切换服务器启用状态
const handleToggleServer = async (server) => {
  try {
    toggleLoading.value = server.name
    const result = await mcpApi.toggleMcpServer(server.name)
    if (result.success) {
      notification.success({ message: result.message })
      await fetchServers()
    } else {
      notification.error({ message: result.message || '操作失败' })
    }
  } catch (err) {
    console.error('切换状态失败:', err)
    notification.error({ message: err.message || '操作失败' })
  } finally {
    toggleLoading.value = null
  }
}

// 测试服务器连接
const handleTestServer = async (server) => {
  try {
    testLoading.value = server.name
    const result = await mcpApi.testMcpServer(server.name)
    if (result.success) {
      notification.success({ message: result.message })
    } else {
      notification.warning({ message: result.message || '连接失败' })
    }
  } catch (err) {
    console.error('测试连接失败:', err)
    notification.error({ message: err.message || '测试失败' })
  } finally {
    testLoading.value = null
  }
}

// 确认删除服务器
const confirmDeleteServer = (server) => {
  // system 创建的服务器不允许删除
  if (server.created_by === 'system') {
    notification.warning({
      message: '无法删除系统服务器',
      description: '系统内置的 MCP 服务器无法删除，如需停用可切换禁用开关。'
    })
    return
  }

  Modal.confirm({
    title: '确认删除服务器',
    content: `确定要删除服务器 "${server.name}" 吗？此操作不可撤销。`,
    okText: '删除',
    okType: 'danger',
    cancelText: '取消',
    async onOk() {
      try {
        const result = await mcpApi.deleteMcpServer(server.name)
        if (result.success) {
          notification.success({ message: '服务器删除成功' })
          await fetchServers()
        } else {
          notification.error({ message: result.message || '删除失败' })
        }
      } catch (err) {
        console.error('删除失败:', err)
        notification.error({ message: err.message || '删除失败' })
      }
    }
  })
}

// 处理服务器更新（来自详情模态框）
const handleServerUpdate = () => {
  fetchServers()
}

// 格式化 JSON
const formatJson = () => {
  try {
    const obj = JSON.parse(jsonContent.value)
    jsonContent.value = JSON.stringify(obj, null, 2)
  } catch {
    notification.error({ message: 'JSON 格式错误，无法格式化' })
  }
}

// 解析 JSON 到表单
const parseJsonToForm = () => {
  try {
    const obj = JSON.parse(jsonContent.value)
    Object.assign(form, {
      name: obj.name || '',
      description: obj.description || '',
      transport: obj.transport || 'streamable_http',
      url: obj.url || '',
      command: obj.command || '',
      args: obj.args || [],
      headersText: obj.headers ? JSON.stringify(obj.headers, null, 2) : '',
      timeout: obj.timeout || null,
      sse_read_timeout: obj.sse_read_timeout || null,
      tags: obj.tags || [],
      icon: obj.icon || ''
    })
    formMode.value = 'form'
    notification.success({ message: '已解析到表单' })
  } catch {
    notification.error({ message: 'JSON 格式错误' })
  }
}

// 初始化
onMounted(() => {
  fetchServers()
})
</script>

<style lang="less" scoped>
.mcp-servers {
  margin-top: 12px;
  min-height: 50vh;

  .header-section {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;

    .header-content {
      flex: 1;

      .description {
        font-size: 14px;
        color: var(--gray-600);
        margin: 0;
        line-height: 1.4;
        margin-bottom: 16px;
      }
    }
  }

  .stats-section {
    margin-bottom: 16px;

    .stats-text {
      font-size: 13px;
      color: var(--gray-600);
    }
  }

  .content-section {
    overflow: hidden;

    .error-message {
      padding: 16px 0;
    }

    .cards-container {
      .empty-state {
        padding: 60px 20px;
        text-align: center;
      }

      .server-cards-grid {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
        gap: 16px;

        .server-card {
          background: var(--gray-0);
          border: 1px solid var(--gray-150);
          border-radius: 8px;
          padding: 16px;
          transition: all 0.2s ease;
          box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);

          &:hover {
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
            border-color: var(--gray-200);
          }

          &.disabled {
            opacity: 0.6;
          }

          .card-header {
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
            margin-bottom: 12px;

            .server-info {
              display: flex;
              align-items: center;
              gap: 12px;

              .server-icon {
                font-size: 24px;
              }

              .server-basic-info {
                .server-name {
                  margin: 0 0 4px 0;
                  font-size: 15px;
                  font-weight: 600;
                  color: var(--gray-900);
                  cursor: pointer;
                  transition: color 0.2s ease;

                  &:hover {
                    color: var(--color-primary);
                  }
                }

                .server-transport {
                  .transport-tag {
                    background: var(--gray-100);
                    border: none;
                    color: var(--gray-600);
                    border-radius: 4px;
                  }
                }
              }
            }
          }

          .card-content {
            min-height: 44px;

            .server-description {
              font-size: 13px;
              color: var(--gray-600);
              line-height: 1.4;
              display: -webkit-box;
              -webkit-line-clamp: 2;
              line-clamp: 2;
              -webkit-box-orient: vertical;
              overflow: hidden;
              text-overflow: ellipsis;
            }
          }

          .card-actions {
            display: flex;
            justify-content: flex-end;
            gap: 6px;
            padding-top: 8px;
            border-top: 1px solid var(--gray-25);

            .action-btn {
              display: flex;
              align-items: center;
              gap: 4px;
              padding: 4px 8px;
              border-radius: 6px;
              transition: all 0.2s ease;
              font-size: 12px;

              span {
                font-size: 12px;
              }

              &:hover {
                background: var(--gray-25);
              }

              &.ant-btn-dangerous:hover {
                background: var(--gray-25);
                border-color: var(--color-error-500);
                color: var(--color-error-500);
              }
            }
          }
        }
      }
    }
  }
}

.server-modal {
  .mode-switch {
    margin-bottom: 16px;
    text-align: right;
  }

  .server-form {
    .form-item {
      margin-bottom: 16px;
    }
  }

  .json-mode {
    .json-textarea {
      font-family: 'Monaco', 'Consolas', monospace;
      font-size: 13px;
    }

    .json-actions {
      margin-top: 12px;
      display: flex;
      gap: 8px;
    }
  }
}
</style>
