<script setup>
import { ref, computed, watch, reactive, onMounted, onUnmounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { message, Modal } from 'ant-design-vue'
import {
  ArrowLeft, RefreshCw, Play, Square, RotateCcw, Plug, CheckSquare, X,
  Plus, MessageCircle, Settings, Shield, Trash2, Clipboard, Stethoscope
} from 'lucide-vue-next'
import { useChannelStore } from '@/stores/channel'
import { useAgentStore } from '@/stores/agent'
import { channelIcons } from '@/constants/channelIcons'
import { channelTypeLabels } from '@/constants/channelTypes'
import { useCredentialStatus } from '@/composables/useCredentialStatus'
import PageHeader from '@/components/shared/PageHeader.vue'
import PageShoulder from '@/components/shared/PageShoulder.vue'
import InfoCard from '@/components/shared/InfoCard.vue'
import ExtensionCardGrid from '@/components/extensions/ExtensionCardGrid.vue'
import ChannelConfigForm from '@/components/channels/ChannelConfigForm.vue'
import AgentRoutingTable from '@/components/channels/AgentRoutingTable.vue'
import ChannelPolicyForm from '@/components/channels/ChannelPolicyForm.vue'
import ChannelStatsPanel from '@/components/channels/ChannelStatsPanel.vue'
import ChannelMessageLog from '@/components/channels/ChannelMessageLog.vue'
import ChannelAbilityPanel from '@/components/channels/ChannelAbilityPanel.vue'
import ChannelMappingBrowser from '@/components/channels/ChannelMappingBrowser.vue'
import ChannelTestDialog from '@/components/channels/ChannelTestDialog.vue'
import ChannelDebugLog from '@/components/channels/ChannelDebugLog.vue'

const route = useRoute()
const router = useRouter()
const channelStore = useChannelStore()
const agentStore = useAgentStore()

const props = defineProps({
  channelId: { type: String, default: null }
})

const viewMode = ref('overview')
const detailChannelId = ref(null)
const detailLoading = ref(false)

const activeTab = ref('info')
const showTestDialog = ref(false)

const editableConfig = ref({})
const editablePolicy = ref({})
const actionLoading = reactive({})
const credRefreshLoading = ref(false)
const policySaving = ref(false)

const restartHint = ref(false)

const refreshing = ref(false)

const channelDetail = computed(() =>
  detailChannelId.value ? channelStore.channels[detailChannelId.value] : null
)

const agentList = computed(() => agentStore.agentsList)

watch(channelDetail, (detail) => {
  if (detail) {
    editableConfig.value = { ...(detail.config || {}) }
    editablePolicy.value = { ...(detail.policy || {}) }
  }
})

watch(activeTab, (tab) => {
  if (tab === 'routing' && detailChannelId.value) {
    channelStore.fetchRouting(detailChannelId.value)
  }
  if (tab === 'policy' && detailChannelId.value) {
    channelStore.fetchChannelPolicy(detailChannelId.value)
  }
})

const tabs = [
  { key: 'info', label: '基本信息' },
  { key: 'config', label: '连接配置' },
  { key: 'ability', label: '渠道能力' },
  { key: 'routing', label: 'Agent 路由' },
  { key: 'policy', label: '策略配置' },
  { key: 'stats', label: '统计图表' },
  { key: 'messages', label: '消息日志' },
  { key: 'mapping', label: '映射管理' },
  { key: 'diagnostic', label: '诊断报告' },
  { key: 'debug', label: '运行日志' }
]

const channelList = computed(() => Object.values(channelStore.channels))

const searchQuery = ref('')

const filteredChannelList = computed(() => {
  const keyword = searchQuery.value.trim().toLowerCase()
  if (!keyword) return channelList.value
  return channelList.value.filter(
    (ch) =>
      (ch.display_name || '').toLowerCase().includes(keyword) ||
      (ch.channel_id || '').toLowerCase().includes(keyword) ||
      (ch.channel_type || '').toLowerCase().includes(keyword)
  )
})

const channelStats = computed(() => {
  let total = 0, enabled = 0, running = 0
  for (const ch of channelList.value) {
    total++
    if (ch.enabled) enabled++
    if (ch.status === 'connected') running++
  }
  return { total, enabled, running }
})

const skeletonCount = 6

const batchMode = ref(false)
const selectedIds = ref(new Set())
const batchActionLoading = ref(false)

const allSelected = computed(() =>
  filteredChannelList.value.length > 0 &&
  filteredChannelList.value.every((ch) => selectedIds.value.has(ch.channel_id))
)

const selectedCount = computed(() => selectedIds.value.size)

function enterBatchMode() {
  batchMode.value = true
  selectedIds.value = new Set()
}

function exitBatchMode() {
  batchMode.value = false
  selectedIds.value = new Set()
}

function handleSelectAll() {
  if (allSelected.value) {
    selectedIds.value = new Set()
  } else {
    selectedIds.value = new Set(filteredChannelList.value.map((ch) => ch.channel_id))
  }
}

async function handleBatchAction(action) {
  const ids = [...selectedIds.value]
  if (!ids.length) return

  if (action === 'unregister') {
    Modal.confirm({
      title: '确认批量注销',
      content: `确定要注销选中的 ${ids.length} 个渠道吗？注销后渠道将停止运行，此操作不可撤销。`,
      okText: '确认注销',
      cancelText: '取消',
      okType: 'danger',
      onOk: async () => {
        batchActionLoading.value = true
        const results = await Promise.allSettled(
          ids.map((id) => channelStore.unregisterChannel(id).then(() => ({ id, ok: true })).catch((e) => ({ id, ok: false, error: e })))
        )
        const succeeded = results.filter((r) => r.value?.ok).length
        const failed = results.length - succeeded
        if (failed === 0) {
          message.success(`批量注销完成：${succeeded} 个成功`)
        } else {
          message.warning(`批量注销完成：${succeeded} 个成功，${failed} 个失败`)
        }
        exitBatchMode()
        batchActionLoading.value = false
        await channelStore.fetchAllStatus()
      }
    })
    return
  }

  batchActionLoading.value = true
  const actionFn = {
    start: (id) => channelStore.startChannel(id),
    stop: (id) => channelStore.stopChannel(id),
    restart: (id) => channelStore.restartChannel(id)
  }[action]

  const results = await Promise.allSettled(ids.map((id) => actionFn(id).then(() => ({ id, ok: true })).catch((e) => ({ id, ok: false, error: e }))))
  const succeeded = results.filter((r) => r.value?.ok).length
  const failed = results.length - succeeded

  if (failed === 0) {
    message.success(`批量${action === 'start' ? '启动' : action === 'stop' ? '停止' : '重启'}完成：${succeeded} 个成功`)
  } else {
    message.warning(`批量操作完成：${succeeded} 个成功，${failed} 个失败`)
  }

  exitBatchMode()
  batchActionLoading.value = false
  await channelStore.fetchAllStatus()
}

function handleManage(channelId) {
  router.push({ name: 'ChannelDetailComp', params: { channelId } })
}

async function handleToggle(channelId) {
  if (actionLoading[`toggle_${channelId}`]) return
  actionLoading[`toggle_${channelId}`] = true
  try {
    const channel = channelStore.channels[channelId]
    if (channel?.enabled) {
      const res = await channelStore.stopChannel(channelId)
      if (res?.code === 0) {
        message.success('渠道已停止')
      } else {
        message.warning(res?.message || '停止失败')
      }
    } else {
      const res = await channelStore.startChannel(channelId)
      if (res?.code === 0) {
        message.success('渠道已启动')
      } else {
        message.warning(res?.message || '启动失败')
      }
    }
  } catch (e) {
    message.error(e.message || '操作失败')
  } finally {
    delete actionLoading[`toggle_${channelId}`]
  }
}

async function handleCardRestart(channelId) {
  if (actionLoading[`restart_${channelId}`]) return
  actionLoading[`restart_${channelId}`] = true
  try {
    const res = await channelStore.restartChannel(channelId)
    if (res?.code === 0) {
      message.success('渠道重启指令已发送')
    } else {
      message.warning(res?.message || '重启失败')
    }
  } catch (e) {
    message.error(e.message || '重启失败')
  } finally {
    delete actionLoading[`restart_${channelId}`]
  }
}

async function handleStartChannel() {
  const id = detailChannelId.value
  if (actionLoading[`start_${id}`]) return
  actionLoading[`start_${id}`] = true
  try {
    await channelStore.startChannel(id)
    message.success('渠道启动指令已发送')
    await loadChannelDetail(id)
  } catch (e) {
    message.error(e.message || '启动失败')
  } finally {
    delete actionLoading[`start_${id}`]
  }
}

async function handleStopChannel() {
  const id = detailChannelId.value
  if (actionLoading[`stop_${id}`]) return
  actionLoading[`stop_${id}`] = true
  try {
    await channelStore.stopChannel(id)
    message.success('渠道已停止')
    await loadChannelDetail(id)
  } catch (e) {
    message.error(e.message || '停止失败')
  } finally {
    delete actionLoading[`stop_${id}`]
  }
}

async function handleRestartChannel() {
  const id = detailChannelId.value
  if (actionLoading[`restart_${id}`]) return
  actionLoading[`restart_${id}`] = true
  try {
    await channelStore.restartChannel(id)
    message.success('渠道重启指令已发送')
    await loadChannelDetail(id)
  } catch (e) {
    message.error(e.message || '重启失败')
  } finally {
    delete actionLoading[`restart_${id}`]
  }
}

function handleTestChannel() {
  showTestDialog.value = true
}

function goBack() {
  editableConfig.value = {}
  editablePolicy.value = {}
  router.push({ name: 'ChannelManageComp' })
}

async function loadChannelDetail(channelId) {
  detailLoading.value = true
  try {
    await Promise.all([
      channelStore.fetchChannelDetail(channelId),
      channelStore.fetchChannelPolicy(channelId),
      channelStore.fetchRouting(channelId),
      channelStore.fetchCredentialStatus(channelId)
    ])
  } finally {
    detailLoading.value = false
  }
}

async function handleConfigSave() {
  try {
    const res = await channelStore.updateConfig(detailChannelId.value, editableConfig.value)
    restartHint.value = !!(res?.data?.needs_restart)
    if (restartHint.value) {
      message.warning('配置已保存。建议重启渠道以确保所有内部状态同步。')
    } else {
      message.success(res?.message || '配置已保存')
    }
    await loadChannelDetail(detailChannelId.value)
  } catch (e) {
    message.error(e.message || '保存失败')
  }
}

function handleRoutingSave(action) {
  const channel = channelDetail.value
  if (!channel) return
  const routes = [...(channel.routing || [])]
  if (action.index >= 0) {
    routes[action.index] = action.route
  } else {
    routes.push(action.route)
  }
  channelStore.updateRouting(detailChannelId.value, routes).then(() => {
    message.success('路由已更新')
  }).catch((e) => {
    message.error(e?.response?.data?.message || e.message || '保存失败')
  })
}

function handleRoutingDelete(index) {
  const channel = channelDetail.value
  if (!channel) return
  const routes = (channel.routing || []).filter((_, i) => i !== index)
  channelStore.updateRouting(detailChannelId.value, routes).then(() => {
    message.success('路由已删除')
  }).catch((e) => {
    message.error(e?.response?.data?.message || e.message || '删除失败')
  })
}

async function handlePolicySave() {
  if (policySaving.value) return
  policySaving.value = true
  try {
    await channelStore.updatePolicy(detailChannelId.value, editablePolicy.value)
    message.success('策略配置已保存')
    await channelStore.fetchChannelPolicy(detailChannelId.value)
  } finally {
    policySaving.value = false
  }
}

async function handleDeleteChannel() {
  const id = detailChannelId.value
  const name = channelDetail.value?.display_name || id
  Modal.confirm({
    title: '确认注销渠道',
    content: `确定要注销渠道 "${name}" 吗？注销后渠道将停止运行，此操作不可撤销。`,
    okText: '确认注销',
    cancelText: '取消',
    okType: 'danger',
    onOk: async () => {
      try {
        await channelStore.unregisterChannel(id)
        message.success(`渠道 "${name}" 已注销`)
        router.push({ name: 'ChannelManageComp' })
      } catch (e) {
        message.error(e.message || '注销渠道失败')
      }
    },
  })
}

const showRegisterDialog = ref(false)
const registerChannelType = ref('')
const registerLoading = ref(false)

const availableChannelTypes = Object.keys(channelTypeLabels).sort()

async function handleRegisterChannel() {
  if (!registerChannelType.value) return
  registerLoading.value = true
  try {
    const res = await channelStore.registerChannel(registerChannelType.value)
    if (res?.code === 0) {
      message.success('渠道注册成功')
      showRegisterDialog.value = false
      registerChannelType.value = ''
      await channelStore.fetchAllStatus()
    } else {
      message.warning(res?.message || '注册失败')
    }
  } catch (e) {
    message.error(e.message || '注册失败')
  } finally {
    registerLoading.value = false
  }
}

watch(() => props.channelId, async (newId, oldId) => {
  if (newId) {
    viewMode.value = 'detail'
    detailChannelId.value = newId
    channelStore.selectedChannelId = newId
    channelStore.stopPolling()
    activeTab.value = 'info'
    await loadChannelDetail(newId)
    if (route.query.tab === 'test') {
      showTestDialog.value = true
    }
  } else if (oldId) {
    viewMode.value = 'overview'
    detailChannelId.value = null
    channelStore.selectedChannelId = null
    editableConfig.value = {}
    editablePolicy.value = {}
    await channelStore.fetchAllStatus()
    if (channelStore.wsState !== 'connected') {
      channelStore.startPolling(5000)
    }
  }
})

// ============ Card Helpers (overview) ============
const imgErrors = ref({})

function getChannelIcon(channel) {
  const type = channel?.channel_type || ''
  return channelIcons[type] || channelIcons.default
}

function getChannelStatus(channel) {
  if (!channel.enabled) return { label: '未启用', level: 'off' }
  const map = {
    connected: { label: '运行中', level: 'success' },
    connecting: { label: '连接中', level: 'warning' },
    reconnecting: { label: '重连中', level: 'warning' },
    error: { label: '异常', level: 'error' }
  }
  return map[channel.status] || { label: channel.status || '未知', level: 'info' }
}

function getChannelInfo(channel) {
  return [
    { label: '类型', value: channel.channel_type || '-' },
    { label: '今日消息', value: channel.today_messages ?? '-' },
    { label: '活跃连接', value: channel.active_connections ?? '-' }
  ]
}

async function handleRefresh() {
  refreshing.value = true
  try {
    await channelStore.fetchAllStatus()
  } finally {
    refreshing.value = false
  }
}

function handleCardTest(channelId) {
  router.push({ name: 'ChannelDetailComp', params: { channelId }, query: { tab: 'test' } })
}

const { credentialClass, credentialLabel, credentialSourceLabel } = useCredentialStatus(
  () => channelDetail.value?.credential_status
)

async function handleRefreshCredential(channelId) {
  if (credRefreshLoading.value) return
  credRefreshLoading.value = true
  try {
    await channelStore.refreshCredential(channelId)
    message.success('凭证刷新成功')
    await loadChannelDetail(channelId)
  } catch (e) {
    message.error(e.message || '刷新凭证失败')
  } finally {
    credRefreshLoading.value = false
  }
}

const diagnosticCopying = ref(false)

const diagnosticReport = computed(() => {
  const ch = channelDetail.value
  if (!ch) return null

  const configKeys = ch.config ? Object.keys(ch.config).filter((k) => k !== 'enabled') : []
  const credStatus = ch.credential_status
  const credentialOk = credStatus?.status === 'ok' || credStatus?.status === 'valid'

  const checks = []
  checks.push({
    name: '渠道注册',
    status: ch.channel_id ? 'pass' : 'fail',
    detail: ch.channel_id ? `渠道已注册: ${ch.channel_id}` : '渠道未注册'
  })
  checks.push({
    name: '启用状态',
    status: ch.enabled ? 'pass' : 'warn',
    detail: ch.enabled ? '渠道已启用' : '渠道已禁用'
  })
  checks.push({
    name: '连接状态',
    status: ch.status === 'connected' ? 'pass' : ch.status === 'connecting' || ch.status === 'reconnecting' ? 'warn' : 'fail',
    detail: `当前状态: ${ch.status || '未知'}`
  })
  checks.push({
    name: '配置完整性',
    status: configKeys.length > 0 ? 'pass' : 'warn',
    detail: configKeys.length > 0 ? `已配置 ${configKeys.length} 项: ${configKeys.join(', ')}` : '暂无配置项'
  })
  checks.push({
    name: '凭证状态',
    status: credentialOk ? 'pass' : credStatus ? 'warn' : 'info',
    detail: credStatus
      ? `来源: ${credStatus.source || '-'}, 类型: ${credStatus.credential_type || '-'}, 状态: ${credStatus.status || '-'}`
      : '未获取凭证信息'
  })
  if (credStatus?.expires_at) {
    checks.push({
      name: '凭证有效期',
      status: credStatus.status === 'expired' ? 'fail' : 'pass',
      detail: `过期时间: ${credStatus.expires_at}`
    })
  }
  checks.push({
    name: 'Agent 路由',
    status: (ch.routing && ch.routing.length > 0) ? 'pass' : 'info',
    detail: (ch.routing && ch.routing.length > 0) ? `已配置 ${ch.routing.length} 条路由规则` : '未配置路由规则'
  })

  return {
    channel_name: ch.display_name || ch.channel_id,
    channel_id: ch.channel_id,
    channel_type: ch.channel_type,
    generated_at: new Date().toLocaleString(),
    checks
  }
})

function buildDiagnosticText(report) {
  const statusMap = { pass: '✅', warn: '⚠️', fail: '❌', info: 'ℹ️' }
  let text = '='.repeat(50) + '\n'
  text += `  渠道诊断报告\n`
  text += '='.repeat(50) + '\n'
  text += `渠道名称: ${report.channel_name}\n`
  text += `渠道 ID:   ${report.channel_id}\n`
  text += `渠道类型: ${report.channel_type}\n`
  text += `生成时间: ${report.generated_at}\n`
  text += '-'.repeat(50) + '\n'
  for (const check of report.checks) {
    text += `  ${statusMap[check.status] || '  '} ${check.name}: ${check.detail}\n`
  }
  text += '='.repeat(50) + '\n'
  return text
}

async function copyDiagnosticReport() {
  const report = diagnosticReport.value
  if (!report) return
  diagnosticCopying.value = true
  try {
    const text = buildDiagnosticText(report)
    await navigator.clipboard.writeText(text)
    message.success('诊断报告已复制到剪贴板')
  } catch {
    message.error('复制失败，请手动复制')
  } finally {
    diagnosticCopying.value = false
  }
}

onMounted(async () => {
  if (!props.channelId) {
    await channelStore.fetchAllStatus()

    const token = localStorage.getItem('token') || ''
    channelStore.initWS(token).then(() => {
    }).catch(() => {
      channelStore.startPolling(5000)
    })
  }
})

onUnmounted(() => {
  channelStore.stopPolling()
  channelStore.disconnectWS()
  channelStore.selectedChannelId = null
})
</script>

<template>
  <div class="channel-manage-view">
    <template v-if="viewMode === 'overview'">
      <!-- Page Header -->
      <PageHeader
        title="渠道管理"
        description="管理和监控所有消息渠道的连接状态与配置"
        :show-border="true"
      >
        <template #info>
          <div class="summary-strip">
            <span class="stat-pill">
              渠道总数 <strong>{{ channelStats.total }}</strong>
            </span>
            <span class="stat-pill">
              已启用 <strong>{{ channelStats.enabled }}</strong>
            </span>
            <span class="stat-pill stat-pill--running">
              运行中 <strong>{{ channelStats.running }}</strong>
            </span>
          </div>
        </template>
      </PageHeader>

      <!-- Batch Bar -->
      <div v-if="batchMode" class="batch-bar">
        <div class="batch-bar-left">
          <label class="select-all-label">
            <input type="checkbox" :checked="allSelected" @change="handleSelectAll" />
            全选
          </label>
          <span class="batch-count">已选 {{ selectedCount }} 项</span>
        </div>
        <div class="batch-bar-right">
          <a-button size="small" :loading="batchActionLoading" @click="handleBatchAction('start')">
            <Play :size="12" /> 批量启动
          </a-button>
          <a-button size="small" :loading="batchActionLoading" @click="handleBatchAction('stop')">
            <Square :size="12" /> 批量停止
          </a-button>
          <a-button size="small" :loading="batchActionLoading" @click="handleBatchAction('restart')">
            <RotateCcw :size="12" /> 批量重启
          </a-button>
          <a-button size="small" danger :loading="batchActionLoading" @click="handleBatchAction('unregister')">
            <Trash2 :size="12" /> 批量注销
          </a-button>
          <button class="cancel-batch-btn" @click="exitBatchMode">
            <X :size="14" />
          </button>
        </div>
      </div>

      <!-- Toolbar -->
      <PageShoulder v-model:search="searchQuery" search-placeholder="搜索渠道名称、ID 或类型...">
        <template #actions>
          <a-button type="primary" class="lucide-icon-btn register-btn" @click="showRegisterDialog = true">
            <Plus :size="14" />
            注册渠道
          </a-button>
          <a-button class="lucide-icon-btn" @click="handleRefresh" :loading="refreshing">
            <RefreshCw :size="14" :class="{ spinning: refreshing }" />
          </a-button>
          <button v-if="!batchMode" class="batch-mode-btn" @click="enterBatchMode">
            <CheckSquare :size="14" />
            批量操作
          </button>
        </template>
      </PageShoulder>

      <!-- Channel Cards -->
      <div class="channel-content">
        <div
          v-if="channelStore.isLoading && !Object.keys(channelStore.channels).length"
        >
          <ExtensionCardGrid :min-width="280">
            <div v-for="n in skeletonCount" :key="n" class="skeleton-card"></div>
          </ExtensionCardGrid>
        </div>

        <div v-else-if="channelStore.loadError && !Object.keys(channelStore.channels).length" class="empty-state">
          <div class="empty-icon">⚠</div>
          <div class="empty-title">加载失败</div>
          <div class="empty-desc">{{ channelStore.loadError }}</div>
          <a-button @click="channelStore.fetchAllStatus()">重试</a-button>
        </div>

        <div v-else-if="!channelList.length" class="empty-state">
          <div class="empty-icon">📡</div>
          <div class="empty-title">暂无已注册渠道</div>
          <div class="empty-desc">系统尚未注册任何消息渠道，请联系管理员进行配置</div>
        </div>

        <div v-else-if="!filteredChannelList.length" class="empty-state">
          <div class="empty-icon">🔍</div>
          <div class="empty-title">未找到匹配渠道</div>
          <div class="empty-desc">尝试调整搜索关键词</div>
        </div>

        <ExtensionCardGrid v-else :min-width="280">
          <InfoCard
            v-for="ch in filteredChannelList"
            :key="ch.channel_id"
            :title="ch.display_name || ch.channel_id"
            :subtitle="ch.channel_id"
            :disabled="!ch.enabled"
            :status="getChannelStatus(ch)"
            :info="getChannelInfo(ch)"
            :default-icon="MessageCircle"
            @click="handleManage(ch.channel_id)"
          >
            <template #icon>
              <img
                v-if="!imgErrors[ch.channel_id]"
                :src="getChannelIcon(ch)"
                :alt="ch.display_name || ch.channel_id"
                @error="imgErrors[ch.channel_id] = true"
              />
            </template>
            <template #status>
              <span class="channel-status-pill" :class="`channel-status-pill--${getChannelStatus(ch).level}`">
                <span class="status-dot"></span>
                {{ getChannelStatus(ch).label }}
              </span>
            </template>
            <template #footer>
              <button
                class="footer-link"
                type="button"
                @click.stop="handleManage(ch.channel_id)"
              >
                <Settings :size="13" />
                管理
              </button>
              <div class="footer-icon-actions">
                <a-tooltip title="测试连接">
                  <button
                    class="footer-icon-btn"
                    type="button"
                    @click.stop="handleCardTest(ch.channel_id)"
                  >
                    <Plug :size="14" />
                  </button>
                </a-tooltip>
                <a-tooltip title="重启">
                  <button
                    class="footer-icon-btn"
                    type="button"
                    :disabled="!!actionLoading[`restart_${ch.channel_id}`]"
                    @click.stop="handleCardRestart(ch.channel_id)"
                  >
                    <RotateCcw :size="14" />
                  </button>
                </a-tooltip>
                <a-switch
                  :checked="ch.enabled"
                  :loading="!!actionLoading[`toggle_${ch.channel_id}`]"
                  size="small"
                  @click.stop
                  @change="handleToggle(ch.channel_id)"
                />
              </div>
            </template>
          </InfoCard>
        </ExtensionCardGrid>
      </div>
    </template>

    <template v-else>
      <div class="detail-toolbar">
        <button class="back-btn" @click="goBack">
          <ArrowLeft :size="18" />
          返回
        </button>
        <div class="detail-title" v-if="channelDetail">
          <h2>{{ channelDetail.display_name || channelDetail.channel_id }}</h2>
          <span class="detail-id">{{ channelDetail.channel_id }}</span>
        </div>
        <div class="toolbar-spacer"></div>
        <button v-if="channelDetail" class="btn-delete" @click="handleDeleteChannel">注销渠道</button>
      </div>

      <div class="detail-content">
        <div class="detail-tabs">
          <button
            v-for="tab in tabs"
            :key="tab.key"
            class="tab-btn"
            :class="{ active: activeTab === tab.key }"
            @click="activeTab = tab.key"
          >
            {{ tab.label }}
          </button>
        </div>

        <div v-if="detailLoading" class="detail-loading">加载中...</div>

        <div v-else-if="channelDetail" class="detail-container">
          <div v-show="activeTab === 'info'" class="section-card">
            <h3 class="section-title">基本信息</h3>
            <div class="info-grid">
              <div class="info-item">
                <span class="info-label">渠道 ID</span>
                <span class="info-value">{{ channelDetail.channel_id }}</span>
              </div>
              <div class="info-item">
                <span class="info-label">渠道类型</span>
                <span class="info-value">{{ channelDetail.channel_type }}</span>
              </div>
              <div class="info-item">
                <span class="info-label">状态</span>
                <span class="info-value">{{ channelDetail.status }}</span>
              </div>
              <div class="info-item">
                <span class="info-label">运行状态</span>
                <span class="info-value">{{ channelDetail.enabled ? '已启用' : '已禁用' }}</span>
              </div>
            </div>

            <div v-if="channelDetail.credential_status" class="credential-info-section">
              <h4 class="subsection-title">
                <Shield :size="14" />
                凭证状态
                <a-button
                  size="small"
                  type="link"
                  :loading="credRefreshLoading"
                  @click="handleRefreshCredential(detailChannelId)"
                >
                  <RefreshCw :size="12" />
                  刷新凭证
                </a-button>
              </h4>
              <div class="credential-info-grid">
                <div class="info-item">
                  <span class="info-label">凭证来源</span>
                  <span class="info-value">
                    <span class="cred-source-badge" :class="`cred-source-${channelDetail.credential_status.source}`">
                      {{ credentialSourceLabel }}
                    </span>
                  </span>
                </div>
                <div class="info-item">
                  <span class="info-label">凭证类型</span>
                  <span class="info-value">{{ channelDetail.credential_status.credential_type || '-' }}</span>
                </div>
                <div class="info-item">
                  <span class="info-label">状态</span>
                  <span class="info-value">
                    <span class="cred-status-badge" :class="credentialClass">
                      {{ credentialLabel }}
                    </span>
                  </span>
                </div>
                <div class="info-item">
                  <span class="info-label">最后更新</span>
                  <span class="info-value">{{ channelDetail.credential_status.last_updated || '-' }}</span>
                </div>
                <div class="info-item">
                  <span class="info-label">过期时间</span>
                  <span class="info-value">
                    {{ channelDetail.credential_status.expires_at || '无过期时间' }}
                  </span>
                </div>
              </div>
            </div>

            <div class="channel-actions">
              <a-button
                type="primary"
                size="small"
                class="lucide-icon-btn"
                :loading="!!actionLoading[`start_${detailChannelId}`]"
                @click="handleStartChannel"
              >
                <Play :size="14" />
                启动
              </a-button>
              <a-button
                danger
                size="small"
                class="lucide-icon-btn"
                :disabled="!!actionLoading[`stop_${detailChannelId}`]"
                @click="handleStopChannel"
              >
                <Square :size="14" />
                停止
              </a-button>
              <a-button
                size="small"
                class="lucide-icon-btn"
                :disabled="!!actionLoading[`restart_${detailChannelId}`]"
                @click="handleRestartChannel"
              >
                <RotateCcw :size="14" />
                重启
              </a-button>
              <a-button
                size="small"
                class="lucide-icon-btn"
                @click="handleTestChannel"
              >
                <Plug :size="14" />
                测试连接
              </a-button>
            </div>
          </div>

          <div v-show="activeTab === 'config'" class="section-card">
            <div class="section-header">
              <h3 class="section-title">连接配置</h3>
              <a-button
                type="primary"
                size="small"
                @click="handleConfigSave()"
              >
                保存配置
              </a-button>
            </div>
            <div v-if="restartHint" class="restart-hint">
              <span>配置已更新，建议重启渠道以使变更生效。</span>
              <a-button
                size="small"
                type="primary"
                :loading="!!actionLoading[`restart_${detailChannelId}`]"
                @click="handleRestartChannel"
              >
                <RotateCcw :size="12" />
                立即重启
              </a-button>
            </div>
            <ChannelConfigForm
              :channel-type="channelDetail.channel_type"
              :channel-id="detailChannelId"
              v-model="editableConfig"
              :agent-list="agentList"
            />
          </div>

          <div v-show="activeTab === 'ability'" class="section-card">
            <h3 class="section-title">渠道能力</h3>
            <ChannelAbilityPanel :channel-id="detailChannelId" />
          </div>

          <div v-show="activeTab === 'routing'" class="section-card">
            <h3 class="section-title">Agent 路由配置</h3>
            <AgentRoutingTable
              :routes="channelDetail.routing || []"
              :agent-list="agentList"
              @add="handleRoutingSave"
              @edit="handleRoutingSave"
              @delete="handleRoutingDelete"
            />
          </div>

          <div v-show="activeTab === 'policy'" class="section-card">
            <div class="section-header">
              <h3 class="section-title">策略配置</h3>
              <a-button
                type="primary"
                size="small"
                :loading="policySaving"
                @click="handlePolicySave()"
              >
                保存策略
              </a-button>
            </div>
            <ChannelPolicyForm
              v-model="editablePolicy"
            />
          </div>

          <div v-show="activeTab === 'stats'" class="section-card">
            <h3 class="section-title">消息统计</h3>
            <ChannelStatsPanel :channel-id="detailChannelId" />
          </div>

          <div v-show="activeTab === 'messages'" class="section-card">
            <h3 class="section-title">消息日志</h3>
            <ChannelMessageLog :channel-id="detailChannelId" />
          </div>

          <div v-show="activeTab === 'mapping'" class="section-card">
            <h3 class="section-title">映射管理</h3>
            <ChannelMappingBrowser :channel-id="detailChannelId" />
          </div>

          <div v-show="activeTab === 'diagnostic'" class="section-card">
            <div class="section-header">
              <h3 class="section-title">
                <Stethoscope :size="16" class="diagnostic-title-icon" />
                诊断报告
              </h3>
              <a-button
                type="primary"
                size="small"
                :loading="diagnosticCopying"
                @click="copyDiagnosticReport"
              >
                <Clipboard :size="14" />
                一键复制报告
              </a-button>
            </div>
            <div v-if="diagnosticReport" class="diagnostic-content">
              <div class="diagnostic-meta">
                <div class="diagnostic-meta-item">
                  <span class="diagnostic-meta-label">渠道名称</span>
                  <span class="diagnostic-meta-value">{{ diagnosticReport.channel_name }}</span>
                </div>
                <div class="diagnostic-meta-item">
                  <span class="diagnostic-meta-label">渠道 ID</span>
                  <span class="diagnostic-meta-value mono">{{ diagnosticReport.channel_id }}</span>
                </div>
                <div class="diagnostic-meta-item">
                  <span class="diagnostic-meta-label">渠道类型</span>
                  <span class="diagnostic-meta-value">{{ diagnosticReport.channel_type }}</span>
                </div>
                <div class="diagnostic-meta-item">
                  <span class="diagnostic-meta-label">报告时间</span>
                  <span class="diagnostic-meta-value">{{ diagnosticReport.generated_at }}</span>
                </div>
              </div>
              <div class="diagnostic-checks">
                <div
                  v-for="check in diagnosticReport.checks"
                  :key="check.name"
                  class="diagnostic-check-item"
                  :class="`diagnostic-check--${check.status}`"
                >
                  <span class="diagnostic-check-icon">
                    <span v-if="check.status === 'pass'">✅</span>
                    <span v-else-if="check.status === 'warn'">⚠️</span>
                    <span v-else-if="check.status === 'fail'">❌</span>
                    <span v-else>ℹ️</span>
                  </span>
                  <div class="diagnostic-check-body">
                    <span class="diagnostic-check-name">{{ check.name }}</span>
                    <span class="diagnostic-check-detail">{{ check.detail }}</span>
                  </div>
                </div>
              </div>
            </div>
            <div v-else class="diagnostic-empty">
              暂无诊断数据，请先加载渠道详情
            </div>
          </div>

          <div v-show="activeTab === 'debug'" class="section-card">
            <h3 class="section-title">运行日志</h3>
            <ChannelDebugLog :channel-id="detailChannelId" />
          </div>
        </div>
      </div>
    </template>

    <ChannelTestDialog
      v-model:visible="showTestDialog"
      :channel-id="detailChannelId"
      @tested="loadChannelDetail(detailChannelId)"
    />

    <Teleport to="body">
      <div v-if="showRegisterDialog" class="dialog-overlay" @click.self="showRegisterDialog = false">
        <div class="dialog-container">
          <div class="dialog-header">
            <h3>注册渠道</h3>
            <button class="dialog-close" @click="showRegisterDialog = false">
              <X :size="18" />
            </button>
          </div>
          <div class="dialog-body">
            <div class="dialog-section">
              <label class="dialog-label">选择渠道类型</label>
              <select v-model="registerChannelType" class="field-input">
                <option value="">-- 请选择 --</option>
                <option v-for="type in availableChannelTypes" :key="type" :value="type">
                  {{ channelTypeLabels[type] || type }}
                </option>
              </select>
            </div>
          </div>
          <div class="dialog-footer">
            <button class="btn-cancel" @click="showRegisterDialog = false">取消</button>
            <button
              class="btn-submit"
              :disabled="!registerChannelType || registerLoading"
              @click="handleRegisterChannel"
            >
              {{ registerLoading ? '注册中...' : '注册' }}
            </button>
          </div>
        </div>
      </div>
    </Teleport>
  </div>
</template>

<style lang="less" scoped>
.channel-manage-view {
  display: flex;
  flex-direction: column;
  min-height: 100%;
  background: var(--gray-0);
  color: var(--gray-1000);
}

// ============ Summary Strip (Pill Tags) ============
.summary-strip {
  display: flex;
  gap: 8px;
}

.stat-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: 20px;
  background: var(--gray-25);
  border: 1px solid var(--gray-100);
  color: var(--gray-600);
  font-size: 12px;
  font-weight: 500;
  line-height: 20px;

  strong {
    color: var(--gray-900);
    font-weight: 700;
    font-size: 14px;
    font-variant-numeric: tabular-nums;
  }

  &--running {
    background: var(--color-success-50);
    border-color: var(--color-success-100);

    color: var(--color-success-700);

    strong {
      color: var(--color-success-700);
    }
  }
}

// ============ Batch Bar ============
.batch-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px var(--page-padding);
  background: var(--gray-10);
  border-bottom: 1px solid var(--gray-100);

  &-left {
    display: flex;
    align-items: center;
    gap: 12px;
  }

  &-right {
    display: flex;
    align-items: center;
    gap: 8px;
  }
}

.select-all-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--gray-700);
  cursor: pointer;

  input[type="checkbox"] {
    accent-color: var(--main-color);
  }
}

.batch-count {
  font-size: 13px;
  color: var(--gray-600);
  padding: 2px 8px;
  background: var(--gray-50);
  border-radius: 4px;
}

.cancel-batch-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--gray-150);
  border-radius: 4px;
  background: transparent;
  color: var(--gray-500);
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;

  &:hover {
    border-color: var(--gray-300);
    color: var(--gray-700);
  }
}

// ============ Register button (teal solid) ============
.register-btn {
  :deep(&.ant-btn-primary) {
    background: var(--color-accent-700);
    border-color: var(--color-accent-700);

    &:hover {
      background: var(--color-accent-500);
      border-color: var(--color-accent-500);
    }
  }
}

// ============ Batch mode entry button ============
.batch-mode-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border: 1px solid var(--gray-200);
  border-radius: 6px;
  background: var(--gray-0);
  color: var(--gray-700);
  font-size: 13px;
  cursor: pointer;
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;

  &:hover {
    background: var(--main-color);
    border-color: var(--main-color);
    color: #fff;
  }
}

// ============ Content Area ============
.channel-content {
  display: flex;
  flex-direction: column;
}

// ============ Channel Status Pill (dot + text) ============
.channel-status-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 20px;
  background: var(--gray-50);
  font-size: 12px;
  font-weight: 500;
  color: var(--gray-600);

  &--success {
    background: var(--color-success-50);
    color: var(--color-success-700);
  }

  &--warning {
    background: var(--color-warning-50);
    color: var(--color-warning-700);
  }

  &--error {
    background: var(--color-error-50);
    color: var(--color-error-700);
  }

  &--off {
    background: var(--gray-100);
    color: var(--gray-500);
  }

  &--info {
    background: var(--color-info-50);
    color: var(--color-info-700);
  }

  .status-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
    flex-shrink: 0;
  }
}

// ============ Card Footer ============
.footer-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border: none;
  background: transparent;
  color: var(--main-700);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  border-radius: 4px;
  transition: background 0.15s;

  &:hover {
    background: var(--main-30);
  }
}

.footer-icon-actions {
  display: flex;
  align-items: center;
  gap: 6px;
}

.footer-icon-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--gray-150);
  border-radius: 4px;
  background: transparent;
  color: var(--gray-500);
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;

  &:hover {
    border-color: var(--main-200);
    color: var(--main-color);
  }

  &:disabled {
    opacity: 0.4;
    cursor: not-allowed;
    border-color: var(--gray-150);
    color: var(--gray-400);

    &:hover {
      border-color: var(--gray-150);
      color: var(--gray-400);
    }
  }
}

// ============ Skeleton ============
.skeleton-card {
  height: 180px;
  background: linear-gradient(90deg, var(--gray-25) 25%, var(--gray-10) 50%, var(--gray-25) 75%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.5s ease-in-out infinite;
  border-radius: 8px;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px;
  color: var(--gray-600);

  .empty-icon {
    font-size: 48px;
    margin-bottom: 16px;
    opacity: 0.4;
  }

  .empty-title {
    font-size: 18px;
    font-weight: 600;
    color: var(--gray-1000);
    margin-bottom: 4px;
  }

  .empty-desc {
    font-size: 14px;
    margin-bottom: 16px;
  }
}

// ============ Spin animation ============
.spinning {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

@keyframes skeleton-shimmer {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}

// ============ Detail View ============
.detail-toolbar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px var(--page-padding);
  border-bottom: 1px solid var(--gray-100);
  background: var(--gray-0);
}

.back-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--gray-150);
  border-radius: 6px;
  background: var(--gray-0);
  color: var(--gray-700);
  font-size: 14px;
  cursor: pointer;
  transition: background-color 0.2s ease, border-color 0.2s ease;

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

.toolbar-spacer {
  flex: 1;
}

.btn-delete {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border: 1px solid var(--color-error-500);
  border-radius: 6px;
  background: transparent;
  color: var(--color-error-500);
  font-size: 13px;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease;

  &:hover {
    background: var(--color-error-500);
    color: #fff;
  }
}

.detail-title {
  h2 {
    margin: 0;
    font-size: 20px;
    font-weight: 600;
    color: var(--gray-1000);
    line-height: 1.3;
  }

  .detail-id {
    font-size: 12px;
    color: var(--gray-500);
    font-family: monospace;
  }
}

.detail-content {
  padding: 0 var(--page-padding) 24px;
}

.detail-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--gray-150);
  overflow-x: auto;

  .tab-btn {
    padding: 8px 14px;
    border: none;
    border-bottom: 2px solid transparent;
    background: transparent;
    font-size: 14px;
    color: var(--gray-600);
    cursor: pointer;
    white-space: nowrap;
    transition: color 0.2s ease, border-color 0.2s ease;

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

    &.active {
      color: var(--main-color);
      border-bottom-color: var(--main-color);
      font-weight: 500;
    }
  }
}

.detail-loading {
  text-align: center;
  padding: 48px;
  color: var(--gray-500);
  font-size: 14px;
}

.detail-container {
  max-width: 960px;
  margin: 16px auto 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.section-card {
  background: var(--gray-0);
  border: 1px solid var(--gray-150);
  border-radius: 8px;
  padding: 20px;
}

.section-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--gray-1000);
  margin: 0 0 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--gray-150);
}

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

  .section-title {
    margin-bottom: 16px;
    padding-bottom: 8px;
  }
}

.info-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;

  @media (max-width: 767px) {
    grid-template-columns: 1fr;
  }
}

.info-item {
  display: flex;
  flex-direction: column;
  gap: 4px;

  .info-label {
    font-size: 12px;
    color: var(--gray-600);
    font-weight: 500;
  }

  .info-value {
    font-size: 14px;
    color: var(--gray-1000);
  }
}

.channel-actions {
  display: flex;
  gap: 8px;
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--gray-150);
  flex-wrap: wrap;
}

// ============ Register Dialog ============
.dialog-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.4);
}

.dialog-container {
  width: 420px;
  max-width: 90vw;
  background: var(--gray-0);
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
  overflow: hidden;
}

.dialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--gray-150);

  h3 {
    font-size: 16px;
    font-weight: 600;
    color: var(--gray-1000);
    margin: 0;
  }
}

.dialog-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: var(--gray-600);
  cursor: pointer;
  transition: background-color 0.2s ease;

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

.dialog-body {
  padding: 24px 20px;
}

.dialog-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.dialog-label {
  font-size: 14px;
  font-weight: 500;
  color: var(--gray-1000);
}

.field-input {
  height: 36px;
  padding: 0 8px;
  border: 1px solid var(--gray-150);
  border-radius: 6px;
  font-size: 14px;
  color: var(--gray-1000);
  background: var(--gray-0);
  transition: border-color 0.25s ease;

  &:focus {
    border-color: var(--main-color);
    outline: none;
  }
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 12px 20px;
  border-top: 1px solid var(--gray-150);
}

.btn-cancel {
  padding: 6px 16px;
  border: 1px solid var(--gray-150);
  border-radius: 6px;
  background: var(--gray-0);
  color: var(--gray-600);
  font-size: 14px;
  cursor: pointer;

  &:hover {
    border-color: var(--gray-300);
  }
}

.btn-submit {
  padding: 6px 20px;
  border: none;
  border-radius: 6px;
  background: var(--main-color);
  color: #fff;
  font-size: 14px;
  cursor: pointer;
  transition: opacity 0.2s ease;

  &:hover {
    opacity: 0.9;
  }

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
}

.credential-info-section {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--gray-150);

  .subsection-title {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
    font-weight: 600;
    color: var(--gray-900);
    margin: 0 0 10px;
  }
}

.credential-info-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;

  @media (max-width: 767px) {
    grid-template-columns: 1fr;
  }
}

.cred-source-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;

  &.cred-source-db { background: var(--color-success-50); color: var(--color-success-700); }
  &.cred-source-config { background: var(--gray-100); color: var(--gray-600); }
  &.cred-source-env { background: var(--gray-100); color: var(--gray-600); }
  &.cred-source-file { background: var(--gray-100); color: var(--gray-600); }
  &.cred-source-memory { background: var(--color-warning-50); color: var(--color-warning-700); }
  &.cred-source-none { background: var(--gray-100); color: var(--gray-500); }
}

.cred-status-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;

  &.cred-ok { background: var(--color-success-50); color: var(--color-success-700); }
  &.cred-soon { background: var(--color-warning-50); color: var(--color-warning-700); }
  &.cred-expired { background: var(--color-error-50); color: var(--color-error-700); }
  &.cred-none { background: var(--gray-100); color: var(--gray-500); }
  &.cred-memory { background: var(--color-warning-50); color: var(--color-warning-700); }
}

.restart-hint {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  margin-bottom: 16px;
  border-radius: 6px;
  background: var(--color-warning-50);
  border: 1px solid var(--color-warning-200);
  font-size: 13px;
  color: var(--color-warning-700);
}

.diagnostic-title-icon {
  vertical-align: -3px;
  margin-right: 4px;
  color: var(--main-color);
}

.diagnostic-content {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.diagnostic-meta {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;

  @media (max-width: 767px) {
    grid-template-columns: 1fr;
  }
}

.diagnostic-meta-item {
  display: flex;
  flex-direction: column;
  gap: 2px;

  .diagnostic-meta-label {
    font-size: 12px;
    color: var(--gray-600);
    font-weight: 500;
  }

  .diagnostic-meta-value {
    font-size: 14px;
    color: var(--gray-1000);

    &.mono {
      font-family: monospace;
      font-size: 13px;
    }
  }
}

.diagnostic-checks {
  display: flex;
  flex-direction: column;
  gap: 8px;
  border-top: 1px solid var(--gray-150);
  padding-top: 12px;
}

.diagnostic-check-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 6px;
  background: var(--gray-25);

  &.diagnostic-check--pass {
    border-left: 3px solid var(--color-success-500);
  }

  &.diagnostic-check--warn {
    border-left: 3px solid var(--color-warning-500);
    background: var(--color-warning-50);
  }

  &.diagnostic-check--fail {
    border-left: 3px solid var(--color-error-500);
    background: var(--color-error-50);
  }

  &.diagnostic-check--info {
    border-left: 3px solid var(--color-info-500);
  }
}

.diagnostic-check-icon {
  font-size: 16px;
  line-height: 1.4;
  flex-shrink: 0;
}

.diagnostic-check-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.diagnostic-check-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--gray-1000);
}

.diagnostic-check-detail {
  font-size: 12px;
  color: var(--gray-600);
}

.diagnostic-empty {
  text-align: center;
  padding: 32px;
  color: var(--gray-500);
  font-size: 14px;
}
</style>