// 智能体配置工作台：智能体、模型服务商、运行时注册分区维护
import { useEffect, useMemo, useState } from 'react'
import {
  listProviders,
  updateProvider,
  setActiveProvider,
  testProvider,
  fetchProviderModels,
  listRuntimes,
  updateRuntime,
  setActiveRuntime,
  testRuntime,
  saveRuntimeAgent,
  listSkills,
} from '../services/api.js'
import { ProviderIcon } from '../components/ProviderIcon.jsx'

const RUNTIME_PROTOCOLS = ['agentrun', 'qoder-cloud-agent', 'local-cli']
const PURPOSE_LABELS = {
  create: 'AI 创建',
  evaluate: '评测',
  run: '运行',
  flowchart: 'AI 绘图',
  api: 'API 调用',
}

function isRuntimeProvider(p) {
  return RUNTIME_PROTOCOLS.includes(p?.protocol)
}

function hasAgentRunIntegrationUrl(p) {
  return !!String(p?.endpointPublicUrl || p?.baseUrl || '').trim()
}

function isQoderCloudAgent(p) {
  return p?.protocol === 'qoder-cloud-agent'
}

function runtimeKindLabel(p) {
  if (p?.protocol === 'agentrun') return 'AgentRun'
  if (p?.protocol === 'qoder-cloud-agent') return 'QODER Cloud Agent'
  if (p?.protocol === 'local-cli') return '本地 CLI'
  return p?.protocol || '运行时'
}

function emptyForm() {
  return {
    apiKey: '',
    baseUrl: '',
    defaultModel: '',
    enabled: false,
    accessKeyId: '',
    accessKeySecret: '',
    securityToken: '',
    accountId: '',
    regionId: 'cn-hangzhou',
    runtimeName: '',
    endpointName: 'default',
    runtimeId: '',
    endpointId: '',
    endpointPublicUrl: '',
    invocationKey: '',
  }
}

function Chip({ tone = 'gray', children }) {
  const map = {
    gray:   'bg-gray-100 text-gray-600',
    green:  'bg-emerald-100 text-emerald-700',
    blue:   'bg-blue-100 text-blue-700',
    amber:  'bg-amber-100 text-amber-700',
    rose:   'bg-rose-100 text-rose-700',
  }
  return (
    <span className={`inline-flex items-center px-2 py-0.5 rounded-full text-[11px] font-medium ${map[tone]}`}>
      {children}
    </span>
  )
}

export default function LlmSettings() {
  const [list, setList] = useState([])
  const [selected, setSelected] = useState(null)   // code
  const [form, setForm] = useState(emptyForm)
  const [showKey, setShowKey] = useState(false)
  const [saving, setSaving] = useState(false)
  const [testing, setTesting] = useState(false)
  const [testResult, setTestResult] = useState(null)
  const [tip, setTip] = useState('')
  const [dynamicModels, setDynamicModels] = useState([])
  const [loadingModels, setLoadingModels] = useState(false)
  const [modelsError, setModelsError] = useState('')
  const [runtimeList, setRuntimeList] = useState([])
  const [runtimeAgents, setRuntimeAgents] = useState([])
  const [runtimeTip, setRuntimeTip] = useState('')
  const [runtimeBusy, setRuntimeBusy] = useState('')
  const [activeConfigTab, setActiveConfigTab] = useState('agents')
  const [platformSkills, setPlatformSkills] = useState([])

  async function load(keepCode) {
    const { list } = await listProviders()
    const visibleList = list || []
    const modelList = visibleList.filter(p => !isRuntimeProvider(p))
    setList(visibleList)
    const code = (keepCode && modelList.some(p => p.code === keepCode))
      ? keepCode
      : (selected && modelList.some(p => p.code === selected))
        ? selected
        : (modelList.find(p => p.isActive) || modelList[0])?.code
    if (code) selectByCode(visibleList, code)
  }

  async function loadModels(code) {
    setLoadingModels(true)
    setModelsError('')
    try {
      const r = await fetchProviderModels(code)
      setDynamicModels(r.models || [])
      if (r.error) setModelsError(r.error)
    } catch (e) {
      setDynamicModels([])
      setModelsError(e.friendlyMessage || e.message || '拉取模型列表失败')
    } finally {
      setLoadingModels(false)
    }
  }

  function selectByCode(arr, code) {
    const p = arr.find(x => x.code === code)
    if (!p) return
    setSelected(code)
    setForm({
      ...emptyForm(),
      apiKey: '',
      baseUrl: p.baseUrl || '',
      defaultModel: p.defaultModel || '',
      enabled: !!p.enabled,
      accountId: p.accountId || '',
      regionId: p.regionId || 'cn-hangzhou',
      runtimeName: p.runtimeName || '',
      endpointName: p.endpointName || 'default',
      runtimeId: p.runtimeId || '',
      endpointId: p.endpointId || '',
      endpointPublicUrl: p.endpointPublicUrl || p.baseUrl || '',
      invocationKey: '',
    })
    setTestResult(null)
    setDynamicModels([])
    setModelsError('')
    if (p.hasKey) loadModels(code)
  }

  async function loadRuntimeRegistry() {
    try {
      const data = await listRuntimes()
      setRuntimeList(data.runtimes || [])
      setRuntimeAgents(data.agents || [])
    } catch (e) {
      setRuntimeTip(e.friendlyMessage || e.response?.data?.error || e.message || '运行时配置读取失败')
    }
  }

  async function loadPlatformSkills() {
    try {
      const data = await listSkills()
      setPlatformSkills(data.list || [])
    } catch {
      setPlatformSkills([])
    }
  }

  async function handleSaveRuntime(code, patch) {
    setRuntimeBusy(code)
    setRuntimeTip('')
    try {
      await updateRuntime(code, patch)
      await loadRuntimeRegistry()
      await load(current?.code)
      setRuntimeTip('运行时已保存')
    } catch (e) {
      setRuntimeTip(`保存失败：${e.response?.data?.error || e.friendlyMessage || e.message}`)
    } finally {
      setRuntimeBusy('')
      setTimeout(() => setRuntimeTip(''), 4000)
    }
  }

  async function handleSetActiveRuntime(code) {
    setRuntimeBusy(code)
    setRuntimeTip('')
    try {
      await setActiveRuntime(code)
      await loadRuntimeRegistry()
      await load(current?.code)
      setRuntimeTip('已设为当前运行时')
    } catch (e) {
      setRuntimeTip(`设置失败：${e.response?.data?.error || e.friendlyMessage || e.message}`)
    } finally {
      setRuntimeBusy('')
      setTimeout(() => setRuntimeTip(''), 4000)
    }
  }

  async function handleTestRuntime(code) {
    setRuntimeBusy(code)
    setRuntimeTip('')
    try {
      const res = await testRuntime(code)
      setRuntimeTip(res.ok ? `连通成功：${res.content || res.model || code}` : `连通失败：${res.message}`)
    } catch (e) {
      setRuntimeTip(`测试失败：${e.response?.data?.message || e.friendlyMessage || e.message}`)
    } finally {
      setRuntimeBusy('')
      setTimeout(() => setRuntimeTip(''), 6000)
    }
  }

  async function handleSaveAgent(id, patch) {
    setRuntimeBusy(id)
    setRuntimeTip('')
    try {
      await saveRuntimeAgent(id, patch)
      await loadRuntimeRegistry()
      setRuntimeTip('智能体已保存')
    } catch (e) {
      setRuntimeTip(`智能体保存失败：${e.response?.data?.error || e.friendlyMessage || e.message}`)
    } finally {
      setRuntimeBusy('')
      setTimeout(() => setRuntimeTip(''), 4000)
    }
  }

  useEffect(() => {
    load()
    loadRuntimeRegistry()
    loadPlatformSkills()
  }, [])

  const current = list.find(p => p.code === selected)
  const agentRunProvider = useMemo(() => runtimeList.find(p => p.protocol === 'agentrun') || list.find(p => p.protocol === 'agentrun') || null, [runtimeList, list])
  const activeRuntimeProvider = useMemo(
    () => runtimeList.find(p => isRuntimeProvider(p) && p.isActive && p.enabled) || list.find(p => isRuntimeProvider(p) && p.isActive && p.enabled) || null,
    [runtimeList, list]
  )
  const runtimeReady = !!(activeRuntimeProvider?.enabled && (activeRuntimeProvider.protocol === 'local-cli' ? activeRuntimeProvider.command : activeRuntimeProvider.ready))

  async function onSave() {
    if (!current) return
    if (current.protocol === 'agentrun') {
      const urlReady = !!form.endpointPublicUrl.trim()
      const invocationReady = current.hasInvocationKey || form.invocationKey.trim()
      const accessKeyReady = current.hasAccessKeyId || form.accessKeyId.trim()
      const secretReady = current.hasAccessKeySecret || form.accessKeySecret.trim()
      const missing = []
      if (urlReady && !invocationReady) missing.push('调用凭证')
      if (!urlReady && !accessKeyReady) missing.push('AccessKey ID 或集成 URL')
      if (!urlReady && !secretReady) missing.push('AccessKey Secret 或集成 URL')
      if (!urlReady && !form.accountId.trim()) missing.push('Account ID')
      if (!urlReady && !form.runtimeName.trim()) missing.push('Runtime 名称')
      if (form.enabled && missing.length) {
        setTip(`启用 AgentRun 前，请补齐：${missing.join('、')}`)
        setTimeout(() => setTip(''), 5000)
        return
      }
    }
    if (isQoderCloudAgent(current)) {
      const missing = []
      if (!(current.hasInvocationKey || form.invocationKey.trim() || form.apiKey.trim())) missing.push('PAT')
      if (!form.runtimeId.trim()) missing.push('Environment ID')
      if (!form.endpointId.trim()) missing.push('Agent ID')
      if (form.enabled && missing.length) {
        setTip(`启用 QODER Cloud Agent 前，请补齐：${missing.join('、')}`)
        setTimeout(() => setTip(''), 5000)
        return
      }
    }
    if (!isRuntimeProvider(current) && form.enabled && !current.hasKey && !form.apiKey?.trim()) {
      setTip('启用服务商前，请先填写并保存 API Key')
      setTimeout(() => setTip(''), 4000)
      return
    }
    if (!isRuntimeProvider(current) && !form.defaultModel?.trim()) {
      setTip('请填写默认模型')
      setTimeout(() => setTip(''), 3000)
      return
    }
    if (!isRuntimeProvider(current) && !form.baseUrl?.trim()) {
      setTip('请填写接口地址')
      setTimeout(() => setTip(''), 3000)
      return
    }
    setSaving(true); setTip('')
    try {
      const patch = {
        defaultModel: form.defaultModel,
        enabled: form.enabled,
      }
      if (current.protocol === 'agentrun') {
        Object.assign(patch, {
          accessKeyId: form.accessKeyId.trim(),
          accessKeySecret: form.accessKeySecret.trim(),
          securityToken: form.securityToken.trim(),
          invocationKey: form.invocationKey.trim(),
          accountId: form.accountId.trim(),
          regionId: form.regionId.trim() || 'cn-hangzhou',
          runtimeName: form.runtimeName.trim(),
          endpointName: form.endpointName.trim() || 'default',
          runtimeId: form.runtimeId.trim(),
          endpointId: form.endpointId.trim(),
          endpointPublicUrl: form.endpointPublicUrl.trim(),
        })
      } else if (isQoderCloudAgent(current)) {
        Object.assign(patch, {
          invocationKey: form.invocationKey.trim() || form.apiKey.trim(),
          runtimeId: form.runtimeId.trim(),
          endpointId: form.endpointId.trim(),
          endpointPublicUrl: form.endpointPublicUrl.trim(),
        })
      } else {
        patch.baseUrl = form.baseUrl
      }
      if (form.apiKey && form.apiKey.trim()) patch.apiKey = form.apiKey.trim()
      const res = await updateProvider(current.code, patch)
      if (res && res.error) {
        setTip(`保存失败：${res.error}`)
      } else {
        setTip('已保存')
        setForm(f => ({ ...f, apiKey: '', accessKeyId: '', accessKeySecret: '', securityToken: '', invocationKey: '' }))
        await load(current.code)
        loadModels(current.code)
      }
    } catch (e) {
      const msg = e.response?.data?.error || e.response?.data?.message || e.friendlyMessage || e.message
      setTip(`保存失败：${msg}`)
    } finally {
      setSaving(false)
      setTimeout(() => setTip(''), 4000)
    }
  }

  async function onSetActive() {
    if (!current) return
    if (current.protocol === 'agentrun') {
      if (!current.enabled) {
        setTip('请先保存并启用 AgentRun 后再设为运行时')
        setTimeout(() => setTip(''), 2500)
        return
      }
      if (current.missing?.length) {
        setTip(`请先补齐 AgentRun 配置：${current.missing.join('、')}`)
        setTimeout(() => setTip(''), 3500)
        return
      }
    } else if (isQoderCloudAgent(current)) {
      if (!current.enabled || current.missing?.length) {
        setTip(`请先补齐 QODER Cloud Agent 配置：${(current.missing || []).join('、')}`)
        setTimeout(() => setTip(''), 3500)
        return
      }
    } else if (!current.hasKey && !form.apiKey?.trim()) {
      setTip('请先填写并保存 API Key 后再设为激活')
      setTimeout(() => setTip(''), 2500)
      return
    }
    try {
      await setActiveProvider(current.code)
      setTip(isRuntimeProvider(current) ? '已设为当前运行时' : '已设为当前激活服务商')
      await load(current.code)
    } catch (e) {
      setTip(`设置失败：${e.response?.data?.message || e.message}`)
    } finally {
      setTimeout(() => setTip(''), 2500)
    }
  }

  async function onTest() {
    if (!current) return
    if (current.protocol === 'agentrun') {
      if (hasAgentRunIntegrationUrl(current) && !current.hasInvocationKey) {
        setTestResult({ ok: false, message: '请先保存 AgentRun 调用凭证后再测试' })
        return
      }
      if (!hasAgentRunIntegrationUrl(current) && (!current.hasAccessKeySecret || !current.hasAccessKeyId)) {
        setTestResult({ ok: false, message: '请先保存 AgentRun 集成 URL + 调用凭证，或 AccessKey 后再测试' })
        return
      }
    } else if (isQoderCloudAgent(current)) {
      if (!current.ready) {
        setTestResult({ ok: false, message: `请先补齐 QODER Cloud Agent 配置：${(current.missing || []).join('、')}` })
        return
      }
    } else if (!current.hasKey) {
      setTestResult({ ok: false, message: '请先保存 API Key 再测试' })
      return
    }
    setTesting(true); setTestResult(null)
    try {
      const r = await testProvider(current.code)
      setTestResult(r)
    } catch (e) {
      setTestResult({ ok: false, message: e.response?.data?.message || e.message })
    } finally {
      setTesting(false)
    }
  }

  return (
    <div className="h-full flex flex-col">
      <div className="px-6 py-4 border-b border-gray-200 bg-white">
        <div className="flex flex-wrap items-start justify-between gap-4">
          <div>
            <h1 className="text-lg font-semibold text-gray-900">智能体配置</h1>
            <p className="mt-1 text-xs text-gray-500">先定义智能体，再分别维护模型服务商和运行时注册。</p>
          </div>
          <div className="flex flex-wrap items-center gap-3">
            <div className="flex rounded-lg border border-gray-200 bg-gray-50 p-1">
              {[
                ['agents', '智能体配置'],
                ['models', '模型配置'],
                ['runtimes', '运行时注册'],
              ].map(([key, label]) => (
                <button
                  key={key}
                  type="button"
                  onClick={() => setActiveConfigTab(key)}
                  className={[
                    'h-8 px-3 rounded-md text-xs font-medium transition',
                    activeConfigTab === key ? 'bg-white text-brand-700 shadow-sm' : 'text-gray-500 hover:text-gray-900',
                  ].join(' ')}
                >
                  {label}
                </button>
              ))}
            </div>
            <Chip tone={runtimeReady ? 'green' : 'rose'}>{runtimeReady ? '运行时已就绪' : '运行时未就绪'}</Chip>
          </div>
        </div>
      </div>

      {activeConfigTab === 'models' ? (
      <div className="flex-1 flex min-h-0 bg-gray-50">
        {/* 左列：服务商卡片 */}
        <div className="w-72 border-r border-gray-200 bg-white overflow-y-auto">
          <div className="p-3 space-y-1.5">
            <div className="px-3 pt-2 pb-1 text-[10px] text-gray-400 font-medium uppercase tracking-wide">AI 模型</div>
            {list.filter(p => !isRuntimeProvider(p)).map(p => {
              const active = p.code === selected
              return (
                <button
                  key={p.code}
                  onClick={() => selectByCode(list, p.code)}
                  className={[
                    'w-full text-left px-3 py-2.5 rounded-lg border transition flex items-start gap-2.5',
                    active ? 'border-brand-500 bg-brand-50' : 'border-transparent hover:bg-gray-50',
                  ].join(' ')}
                >
                  <span className="mt-0.5 flex-shrink-0"><ProviderIcon code={p.code} size={22} /></span>
                  <span className="flex-1 min-w-0">
                    <span className="block text-sm font-medium text-gray-900 truncate">{p.name}</span>
                    <span className="mt-1 flex items-center gap-1 flex-wrap">
                      {p.isActive  && <Chip tone="blue">当前激活</Chip>}
                      {p.hasKey    && <Chip tone="green">已配置</Chip>}
                      {!p.hasKey   && <Chip tone="gray">未配置</Chip>}
                      {p.enabled && !p.isActive && <Chip tone="amber">已启用</Chip>}
                    </span>
                  </span>
                </button>
              )
            })}
          </div>
        </div>

        {/* 右侧：表单 */}
        <div className="flex-1 overflow-y-auto">
          {!current ? (
            <div className="h-full grid place-items-center text-gray-400 text-sm">请先选择左侧服务商</div>
          ) : (
            <div className="max-w-3xl mx-auto p-6 space-y-5">
              {/* 标题 */}
              <div className="flex items-center gap-3">
                <span className="flex-shrink-0"><ProviderIcon code={current.code} size={36} /></span>
                <div>
                  <div className="text-base font-semibold text-gray-900">{current.name}</div>
                  <div className="text-xs text-gray-500">协议：{current.protocol === 'anthropic' ? 'Anthropic' : isRuntimeProvider(current) ? runtimeKindLabel(current) : 'OpenAI 兼容'}</div>
                </div>
                <div className="ml-auto flex gap-1.5">
                  {current.isActive && <Chip tone="blue">{isRuntimeProvider(current) ? '当前运行时' : '当前激活'}</Chip>}
                  {current.hasKey   && <Chip tone="green">已配置 {current.keyPreview}</Chip>}
                  {current.protocol === 'agentrun' && hasAgentRunIntegrationUrl(current) && current.hasInvocationKey && <Chip tone="green">集成 URL 已配置</Chip>}
                  {current.protocol === 'agentrun' && current.hasAccessKeyId && <Chip tone="green">AK {current.accessKeyIdPreview}</Chip>}
                </div>
              </div>

              {current.protocol === 'agentrun' ? (
                <AgentRunFields
                  current={current}
                  form={form}
                  setForm={setForm}
                  showKey={showKey}
                  setShowKey={setShowKey}
                />
              ) : isQoderCloudAgent(current) ? (
                <QoderCloudAgentFields
                  current={current}
                  form={form}
                  setForm={setForm}
                  showKey={showKey}
                  setShowKey={setShowKey}
                />
              ) : (
                <Field label="API Key" hint={current.hasKey ? `已保存（${current.keyPreview}），重新输入可覆盖；留空保持不变` : '请到服务商控制台获取 API Key'}>
                  <div className="relative">
                    <input
                      type={showKey ? 'text' : 'password'}
                      value={form.apiKey}
                      onChange={e => setForm({ ...form, apiKey: e.target.value })}
                      placeholder={current.code === 'claude' ? 'sk-ant-xxxx' : 'sk-xxxx'}
                      className="w-full h-10 px-3 pr-20 rounded-lg border border-gray-300 text-sm focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-brand-500"
                    />
                    <button
                      type="button"
                      onClick={() => setShowKey(s => !s)}
                      className="absolute right-2 top-1/2 -translate-y-1/2 text-xs text-gray-500 hover:text-gray-800 px-2 py-1"
                    >
                      {showKey ? '隐藏' : '显示'}
                    </button>
                  </div>
                </Field>
              )}

              {/* 默认模型 */}
              {!isRuntimeProvider(current) && <Field label="默认模型" hint="Skill 未指定模型时使用">
                {loadingModels ? (
                  <div className="w-full h-10 px-3 rounded-lg border border-gray-300 flex items-center text-sm text-gray-400">
                    正在获取模型列表...
                  </div>
                ) : (dynamicModels.length > 0 || current.models?.length) ? (
                  <select
                    value={form.defaultModel}
                    onChange={e => setForm({ ...form, defaultModel: e.target.value })}
                    className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm focus:outline-none focus:ring-2 focus:ring-brand-500"
                  >
                    {(dynamicModels.length > 0 ? dynamicModels : current.models).map(m => (
                      <option key={m.value} value={m.value}>{m.label}</option>
                    ))}
                  </select>
                ) : (
                  <input
                    value={form.defaultModel}
                    onChange={e => setForm({ ...form, defaultModel: e.target.value })}
                    placeholder="如：gpt-4o-mini"
                    className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm focus:outline-none focus:ring-2 focus:ring-brand-500"
                  />
                )}
                {modelsError && <p className="mt-1 text-[11px] text-amber-600">⚠️ 动态拉取失败：{modelsError}（已回退到静态列表）</p>}
              </Field>}

              {/* 接口地址（高级） */}
              {!isRuntimeProvider(current) && (
                <details className="group">
                  <summary className="cursor-pointer text-xs text-gray-500 hover:text-gray-800 select-none">
                    高级设置（自定义接口地址）
                  </summary>
                  <div className="mt-3">
                    <Field label="Endpoint URL" hint={current.protocol === 'anthropic' ? '通常为 https://api.anthropic.com/v1/messages' : 'OpenAI 兼容的 chat completions 完整地址'}>
                      <input
                        value={form.baseUrl}
                        onChange={e => setForm({ ...form, baseUrl: e.target.value })}
                        className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
                      />
                    </Field>
                  </div>
                </details>
              )}
              {current.protocol === 'agentrun' && (
                <div className="text-[11px] text-gray-500">
                  AgentRun 调用方式：后端按控制台集成 URL 直连 OpenAI 兼容接口，并自动携带 <code className="font-mono">x-agentrun-session-id</code>。
                </div>
              )}
              {isQoderCloudAgent(current) && (
                <div className="text-[11px] text-gray-500">
                  QODER Cloud Agent 调用方式：后端使用 PAT 创建云端会话，按 Environment ID + Agent ID 进入指定运行环境。
                </div>
              )}

              {/* 启用开关 */}
              <div className="flex items-center justify-between p-3 rounded-lg bg-gray-50 border border-gray-100">
                <div>
                  <div className="text-sm font-medium text-gray-900">{isRuntimeProvider(current) ? '启用此执行内核' : '启用此服务商'}</div>
                  <div className="text-xs text-gray-500">
                    {current.protocol === 'agentrun'
                        ? '关闭后 Skill 创建、评测、运行和 API 调用不会进入 AgentRun'
                        : isQoderCloudAgent(current)
                          ? '关闭后 Skill 创建、评测和运行不会进入 QODER Cloud Agent'
                        : '关闭后即使被设为激活也无法调用'}
                  </div>
                </div>
                <button
                  onClick={() => setForm({ ...form, enabled: !form.enabled })}
                  className={[
                    'relative w-11 h-6 rounded-full transition',
                    form.enabled ? 'bg-brand-600' : 'bg-gray-300',
                  ].join(' ')}
                >
                  <span className={[
                    'absolute top-0.5 left-0.5 w-5 h-5 rounded-full bg-white shadow transition-transform',
                    form.enabled ? 'translate-x-5' : 'translate-x-0',
                  ].join(' ')} />
                </button>
              </div>

              {/* 操作 */}
              <div className="flex flex-wrap items-center gap-2 pt-2">
                <button
                  onClick={onSave}
                  disabled={saving}
                  className="h-9 px-4 rounded-lg bg-brand-600 text-white text-sm font-medium hover:bg-brand-700 disabled:opacity-60"
                >
                  {saving ? '保存中…' : '保存'}
                </button>
                <button
                  onClick={onTest}
                  disabled={testing || (isRuntimeProvider(current) ? !current.ready : !current.hasKey)}
                  className="h-9 px-4 rounded-lg border border-gray-300 text-sm text-gray-700 hover:bg-gray-50 disabled:opacity-50"
                >
                  {testing ? '测试中…' : '测试连通'}
                </button>
                <button
                  onClick={onSetActive}
                  disabled={current.isActive || (isRuntimeProvider(current) ? !current.enabled : !current.hasKey)}
                  className="h-9 px-4 rounded-lg border border-brand-200 bg-brand-50 text-sm text-brand-700 hover:bg-brand-100 disabled:opacity-50"
                  title={current.protocol === 'agentrun' ? '请先保存并启用 AgentRun' : !current.hasKey ? '请先填写并保存 API Key' : ''}
                >
                  {current.isActive ? (isRuntimeProvider(current) ? '已是当前运行时' : '已是当前激活') : (isRuntimeProvider(current) ? '设为当前运行时' : '设为当前激活')}
                </button>
                {tip && <span className="text-xs text-gray-600 ml-2">{tip}</span>}
              </div>

              {/* 测试结果 */}
              {testResult && (
                <div className={[
                  'mt-2 text-xs rounded-lg p-3 border',
                  testResult.ok ? 'bg-emerald-50 border-emerald-200 text-emerald-800' : 'bg-rose-50 border-rose-200 text-rose-800',
                ].join(' ')}>
                  {testResult.ok
                    ? <>✅ 连通成功 · 模型 <code className="font-mono">{testResult.model}</code> · {testResult.latencyMs}ms · 回复：{testResult.content}</>
                    : <>❌ 连通失败：{testResult.message}</>
                  }
                </div>
              )}
            </div>
          )}
        </div>
      </div>
      ) : (
        <div className="flex-1 overflow-y-auto bg-gray-50">
          <div className="mx-auto max-w-5xl p-6 space-y-5">
            {activeConfigTab === 'agents' ? (
              <>
                <RuntimeRegistryPanel
                  view="agents"
                  runtimes={runtimeList}
                  agents={runtimeAgents}
                  busyKey={runtimeBusy}
                  message={runtimeTip}
                  skills={platformSkills}
                  onSaveRuntime={handleSaveRuntime}
                  onSetActive={handleSetActiveRuntime}
                  onTestRuntime={handleTestRuntime}
                  onSaveAgent={handleSaveAgent}
                />
                <RuntimeReadinessPanel
                  agentRun={agentRunProvider}
                  activeRuntime={activeRuntimeProvider}
                  onSelect={() => setActiveConfigTab('runtimes')}
                />
              </>
            ) : (
              <RuntimeRegistryPanel
                view="runtimes"
                runtimes={runtimeList}
                agents={runtimeAgents}
                busyKey={runtimeBusy}
                message={runtimeTip}
                skills={platformSkills}
                onSaveRuntime={handleSaveRuntime}
                onSetActive={handleSetActiveRuntime}
                onTestRuntime={handleTestRuntime}
                onSaveAgent={handleSaveAgent}
              />
            )}
          </div>
        </div>
      )}
    </div>
  )
}

function AgentRunFields({ current, form, setForm, showKey, setShowKey }) {
  return (
    <div className="space-y-4">
      <Field label="AgentRun 集成 URL" hint="粘贴 AgentRun 控制台给出的 OpenAI 兼容 chat/completions 地址；模型已在 AgentRun 内部选择时，优先使用这个地址直连">
        <input
          value={form.endpointPublicUrl}
          onChange={e => setForm({ ...form, endpointPublicUrl: e.target.value })}
          placeholder="https://...agentrun-data.cn-hangzhou.aliyuncs.com/agent-runtimes/.../chat/completions"
          className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
        />
      </Field>

      <Field label="调用凭证" hint={current.hasInvocationKey ? `已保存（${current.invocationKeyPreview}），重新输入可覆盖；留空保持不变` : '用于 Authorization: Bearer；保存后只在后端持久化，前端不回显明文'}>
        <div className="relative">
          <input
            type={showKey ? 'text' : 'password'}
            value={form.invocationKey}
            onChange={e => setForm({ ...form, invocationKey: e.target.value })}
            placeholder="ak_..."
            className="w-full h-10 px-3 pr-20 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
          />
          <button
            type="button"
            onClick={() => setShowKey(s => !s)}
            className="absolute right-2 top-1/2 -translate-y-1/2 text-xs text-gray-500 hover:text-gray-800 px-2 py-1"
          >
            {showKey ? '隐藏' : '显示'}
          </button>
        </div>
      </Field>

      <div className="grid gap-4 md:grid-cols-2">
        <Field label="Runtime 名称" hint="填写集成 URL 后会由后端自动解析；也可以手动确认">
          <input
            value={form.runtimeName}
            onChange={e => setForm({ ...form, runtimeName: e.target.value })}
            placeholder="AIPRO-SP"
            className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
          />
        </Field>
        <Field label="Endpoint 名称" hint="你的集成信息里是 Default">
          <input
            value={form.endpointName}
            onChange={e => setForm({ ...form, endpointName: e.target.value })}
            placeholder="Default"
            className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
          />
        </Field>
      </div>

      <div className="grid gap-4 md:grid-cols-2">
        <Field label="Account ID" hint="阿里云主账号 ID，用于 AgentRun SDK 定位账号资源">
          <input
            value={form.accountId}
            onChange={e => setForm({ ...form, accountId: e.target.value })}
            placeholder="如：1234567890"
            className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
          />
        </Field>
        <Field label="Region" hint="默认 cn-hangzhou；请和 AgentRun Runtime 所在地域一致">
          <input
            value={form.regionId}
            onChange={e => setForm({ ...form, regionId: e.target.value })}
            placeholder="cn-hangzhou"
            className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
          />
        </Field>
      </div>

      <details>
        <summary className="cursor-pointer text-xs text-gray-500 hover:text-gray-800 select-none">
          高级备用：AccessKey / 资源 ID
        </summary>
        <div className="mt-3 space-y-4">
          <div className="grid gap-4 md:grid-cols-2">
            <Field label="AccessKey ID" hint={current.hasAccessKeyId ? `已保存（${current.accessKeyIdPreview}），重新输入可覆盖；留空保持不变` : '仅当你不用集成 URL、改走 SDK 调用时才需要'}>
              <input
                value={form.accessKeyId}
                onChange={e => setForm({ ...form, accessKeyId: e.target.value })}
                placeholder="LTAI..."
                className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
              />
            </Field>
            <Field label="AccessKey Secret" hint={current.hasAccessKeySecret ? `已保存（${current.keyPreview}），重新输入可覆盖；留空保持不变` : '保存后只在后端持久化，前端不会再次拿到明文'}>
              <div className="relative">
                <input
                  type={showKey ? 'text' : 'password'}
                  value={form.accessKeySecret}
                  onChange={e => setForm({ ...form, accessKeySecret: e.target.value })}
                  placeholder="AccessKey Secret"
                  className="w-full h-10 px-3 pr-20 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
                />
                <button
                  type="button"
                  onClick={() => setShowKey(s => !s)}
                  className="absolute right-2 top-1/2 -translate-y-1/2 text-xs text-gray-500 hover:text-gray-800 px-2 py-1"
                >
                  {showKey ? '隐藏' : '显示'}
                </button>
              </div>
            </Field>
          </div>

          <Field label="STS Security Token（可选）" hint={current.hasSecurityToken ? '已保存临时令牌，重新输入可覆盖；长期 AK 可留空' : '使用 STS 临时凭证时填写；长期 AccessKey 可不填'}>
            <input
              type={showKey ? 'text' : 'password'}
              value={form.securityToken}
              onChange={e => setForm({ ...form, securityToken: e.target.value })}
              placeholder="可选"
              className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
            />
          </Field>

          <div className="grid gap-4 md:grid-cols-2">
            <Field label="Runtime ID" hint="已有资源时可记录，便于后续更新和排障">
              <input
                value={form.runtimeId}
                onChange={e => setForm({ ...form, runtimeId: e.target.value })}
                className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
              />
            </Field>
            <Field label="Endpoint ID" hint="已有资源时可记录，便于后续更新和排障">
              <input
                value={form.endpointId}
                onChange={e => setForm({ ...form, endpointId: e.target.value })}
                className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
              />
            </Field>
          </div>
        </div>
      </details>
    </div>
  )
}

function QoderCloudAgentFields({ current, form, setForm, showKey, setShowKey }) {
  return (
    <div className="space-y-4">
      <Field label="QODER PAT" hint={current.hasInvocationKey ? `已保存（${current.invocationKeyPreview || current.keyPreview}），重新输入可覆盖；留空保持不变` : '在 QODER 账号集成页创建 Personal Access Token'}>
        <div className="relative">
          <input
            type={showKey ? 'text' : 'password'}
            value={form.invocationKey || form.apiKey || ''}
            onChange={e => setForm({ ...form, invocationKey: e.target.value, apiKey: e.target.value })}
            placeholder="qoder_pat_..."
            className="w-full h-10 px-3 pr-20 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
          />
          <button
            type="button"
            onClick={() => setShowKey(s => !s)}
            className="absolute right-2 top-1/2 -translate-y-1/2 text-xs text-gray-500 hover:text-gray-800 px-2 py-1"
          >
            {showKey ? '隐藏' : '显示'}
          </button>
        </div>
      </Field>

      <div className="grid gap-4 md:grid-cols-2">
        <Field label="Environment ID" hint="QODER Cloud Agent 会话运行环境 ID">
          <input
            value={form.runtimeId || form.environmentId || ''}
            onChange={e => setForm({ ...form, runtimeId: e.target.value, environmentId: e.target.value })}
            placeholder="env_..."
            className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
          />
        </Field>
        <Field label="Agent ID" hint="复用已创建的 QODER Cloud Agent">
          <input
            value={form.endpointId || form.agentId || ''}
            onChange={e => setForm({ ...form, endpointId: e.target.value, agentId: e.target.value })}
            placeholder="agent_..."
            className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
          />
        </Field>
      </div>

      <Field label="API Base（可选）" hint="默认 https://api.qoder.com/api/v1/cloud；私有或区域环境才需要覆盖">
        <input
          value={form.endpointPublicUrl || ''}
          onChange={e => setForm({ ...form, endpointPublicUrl: e.target.value })}
          placeholder="https://api.qoder.com/api/v1/cloud"
          className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
        />
      </Field>
    </div>
  )
}

function RuntimeRegistryPanel({
  view = 'all',
  runtimes,
  agents,
  skills = [],
  busyKey,
  message,
  onSaveRuntime,
  onSetActive,
  onTestRuntime,
  onSaveAgent,
}) {
  const [activeRuntimeCode, setActiveRuntimeCode] = useState('')
  const [runtimeDrafts, setRuntimeDrafts] = useState({})
  const [agentDrafts, setAgentDrafts] = useState({})
  const [showRuntimeSecret, setShowRuntimeSecret] = useState(false)
  const normalizedRuntimes = runtimes || []
  const normalizedAgents = agents || []
  const normalizedSkills = skills || []
  const showRuntimes = view !== 'agents'
  const showAgents = view !== 'runtimes'

  useEffect(() => {
    if (!activeRuntimeCode && normalizedRuntimes.length) {
      setActiveRuntimeCode((normalizedRuntimes.find(r => r.isActive) || normalizedRuntimes[0]).code)
    }
    const next = {}
    for (const runtime of normalizedRuntimes) {
      next[runtime.code] = {
        name: runtime.name || '',
        icon: runtime.icon || '',
        command: runtime.command || '',
        argsText: runtime.argsText || '',
        healthcheckArgsText: runtime.healthcheckArgsText || '',
        workingDir: runtime.workingDir || '',
        envText: runtime.envText || '',
        purposeScopes: runtime.purposeScopes || [],
        timeoutMs: runtime.timeoutMs || 300000,
        notes: runtime.notes || '',
        enabled: !!runtime.enabled,
        endpointPublicUrl: runtime.endpointPublicUrl || runtime.baseUrl || '',
        invocationKey: '',
        runtimeName: runtime.runtimeName || '',
        endpointName: runtime.endpointName || 'default',
        accountId: runtime.accountId || '',
        regionId: runtime.regionId || 'cn-hangzhou',
        accessKeyId: '',
        accessKeySecret: '',
        securityToken: '',
        runtimeId: runtime.runtimeId || '',
        endpointId: runtime.endpointId || '',
      }
    }
    setRuntimeDrafts(next)
  }, [normalizedRuntimes, activeRuntimeCode])

  useEffect(() => {
    const next = {}
    for (const agent of normalizedAgents) {
      next[agent.id] = {
        name: agent.name || '',
        description: agent.description || '',
        prompt: agent.prompt || '',
        runtimeCode: agent.runtimeCode || '',
        systemSkillKind: agent.systemSkillKind || '',
        skillId: agent.skillId || '',
        appliesTo: agent.appliesTo || [],
        enabled: !!agent.enabled,
      }
    }
    setAgentDrafts(next)
  }, [normalizedAgents])

  const activeRuntime = normalizedRuntimes.find(r => r.code === activeRuntimeCode) || normalizedRuntimes[0]
  const runtimeDraft = activeRuntime ? (runtimeDrafts[activeRuntime.code] || {}) : {}

  function updateRuntimeDraft(patch) {
    if (!activeRuntime) return
    setRuntimeDrafts(prev => ({
      ...prev,
      [activeRuntime.code]: {
        ...(prev[activeRuntime.code] || runtimeDraft),
        ...patch,
      },
    }))
  }

  function toggleRuntimePurpose(purpose) {
    const current = runtimeDraft.purposeScopes || []
    updateRuntimeDraft({
      purposeScopes: current.includes(purpose)
        ? current.filter(p => p !== purpose)
        : [...current, purpose],
    })
  }

  function updateAgentDraft(id, patch) {
    setAgentDrafts(prev => ({
      ...prev,
      [id]: {
        ...(prev[id] || {}),
        ...patch,
      },
    }))
  }

  function toggleAgentPurpose(id, purpose) {
    const current = agentDrafts[id]?.appliesTo || []
    updateAgentDraft(id, {
      appliesTo: current.includes(purpose)
        ? current.filter(p => p !== purpose)
        : [...current, purpose],
    })
  }

  return (
    <section className="rounded-lg border border-gray-200 bg-white px-4 py-4">
      <div className="flex flex-wrap items-start justify-between gap-3">
        <div>
          <div className="text-sm font-semibold text-gray-950">
            {view === 'agents' ? '智能体配置' : view === 'runtimes' ? '运行时注册' : '运行时与智能体'}
          </div>
          <div className="mt-1 text-xs leading-5 text-gray-600">
            {view === 'agents'
              ? '先配置智能体名称和提示词，再绑定运行时、平台 Skill 与生效范围。'
              : '运行时负责“在哪里执行”，可以是 AgentRun、QODER Cloud Agent 远端运行时，也可以是本机 CLI。'}
          </div>
        </div>
        <Chip tone={view === 'agents' ? 'blue' : (normalizedRuntimes.some(r => r.isActive && r.enabled) ? 'green' : 'amber')}>
          {view === 'agents'
            ? `${normalizedAgents.filter(a => a.enabled).length}/${normalizedAgents.length} 个智能体启用`
            : normalizedRuntimes.some(r => r.isActive && r.enabled) ? '运行时已选择' : '待选择运行时'}
        </Chip>
      </div>

      {message && <div className="mt-3 text-xs text-gray-600">{message}</div>}

      {showRuntimes && <div className="mt-4 grid gap-4 lg:grid-cols-[240px_1fr]">
        <div className="space-y-1.5">
          {normalizedRuntimes.map(runtime => (
            <button
              key={runtime.code}
              type="button"
              onClick={() => setActiveRuntimeCode(runtime.code)}
              className={[
                'w-full rounded-lg border px-3 py-2 text-left transition',
                activeRuntime?.code === runtime.code ? 'border-brand-500 bg-brand-50' : 'border-gray-200 hover:bg-gray-50',
              ].join(' ')}
            >
              <div className="flex items-start gap-2">
                <span className="mt-0.5"><ProviderIcon code={runtime.code} size={20} /></span>
                <span className="min-w-0 flex-1">
                  <span className="block truncate text-sm font-medium text-gray-900">{runtime.name}</span>
                  <span className="mt-1 flex flex-wrap gap-1">
                    <Chip tone={runtime.protocol === 'local-cli' ? 'amber' : 'blue'}>{runtime.protocol === 'local-cli' ? '本地' : '远端'}</Chip>
                    {runtime.isActive && <Chip tone="blue">当前</Chip>}
                    {runtime.enabled ? <Chip tone="green">启用</Chip> : <Chip tone="gray">停用</Chip>}
                  </span>
                </span>
              </div>
            </button>
          ))}
        </div>

        {activeRuntime && (
          <div className="space-y-4">
            <div className="flex flex-wrap items-center gap-2">
              <Chip tone={activeRuntime.protocol === 'local-cli' ? 'amber' : 'blue'}>{runtimeKindLabel(activeRuntime)}</Chip>
              {activeRuntime.isActive && <Chip tone="blue">当前运行时</Chip>}
              {activeRuntime.ready ? <Chip tone="green">配置完整</Chip> : <Chip tone="rose">待补齐</Chip>}
              {activeRuntime.missing?.length ? <span className="text-xs text-rose-600">缺少：{activeRuntime.missing.join('、')}</span> : null}
            </div>

            {activeRuntime.protocol === 'local-cli' ? (
              <div className="grid gap-4 md:grid-cols-2">
                <Field label="显示名称">
                  <input
                    value={runtimeDraft.name || ''}
                    onChange={e => updateRuntimeDraft({ name: e.target.value })}
                    className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm focus:outline-none focus:ring-2 focus:ring-brand-500"
                  />
                </Field>
                <Field label="命令" hint="可填命令名或绝对路径，例如 codex">
                  <input
                    value={runtimeDraft.command || ''}
                    onChange={e => updateRuntimeDraft({ command: e.target.value })}
                    className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
                  />
                </Field>
                <Field label="运行参数" hint="使用 {workdir} 代表本次运行目录；使用 {prompt} 可把提示词作为参数传入；没有 {prompt} 时默认走 stdin">
                  <input
                    value={runtimeDraft.argsText || ''}
                    onChange={e => updateRuntimeDraft({ argsText: e.target.value })}
                    className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
                  />
                </Field>
                <Field label="健康检查参数" hint="用于测试连通，默认 --version">
                  <input
                    value={runtimeDraft.healthcheckArgsText || ''}
                    onChange={e => updateRuntimeDraft({ healthcheckArgsText: e.target.value })}
                    className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
                  />
                </Field>
                <Field label="工作目录覆盖" hint="留空时使用每次运行的会话目录">
                  <input
                    value={runtimeDraft.workingDir || ''}
                    onChange={e => updateRuntimeDraft({ workingDir: e.target.value })}
                    className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
                  />
                </Field>
                <Field label="超时毫秒">
                  <input
                    type="number"
                    min="5000"
                    value={runtimeDraft.timeoutMs || 300000}
                    onChange={e => updateRuntimeDraft({ timeoutMs: Number(e.target.value) })}
                    className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
                  />
                </Field>
                <div className="md:col-span-2">
                  <Field label="环境变量" hint="每行 KEY=value；留空则继承服务端环境">
                    <textarea
                      value={runtimeDraft.envText || ''}
                      onChange={e => updateRuntimeDraft({ envText: e.target.value })}
                      className="w-full h-20 px-3 py-2 rounded-lg border border-gray-300 text-xs font-mono focus:outline-none focus:ring-2 focus:ring-brand-500"
                    />
                  </Field>
                </div>
              </div>
            ) : (
              isQoderCloudAgent(activeRuntime) ? (
                <QoderCloudAgentFields
                  current={activeRuntime}
                  form={runtimeDraft}
                  setForm={(next) => updateRuntimeDraft(next)}
                  showKey={showRuntimeSecret}
                  setShowKey={setShowRuntimeSecret}
                />
              ) : (
                <AgentRunFields
                  current={activeRuntime}
                  form={runtimeDraft}
                  setForm={(next) => updateRuntimeDraft(next)}
                  showKey={showRuntimeSecret}
                  setShowKey={setShowRuntimeSecret}
                />
              )
            )}

            <div>
              <div className="mb-2 text-sm font-medium text-gray-800">适用场景</div>
              <div className="flex flex-wrap gap-2">
                {Object.entries(PURPOSE_LABELS).map(([purpose, label]) => (
                  <button
                    key={purpose}
                    type="button"
                    onClick={() => toggleRuntimePurpose(purpose)}
                    className={[
                      'h-8 px-3 rounded-lg border text-xs',
                      (runtimeDraft.purposeScopes || []).includes(purpose)
                        ? 'border-brand-200 bg-brand-50 text-brand-700'
                        : 'border-gray-200 text-gray-600 hover:bg-gray-50',
                    ].join(' ')}
                  >
                    {label}
                  </button>
                ))}
              </div>
            </div>

            <Field label="备注">
              <textarea
                value={runtimeDraft.notes || ''}
                onChange={e => updateRuntimeDraft({ notes: e.target.value })}
                className="w-full h-16 px-3 py-2 rounded-lg border border-gray-300 text-sm focus:outline-none focus:ring-2 focus:ring-brand-500"
              />
            </Field>

            <div className="flex flex-wrap items-center gap-2">
              <button
                type="button"
                onClick={() => updateRuntimeDraft({ enabled: !runtimeDraft.enabled })}
                className={[
                  'h-9 px-3 rounded-lg border text-sm',
                  runtimeDraft.enabled ? 'border-emerald-200 bg-emerald-50 text-emerald-700' : 'border-gray-300 text-gray-600 hover:bg-gray-50',
                ].join(' ')}
              >
                {runtimeDraft.enabled ? '启用中' : '已停用'}
              </button>
              <button
                type="button"
                onClick={() => onSaveRuntime(activeRuntime.code, runtimeDraft)}
                disabled={busyKey === activeRuntime.code}
                className="h-9 px-4 rounded-lg bg-brand-600 text-white text-sm font-medium hover:bg-brand-700 disabled:opacity-50"
              >
                {busyKey === activeRuntime.code ? '保存中...' : '保存运行时'}
              </button>
              <button
                type="button"
                onClick={() => onTestRuntime(activeRuntime.code)}
                disabled={busyKey === activeRuntime.code}
                className="h-9 px-4 rounded-lg border border-gray-300 text-sm text-gray-700 hover:bg-gray-50 disabled:opacity-50"
              >
                测试
              </button>
              <button
                type="button"
                onClick={() => onSetActive(activeRuntime.code)}
                disabled={activeRuntime.isActive || busyKey === activeRuntime.code}
                className="h-9 px-4 rounded-lg border border-brand-200 bg-brand-50 text-sm text-brand-700 hover:bg-brand-100 disabled:opacity-50"
              >
                {activeRuntime.isActive ? '已是当前运行时' : '设为当前运行时'}
              </button>
            </div>
          </div>
        )}
      </div>}

      {showAgents && <div className={showRuntimes ? 'mt-6 border-t border-gray-100 pt-5' : 'mt-4'}>
        {showRuntimes && <div className="mb-3 text-sm font-semibold text-gray-950">智能体配置</div>}
        <div className="grid gap-4">
          {normalizedAgents.map(agent => {
            const draft = agentDrafts[agent.id] || {}
            return (
              <div key={agent.id} className="rounded-lg border border-gray-200 px-4 py-4">
                <div className="mb-4 flex flex-wrap items-start justify-between gap-3">
                  <div>
                    <div className="text-sm font-semibold text-gray-950">{draft.name || agent.name || '未命名智能体'}</div>
                    <div className="mt-1 text-xs text-gray-500">{draft.description || '为一个具体执行场景配置独立提示词和运行边界'}</div>
                  </div>
                  <div className="flex flex-wrap items-center gap-1.5">
                    <Chip tone={draft.enabled ? 'green' : 'gray'}>{draft.enabled ? '启用' : '停用'}</Chip>
                    {draft.skillId && <Chip tone="blue">{normalizedSkills.find(s => s.id === draft.skillId)?.name || agent.skillName || '平台 Skill'}</Chip>}
                  </div>
                </div>
                <div className="grid gap-4 md:grid-cols-2">
                  <Field label="智能体名称" hint="例如：AI 创建智能体、Skill 评测智能体、运行调试智能体">
                    <input
                      value={draft.name || ''}
                      onChange={e => updateAgentDraft(agent.id, { name: e.target.value })}
                      className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm focus:outline-none focus:ring-2 focus:ring-brand-500"
                    />
                  </Field>
                  <Field label="选择运行时" hint="可使用当前运行时，也可为这个智能体指定本地 CLI 或 AgentRun">
                    <select
                      value={draft.runtimeCode || ''}
                      onChange={e => updateAgentDraft(agent.id, { runtimeCode: e.target.value })}
                      className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm focus:outline-none focus:ring-2 focus:ring-brand-500"
                    >
                      <option value="">使用当前运行时</option>
                      {normalizedRuntimes.map(runtime => (
                        <option key={runtime.code} value={runtime.code}>{runtime.name}</option>
                      ))}
                    </select>
                  </Field>
                </div>
                <div className="mt-4 grid gap-4 md:grid-cols-2">
                  <Field label="挂载平台 Skill" hint="从平台已有 Skill 中选择；运行时读取它的 zip 包，不在配置页存大段文本">
                    <select
                      value={draft.skillId || ''}
                      onChange={e => updateAgentDraft(agent.id, { skillId: e.target.value })}
                      className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm focus:outline-none focus:ring-2 focus:ring-brand-500"
                    >
                      <option value="">不挂载</option>
                      {normalizedSkills.map(skill => (
                        <option key={skill.id} value={skill.id}>
                          {skill.name || skill.title || skill.id}
                        </option>
                      ))}
                    </select>
                  </Field>
                  <Field label="说明" hint="给管理员看的用途说明，不会直接作为提示词发送">
                    <input
                      value={draft.description || ''}
                      onChange={e => updateAgentDraft(agent.id, { description: e.target.value })}
                      className="w-full h-10 px-3 rounded-lg border border-gray-300 text-sm focus:outline-none focus:ring-2 focus:ring-brand-500"
                    />
                  </Field>
                </div>
                <div className="mt-4">
                  <Field label="智能体提示词" hint="这里写这个智能体的角色、边界、输出要求和禁止事项；运行时会叠加挂载的 Skill 包">
                    <textarea
                      value={draft.prompt || ''}
                      onChange={e => updateAgentDraft(agent.id, { prompt: e.target.value })}
                      className="w-full h-32 px-3 py-2 rounded-lg border border-gray-300 text-xs font-mono leading-5 focus:outline-none focus:ring-2 focus:ring-brand-500"
                      placeholder="例如：你是 Skill 评测智能体。必须先读取包文件，再按结构完整性、触发准确性、可执行性和安全边界输出评测结论..."
                    />
                  </Field>
                </div>
                <div className="mt-4">
                  <div className="mb-2 flex flex-wrap items-center gap-2">
                    <span className="text-sm font-medium text-gray-800">生效范围</span>
                    <span className="text-[11px] text-gray-500">决定这个智能体用于 AI 创建、评测、运行或 API 调用等场景</span>
                  </div>
                  <div className="flex flex-wrap items-center gap-2">
                    {Object.entries(PURPOSE_LABELS).map(([purpose, label]) => (
                      <button
                        key={purpose}
                        type="button"
                        onClick={() => toggleAgentPurpose(agent.id, purpose)}
                        className={[
                          'h-8 px-3 rounded-lg border text-xs',
                          (draft.appliesTo || []).includes(purpose)
                            ? 'border-brand-200 bg-brand-50 text-brand-700'
                            : 'border-gray-200 text-gray-600 hover:bg-gray-50',
                        ].join(' ')}
                      >
                        {label}
                      </button>
                    ))}
                  </div>
                </div>
                <div className="mt-4 flex flex-wrap items-center gap-2">
                  <button
                    type="button"
                    onClick={() => updateAgentDraft(agent.id, { enabled: !draft.enabled })}
                    className={[
                      'h-8 px-3 rounded-lg border text-xs',
                      draft.enabled ? 'border-emerald-200 bg-emerald-50 text-emerald-700' : 'border-gray-200 text-gray-600 hover:bg-gray-50',
                    ].join(' ')}
                  >
                    {draft.enabled ? '启用' : '停用'}
                  </button>
                  <button
                    type="button"
                    onClick={() => onSaveAgent(agent.id, draft)}
                    disabled={busyKey === agent.id}
                    className="h-8 px-4 rounded-lg bg-brand-600 text-white text-xs font-medium hover:bg-brand-700 disabled:opacity-50"
                  >
                    {busyKey === agent.id ? '保存中...' : '保存智能体'}
                  </button>
                </div>
              </div>
            )
          })}
        </div>
      </div>}
    </section>
  )
}

function RuntimeReadinessPanel({ agentRun, activeRuntime, onSelect }) {
  const agentRunReady = !!(agentRun?.enabled && ((hasAgentRunIntegrationUrl(agentRun) && agentRun?.hasInvocationKey) || (agentRun?.hasAccessKeyId && agentRun?.hasAccessKeySecret && agentRun?.accountId && agentRun?.runtimeName)))
  const localReady = activeRuntime?.protocol === 'local-cli' && activeRuntime?.enabled && activeRuntime?.command
  const usingAgentRun = activeRuntime?.protocol === 'agentrun'
  const cloudReady = isQoderCloudAgent(activeRuntime) && activeRuntime?.ready
  const ready = (usingAgentRun && agentRunReady) || localReady || cloudReady

  return (
    <section className={[
      'rounded-lg border px-4 py-4',
      ready ? 'border-emerald-200 bg-emerald-50/60' : 'border-amber-200 bg-amber-50/70',
    ].join(' ')}>
      <div className="flex flex-wrap items-start justify-between gap-3">
        <div>
          <div className="text-sm font-semibold text-gray-950">发布运行检查</div>
          <div className="mt-1 text-xs leading-5 text-gray-600">
            当前运行时：{activeRuntime ? activeRuntime.name : '未选择'}。新建、评测、运行和外部 API 可以分别绑定智能体。
          </div>
        </div>
        <Chip tone={ready ? 'green' : 'amber'}>{ready ? '可运行' : '待配置'}</Chip>
      </div>

      <div className="mt-4 grid gap-3 md:grid-cols-3">
        <ReadinessStep
          ok={!!activeRuntime}
          title="运行时"
          body={activeRuntime ? `${activeRuntime.name} / ${activeRuntime.protocol === 'local-cli' ? activeRuntime.command : isQoderCloudAgent(activeRuntime) ? (activeRuntime.agentId || activeRuntime.endpointId || '未填 Agent ID') : (activeRuntime.runtimeName || '未填 Runtime')}` : '请先选择运行时'}
          actionLabel={activeRuntime?.protocol === 'local-cli' ? undefined : `配置 ${runtimeKindLabel(activeRuntime)}`}
          onAction={() => onSelect(activeRuntime?.code || agentRun?.code)}
        />
        <ReadinessStep
          ok={ready}
          title={activeRuntime?.protocol === 'local-cli' ? '本地 CLI' : `${runtimeKindLabel(activeRuntime)} 云配置`}
          body={activeRuntime?.protocol === 'local-cli'
            ? (localReady ? activeRuntime.command : '请填写并测试本地命令')
            : isQoderCloudAgent(activeRuntime)
              ? (cloudReady ? `${activeRuntime.environmentId || activeRuntime.runtimeId} / ${activeRuntime.agentId || activeRuntime.endpointId}` : '请配置 PAT、Environment ID 和 Agent ID')
              : (agentRunReady ? `${agentRun.runtimeName || 'AgentRun'} / ${agentRun.endpointName || 'Default'}` : '请配置 AgentRun 集成 URL 和调用凭证')}
          actionLabel={activeRuntime?.protocol === 'local-cli' ? undefined : `配置 ${runtimeKindLabel(activeRuntime)}`}
          onAction={() => onSelect(activeRuntime?.code || agentRun?.code)}
        />
        <ReadinessStep
          ok={ready}
          title="Skill 运行"
          body={ready ? '沙箱、评测和 API 调用将进入同一执行链路' : '两项都完成后才允许线上执行'}
        />
      </div>
    </section>
  )
}

function ReadinessStep({ ok, title, body, actionLabel, onAction }) {
  return (
    <div className="px-1 py-1">
      <div className="flex items-center gap-2">
        <span className={['h-2 w-2 rounded-full', ok ? 'bg-emerald-500' : 'bg-amber-500'].join(' ')} />
        <span className="text-sm font-medium text-gray-900">{title}</span>
      </div>
      <div className="mt-1 min-h-[34px] text-xs leading-5 text-gray-500">{body}</div>
      {actionLabel && (
        <button
          type="button"
          onClick={onAction}
          className="mt-2 text-xs font-medium text-brand-700 hover:text-brand-900"
        >
          {actionLabel}
        </button>
      )}
    </div>
  )
}

function Field({ label, hint, children }) {
  return (
    <div>
      <div className="flex items-center justify-between mb-1.5">
        <label className="text-sm font-medium text-gray-800">{label}</label>
      </div>
      {children}
      {hint && <p className="mt-1 text-[11px] text-gray-500">{hint}</p>}
    </div>
  )
}
