import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'

import { useSystemState } from '../../composables/useSystemState.js'
import { useToast } from '../../composables/useToast.js'
import {
  activateAgentAsset,
  createAgentAssetReview,
  createAgentAssetVersion,
  fetchAgentAssetDetail,
  fetchAgentAssets,
  fetchAgentRuns
} from '../../services/agentAssets.js'
import { isManagerUser } from '../../utils/accessControl.js'

const TYPE_META = {
  rules: {
    assetType: 'rule',
    label: '规则',
    typeLabel: '规则',
    createButtonLabel: '规则已接入',
    hintText: '规则列表已接到真实资产 API，可查看 Markdown、版本、审核状态和上线约束。',
    searchPlaceholder: '搜索规则名称、编码或负责人',
    tableColumns: {
      name: '规则名称',
      category: '业务域',
      owner: '负责人',
      scope: '适用场景',
      runtime: '风险等级',
      version: '当前版本',
      metric: '审核状态'
    }
  },
  skills: {
    assetType: 'skill',
    label: '技能',
    typeLabel: '技能',
    createButtonLabel: '技能已接入',
    hintText: '技能页签已接到真实资产 API，可查看输入、输出、依赖和场景信息。',
    searchPlaceholder: '搜索技能名称、编码或负责人',
    tableColumns: {
      name: '技能名称',
      category: '业务域',
      owner: '负责人',
      scope: '适用场景',
      runtime: '输入摘要',
      version: '当前版本',
      metric: '输出摘要'
    }
  },
  mcp: {
    assetType: 'mcp',
    label: 'MCP',
    typeLabel: 'MCP',
    createButtonLabel: 'MCP 已接入',
    hintText: 'MCP 页签已接到真实资产 API，可查看服务地址、鉴权方式、超时和降级策略。',
    searchPlaceholder: '搜索 MCP 名称、编码或负责人',
    tableColumns: {
      name: 'MCP 服务',
      category: '业务域',
      owner: '维护人',
      scope: '适用场景',
      runtime: '调用地址',
      version: '当前版本',
      metric: '超时配置'
    }
  },
  tasks: {
    assetType: 'task',
    label: '任务',
    typeLabel: '任务',
    createButtonLabel: '任务已接入',
    hintText: '任务页签已接到真实资产 API，可查看调度周期、执行 Agent 和最近执行结果。',
    searchPlaceholder: '搜索任务名称、编码或负责人',
    tableColumns: {
      name: '任务名称',
      category: '业务域',
      owner: '负责人',
      scope: '适用场景',
      runtime: '调度周期',
      version: '当前版本',
      metric: '执行 Agent'
    }
  }
}

const BADGE_TONES = {
  rules: 'emerald',
  skills: 'blue',
  mcp: 'amber',
  tasks: 'violet'
}

const STATUS_META = {
  draft: { label: '草稿中', tone: 'draft' },
  review: { label: '待审核', tone: 'warning' },
  active: { label: '已上线', tone: 'success' },
  disabled: { label: '已停用', tone: 'disabled' }
}

const REVIEW_META = {
  approved: { label: '已通过', tone: 'success' },
  pending: { label: '待审核', tone: 'warning' },
  rejected: { label: '已驳回', tone: 'danger' }
}

const DOMAIN_LABELS = {
  expense: '报销',
  ar: '应收',
  ap: '应付',
  knowledge: '知识',
  system: '系统'
}

const SCENARIO_LABELS = {
  expense: '报销',
  risk_check: '风险检查',
  duplicate_expense: '重复报销',
  explain: '规则解释',
  invoice_anomaly: '票据异常',
  accounts_payable: '应付',
  accounts_receivable: '应收',
  approval_required: '需审批',
  query: '查询',
  summary: '汇总',
  system: '系统',
  schedule: '调度',
  rule_center: '规则中心',
  review_digest: '待审摘要',
  aging_summary: '账龄汇总',
  invoice_validation: '发票验真'
}

const DETAIL_TITLES = {
  rules: {
    configTitle: '规则元信息',
    configDesc: '展示规则编码、版本、业务域和当前审核 / 上线状态。',
    detailTitle: '规则版本说明',
    detailDesc: '规则正文由 Markdown 驱动，保存后会生成新的版本快照。',
    outputTitle: '审核与上线',
    outputDesc: '规则上线受审核状态控制，未审核通过的版本会被后端拦截。',
    ruleListTitle: '上线要求',
    checkListTitle: '当前状态',
    triggerTitle: '适用场景',
    triggerDesc: '当前规则注册到的业务场景',
    toolTitle: '关联信息',
    toolDesc: '规则当前审核、保存和版本快照信息',
    historyTitle: '版本历史',
    historyDesc: '最近 5 个规则版本',
    publishTitle: '上线控制',
    publishDesc: '正式上线会调用后端激活接口，审核未通过时会被拦截。'
  },
  skills: {
    configTitle: '技能配置',
    configDesc: '展示技能编码、输入摘要、版本和业务域。',
    detailTitle: '技能结构',
    detailDesc: '按输入、输出和依赖组织技能定义。',
    outputTitle: '输出契约',
    outputDesc: '技能详情重点展示输入参数、输出参数和依赖能力。',
    ruleListTitle: '输出要求',
    checkListTitle: '当前快照',
    triggerTitle: '适用场景',
    triggerDesc: '当前技能注册到的场景标签',
    toolTitle: '依赖能力',
    toolDesc: '技能当前依赖的数据库或其他能力',
    historyTitle: '版本历史',
    historyDesc: '最近版本记录',
    publishTitle: '发布状态',
    publishDesc: '技能当前状态由资产中心统一管理。'
  },
  mcp: {
    configTitle: 'MCP 连接配置',
    configDesc: '展示服务地址、超时和调用方式。',
    detailTitle: '服务协议',
    detailDesc: '按服务类型、鉴权方式和降级策略组织外部服务信息。',
    outputTitle: '调用约束',
    outputDesc: 'MCP 详情重点展示鉴权方式、返回策略和最近调用状态。',
    ruleListTitle: '调用约束',
    checkListTitle: '最近状态',
    triggerTitle: '适用场景',
    triggerDesc: '当前 MCP 覆盖的业务场景',
    toolTitle: '运行信息',
    toolDesc: '结合 AgentRun 中的 ToolCall 还原最近一次调用状态',
    historyTitle: '版本历史',
    historyDesc: '最近版本记录',
    publishTitle: '服务状态',
    publishDesc: 'MCP 资产已接入规则中心，但真实外部调用仍以后续链路集成为准。'
  },
  tasks: {
    configTitle: '任务配置',
    configDesc: '展示调度周期、执行 Agent 和任务编码。',
    detailTitle: '任务结构',
    detailDesc: '按调度计划、目标场景和运行结果组织任务信息。',
    outputTitle: '运行要求',
    outputDesc: '任务详情重点展示调度 Agent、最近运行结果和运行日志入口。',
    ruleListTitle: '运行要求',
    checkListTitle: '最近执行',
    triggerTitle: '适用场景',
    triggerDesc: '当前任务覆盖的业务场景',
    toolTitle: '最近调用',
    toolDesc: '根据 AgentRun 中的最近执行记录回显任务运行情况',
    historyTitle: '版本历史',
    historyDesc: '最近版本记录',
    publishTitle: '调度状态',
    publishDesc: '任务资产已接入规则中心，后续 Day 4 运行时会继续消费这些配置。'
  }
}

const STATUS_OPTIONS = [
  { value: '', label: '全部状态' },
  { value: 'draft', label: '草稿中' },
  { value: 'review', label: '待审核' },
  { value: 'active', label: '已上线' },
  { value: 'disabled', label: '已停用' }
]

function normalizeText(value) {
  return String(value || '').trim()
}

function makeShort(value) {
  const text = normalizeText(value).replace(/\s+/g, '')
  if (!text) {
    return 'AG'
  }
  return text.slice(0, 2).toUpperCase()
}

function formatDateTime(value) {
  if (!value) {
    return '未记录'
  }

  const date = new Date(value)
  if (Number.isNaN(date.getTime())) {
    return String(value)
  }

  return new Intl.DateTimeFormat('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    hour12: false
  })
    .format(date)
    .replace(/\//g, '-')
}

function resolveDomainLabel(value) {
  return DOMAIN_LABELS[value] || normalizeText(value) || '未分类'
}

function resolveStatusMeta(value) {
  return STATUS_META[value] || { label: normalizeText(value) || '未知状态', tone: 'draft' }
}

function resolveReviewMeta(value) {
  return REVIEW_META[value] || { label: '暂无审核', tone: 'draft' }
}

function formatScenarioList(items) {
  if (!Array.isArray(items) || !items.length) {
    return '未配置场景'
  }

  return items
    .map((item) => SCENARIO_LABELS[item] || item)
    .filter(Boolean)
    .join(' / ')
}

function buildHistory(recentVersions = []) {
  return recentVersions.map((item) => ({
    version: item.version,
    note: item.change_note || '无版本说明',
    time: formatDateTime(item.created_at),
    content: item.content,
    contentType: item.content_type,
    createdBy: item.created_by,
    isCurrent: Boolean(item.is_current)
  }))
}

function resolveTypeKey(assetType) {
  if (assetType === 'rule') {
    return 'rules'
  }
  if (assetType === 'skill') {
    return 'skills'
  }
  if (assetType === 'mcp') {
    return 'mcp'
  }
  return 'tasks'
}

function formatSeverity(value) {
  const severity = normalizeText(value).toLowerCase()
  if (severity === 'high') {
    return '高风险'
  }
  if (severity === 'medium') {
    return '中风险'
  }
  if (severity === 'low') {
    return '低风险'
  }
  return '未配置'
}

function formatInputSummary(items) {
  if (!Array.isArray(items) || !items.length) {
    return '无输入'
  }
  return `${items.length} 项输入`
}

function formatOutputSummary(items) {
  if (!Array.isArray(items) || !items.length) {
    return '无输出'
  }
  return `${items.length} 项输出`
}

function formatTaskRisk(scenarios) {
  if (Array.isArray(scenarios) && scenarios.includes('risk_check')) {
    return '高风险'
  }
  if (
    Array.isArray(scenarios) &&
    (scenarios.includes('accounts_receivable') || scenarios.includes('accounts_payable'))
  ) {
    return '中风险'
  }
  return '常规'
}

function findLatestTaskRun(runs, assetId) {
  return runs.find((item) => item.task_id === assetId) || null
}

function findLatestMcpCall(runs, assetCode) {
  const expectedToolName = normalizeText(assetCode).replace(/^mcp\./, '')

  for (const run of runs) {
    for (const toolCall of run.tool_calls || []) {
      const toolName = normalizeText(toolCall.tool_name)
      if (
        toolName === expectedToolName ||
        toolName.endsWith(expectedToolName) ||
        expectedToolName.endsWith(toolName)
      ) {
        return {
          run,
          toolCall
        }
      }
    }
  }

  return null
}

function buildRowRuntime(asset, typeKey) {
  if (typeKey === 'rules') {
    return formatSeverity(asset.config_json?.severity)
  }
  if (typeKey === 'skills') {
    return formatInputSummary(asset.config_json?.input_schema)
  }
  if (typeKey === 'mcp') {
    return normalizeText(asset.config_json?.endpoint) || '未配置地址'
  }
  return normalizeText(asset.config_json?.cron) || '未配置调度'
}

function buildRowMetric(asset, typeKey) {
  if (typeKey === 'rules') {
    return asset.reviewer ? `审核人：${asset.reviewer}` : '待分配审核人'
  }
  if (typeKey === 'skills') {
    return '进入详情查看输出'
  }
  if (typeKey === 'mcp') {
    return asset.config_json?.timeout_ms ? `${asset.config_json.timeout_ms} ms` : '未配置超时'
  }
  return normalizeText(asset.config_json?.agent) || '未配置 Agent'
}

function buildListItem(asset) {
  const typeKey = resolveTypeKey(asset.asset_type)
  const statusMeta = resolveStatusMeta(asset.status)

  return {
    id: asset.id,
    type: typeKey,
    typeLabel: TYPE_META[typeKey].typeLabel,
    short: makeShort(asset.name),
    name: asset.name,
    code: asset.code,
    summary: asset.description,
    category: resolveDomainLabel(asset.domain),
    owner: asset.owner,
    reviewer: asset.reviewer || '待分配',
    scope: formatScenarioList(asset.scenario_json),
    model: buildRowRuntime(asset, typeKey),
    version: asset.current_version || '-',
    status: statusMeta.label,
    statusValue: asset.status,
    statusTone: statusMeta.tone,
    hitRate: buildRowMetric(asset, typeKey),
    updatedAt: formatDateTime(asset.updated_at),
    badgeTone: BADGE_TONES[typeKey],
    spotlight: asset.status === 'active',
    domainValue: asset.domain
  }
}

function buildRuleFields(detail) {
  return [
    { label: '规则编码', value: detail.code },
    { label: '业务域', value: resolveDomainLabel(detail.domain) },
    { label: '适用场景', value: formatScenarioList(detail.scenario_json) },
    { label: '当前版本', value: detail.current_version || '-' }
  ]
}

function buildSkillFields(detail) {
  const content = detail.current_version_content || {}
  return [
    { label: '技能编码', value: detail.code },
    { label: '业务域', value: resolveDomainLabel(detail.domain) },
    {
      label: '输入参数',
      value: Array.isArray(content.inputs) && content.inputs.length ? content.inputs.join('、') : '未配置'
    },
    {
      label: '输出参数',
      value: Array.isArray(content.outputs) && content.outputs.length ? content.outputs.join('、') : '未配置'
    }
  ]
}

function buildMcpFields(detail, latestCall) {
  const content = detail.current_version_content || {}
  return [
    { label: '服务编码', value: detail.code },
    { label: '调用地址', value: normalizeText(detail.config_json?.endpoint) || '未配置' },
    { label: '鉴权方式', value: normalizeText(content.auth_mode) || '未配置' },
    {
      label: '最近调用',
      value: latestCall ? `${latestCall.toolCall.status} / ${formatDateTime(latestCall.run.started_at)}` : '暂无调用记录'
    }
  ]
}

function buildTaskFields(detail, latestRun) {
  const content = detail.current_version_content || {}
  return [
    { label: '任务编码', value: detail.code },
    { label: 'Cron', value: normalizeText(detail.config_json?.cron) || normalizeText(content.schedule) || '未配置' },
    { label: '执行 Agent', value: normalizeText(detail.config_json?.agent) || normalizeText(content.target_agent) || '未配置' },
    { label: '风险等级', value: formatTaskRisk(detail.scenario_json) },
    {
      label: '最近执行',
      value: latestRun ? formatDateTime(latestRun.started_at) : '暂无执行记录'
    }
  ]
}

function buildFields(detail, typeKey, latestRun, latestCall) {
  if (typeKey === 'rules') {
    return buildRuleFields(detail)
  }
  if (typeKey === 'skills') {
    return buildSkillFields(detail)
  }
  if (typeKey === 'mcp') {
    return buildMcpFields(detail, latestCall)
  }
  return buildTaskFields(detail, latestRun)
}

function buildPromptSections(detail, typeKey, latestRun, latestCall) {
  const content = detail.current_version_content || {}

  if (typeKey === 'skills') {
    return [
      {
        title: '输入参数',
        intent: '技能入口',
        content: Array.isArray(content.inputs) && content.inputs.length ? content.inputs.join('\n') : '未配置输入参数。'
      },
      {
        title: '输出参数',
        intent: '技能产出',
        content: Array.isArray(content.outputs) && content.outputs.length ? content.outputs.join('\n') : '未配置输出参数。'
      },
      {
        title: '依赖能力',
        intent: '外部依赖',
        content:
          Array.isArray(content.dependencies) && content.dependencies.length
            ? content.dependencies.join('\n')
            : '当前技能未声明外部依赖。'
      }
    ]
  }

  if (typeKey === 'mcp') {
    return [
      {
        title: '服务类型',
        intent: '协议说明',
        content: normalizeText(content.service_type) || '未配置服务类型。'
      },
      {
        title: '鉴权方式',
        intent: '安全要求',
        content: normalizeText(content.auth_mode) || '未配置鉴权方式。'
      },
      {
        title: '降级策略',
        intent: '失败处理',
        content: normalizeText(content.degrade_strategy) || '未配置降级策略。'
      }
    ]
  }

  return [
    {
      title: '任务场景',
      intent: '调度目标',
      content: formatScenarioList(detail.scenario_json)
    },
    {
      title: '执行 Agent',
      intent: '运行主体',
      content: normalizeText(content.target_agent) || normalizeText(detail.config_json?.agent) || '未配置执行 Agent。'
    },
    {
      title: '最近执行结果',
      intent: '运行反馈',
      content: latestRun?.result_summary || latestRun?.error_message || '暂无执行记录。'
    }
  ]
}

function buildOutputRules(detail, typeKey, latestRun, latestCall) {
  const content = detail.current_version_content || {}

  if (typeKey === 'rules') {
    return [
      '规则 Markdown 保存后会生成新版本。',
      '未审核通过的规则版本不能正式上线。',
      '版本切换当前只影响前端展示内容，不会直接回滚后端版本。'
    ]
  }

  if (typeKey === 'skills') {
    return [
      `输入参数：${Array.isArray(content.inputs) && content.inputs.length ? content.inputs.join('、') : '未配置'}`,
      `输出参数：${Array.isArray(content.outputs) && content.outputs.length ? content.outputs.join('、') : '未配置'}`,
      `依赖能力：${Array.isArray(content.dependencies) && content.dependencies.length ? content.dependencies.join('、') : '未声明'}`
    ]
  }

  if (typeKey === 'mcp') {
    return [
      `服务地址：${normalizeText(detail.config_json?.endpoint) || '未配置'}`,
      `鉴权方式：${normalizeText(content.auth_mode) || '未配置'}`,
      `降级策略：${normalizeText(content.degrade_strategy) || '未配置'}`
    ]
  }

  return [
    `调度周期：${normalizeText(detail.config_json?.cron) || normalizeText(content.schedule) || '未配置'}`,
    `执行 Agent：${normalizeText(detail.config_json?.agent) || normalizeText(content.target_agent) || '未配置'}`,
    `风险等级：${formatTaskRisk(detail.scenario_json)}`,
    `最近执行结果：${latestRun?.status || '暂无执行记录'}`
  ]
}

function buildTests(detail, typeKey, latestRun, latestCall) {
  if (typeKey === 'rules') {
    const reviewMeta = resolveReviewMeta(detail.latest_review?.review_status)
    return [
      {
        name: '审核状态',
        input: detail.latest_review?.version || detail.current_version || '暂无版本',
        result: reviewMeta.label,
        tone: reviewMeta.tone
      },
      {
        name: '上线状态',
        input: detail.current_version || '暂无版本',
        result: resolveStatusMeta(detail.status).label,
        tone: resolveStatusMeta(detail.status).tone
      }
    ]
  }

  if (typeKey === 'skills') {
    const content = detail.current_version_content || {}
    return [
      {
        name: '输入数量',
        input: detail.current_version || '暂无版本',
        result: `${content.inputs?.length || 0} 项`,
        tone: 'success'
      },
      {
        name: '输出数量',
        input: detail.current_version || '暂无版本',
        result: `${content.outputs?.length || 0} 项`,
        tone: 'success'
      }
    ]
  }

  if (typeKey === 'mcp') {
    return [
      {
        name: '最近调用状态',
        input: latestCall?.run?.run_id || '暂无调用',
        result: latestCall?.toolCall?.status || '未记录',
        tone: latestCall?.toolCall?.status === 'failed' ? 'danger' : 'success'
      },
      {
        name: '最近调用耗时',
        input: latestCall?.toolCall?.tool_name || '暂无调用',
        result:
          typeof latestCall?.toolCall?.duration_ms === 'number'
            ? `${latestCall.toolCall.duration_ms} ms`
            : '未记录',
        tone: 'success'
      }
    ]
  }

  return [
    {
      name: '最近运行状态',
      input: latestRun?.run_id || '暂无运行',
      result: latestRun?.status || '未记录',
      tone: latestRun?.status === 'failed' || latestRun?.status === 'blocked' ? 'danger' : 'success'
    },
    {
      name: '结果摘要',
      input: latestRun?.agent || normalizeText(detail.config_json?.agent) || '未配置',
      result: latestRun?.result_summary || '暂无摘要',
      tone: 'success'
    }
  ]
}

function buildTools(detail, typeKey, latestRun, latestCall) {
  const content = detail.current_version_content || {}

  if (typeKey === 'skills') {
    return (content.dependencies || []).map((item) => ({
      name: item,
      scope: '技能依赖',
      mode: '读取',
      tone: 'safe'
    }))
  }

  if (typeKey === 'mcp') {
    return [
      {
        name: normalizeText(content.service_type) || '未配置服务类型',
        scope: '服务类型',
        mode: 'MCP',
        tone: 'active'
      },
      {
        name: normalizeText(content.auth_mode) || '未配置鉴权方式',
        scope: '鉴权',
        mode: '安全',
        tone: 'safe'
      },
      {
        name: latestCall?.run?.run_id || '暂无调用记录',
        scope: '最近 Run',
        mode: latestCall?.toolCall?.status || '未执行',
        tone: latestCall?.toolCall?.status === 'failed' ? 'danger' : 'active'
      }
    ]
  }

  return [
    {
      name: normalizeText(detail.config_json?.agent) || normalizeText(content.target_agent) || '未配置 Agent',
      scope: '执行 Agent',
      mode: '调度',
      tone: 'active'
    },
    {
      name: latestRun?.run_id || '暂无执行记录',
      scope: '最近 Run',
      mode: latestRun?.status || '未执行',
      tone: latestRun?.status === 'failed' || latestRun?.status === 'blocked' ? 'danger' : 'active'
    },
    {
      name: latestRun?.permission_level || '未记录',
      scope: '权限级别',
      mode: 'Trace',
      tone: 'safe'
    }
  ]
}

function buildPublishDescription(detail, typeKey) {
  if (typeKey === 'rules') {
    if (detail.status === 'active') {
      return '当前规则版本已经上线，仍可继续保存新版本并重新走审核。'
    }
    return '当前规则需要先完成审核，再调用上线接口正式激活。'
  }

  return DETAIL_TITLES[typeKey].publishDesc
}

function buildDetailViewModel(detail, runs) {
  const typeKey = resolveTypeKey(detail.asset_type)
  const latestRun = typeKey === 'tasks' ? findLatestTaskRun(runs, detail.id) : null
  const latestCall = typeKey === 'mcp' ? findLatestMcpCall(runs, detail.code) : null
  const statusMeta = resolveStatusMeta(detail.status)
  const reviewMeta = resolveReviewMeta(detail.latest_review?.review_status)
  const history = buildHistory(detail.recent_versions || [])
  const previewVersion = history.find((item) => item.isCurrent) || history[0] || null
  const previewMarkdown =
    detail.current_version_content_type === 'markdown'
      ? String(previewVersion?.content ?? detail.current_version_content ?? '')
      : ''
  const titles = DETAIL_TITLES[typeKey]

  return {
    id: detail.id,
    type: typeKey,
    typeLabel: TYPE_META[typeKey].typeLabel,
    short: makeShort(detail.name),
    name: detail.name,
    code: detail.code,
    summary: detail.description,
    owner: detail.owner,
    reviewer: detail.reviewer || detail.latest_review?.reviewer || '待分配',
    category: resolveDomainLabel(detail.domain),
    scope: formatScenarioList(detail.scenario_json),
    version: detail.current_version || '-',
    currentVersion: detail.current_version || '-',
    displayVersion: previewVersion?.version || detail.current_version || '-',
    status: statusMeta.label,
    statusValue: detail.status,
    statusTone: statusMeta.tone,
    hitRate: buildRowMetric(detail, typeKey),
    updatedAt: formatDateTime(detail.updated_at),
    badgeTone: BADGE_TONES[typeKey],
    markdownContent: previewMarkdown,
    currentVersionContentType: detail.current_version_content_type,
    currentVersionChangeNote: detail.current_version_change_note || '无版本说明',
    reviewStatusLabel: reviewMeta.label,
    reviewStatusTone: reviewMeta.tone,
    reviewStatusValue: detail.latest_review?.review_status || '',
    reviewTimeLabel: formatDateTime(detail.latest_review?.reviewed_at),
    reviewNote: detail.latest_review?.review_note || '',
    latestRun,
    latestCall,
    fields: buildFields(detail, typeKey, latestRun, latestCall),
    promptSections:
      typeKey === 'rules' ? [] : buildPromptSections(detail, typeKey, latestRun, latestCall),
    outputRules: buildOutputRules(detail, typeKey, latestRun, latestCall),
    tests: buildTests(detail, typeKey, latestRun, latestCall),
    triggers: detail.scenario_json?.length ? detail.scenario_json.map((item) => SCENARIO_LABELS[item] || item) : ['未配置场景'],
    tools:
      typeKey === 'rules'
        ? [
            {
              name: detail.latest_review?.reviewer || '待分配审核人',
              scope: '审核负责人',
              mode: reviewMeta.label,
              tone: reviewMeta.tone
            },
            {
              name: detail.current_version || '暂无版本',
              scope: '当前版本',
              mode: detail.current_version_change_note || '无版本说明',
              tone: 'safe'
            }
          ]
        : buildTools(detail, typeKey, latestRun, latestCall),
    history,
    configTitle: titles.configTitle,
    configDesc: titles.configDesc,
    detailTitle: titles.detailTitle,
    detailDesc: titles.detailDesc,
    outputTitle: titles.outputTitle,
    outputDesc: titles.outputDesc,
    ruleListTitle: titles.ruleListTitle,
    checkListTitle: titles.checkListTitle,
    triggerTitle: titles.triggerTitle,
    triggerDesc: titles.triggerDesc,
    toolTitle: titles.toolTitle,
    toolDesc: titles.toolDesc,
    historyTitle: titles.historyTitle,
    historyDesc: titles.historyDesc,
    publishTitle: titles.publishTitle,
    publishDesc: buildPublishDescription(detail, typeKey),
    publishMeta:
      typeKey === 'rules'
        ? `最近保存：${formatDateTime(detail.updated_at)}`
        : latestRun
          ? `最近运行：${formatDateTime(latestRun.started_at)}`
          : `最近更新：${formatDateTime(detail.updated_at)}`,
    publishState: statusMeta.label,
    latestReviewVersion: detail.latest_review?.version || detail.current_version || '-',
    loading: false
  }
}

function incrementVersion(version) {
  const normalized = normalizeText(version).replace(/^v/i, '')
  const match = normalized.match(/^(\d+)\.(\d+)\.(\d+)$/)

  if (!match) {
    return 'v1.0.0'
  }

  const major = Number(match[1])
  const minor = Number(match[2])
  const patch = Number(match[3]) + 1
  return `v${major}.${minor}.${patch}`
}

function buildReviewNote(status) {
  if (status === 'approved') {
    return '通过任务规则中心审核。'
  }
  if (status === 'rejected') {
    return '在任务规则中心驳回当前版本。'
  }
  return '提交任务规则中心待审核。'
}

export default {
  name: 'AuditView',
  emits: ['detail-open-change'],
  setup(_, { emit }) {
    const { toast } = useToast()
    const { currentUser } = useSystemState()

    const tabs = Object.entries(TYPE_META).map(([id, meta]) => ({
      id,
      label: meta.label
    }))

    const activeType = ref('rules')
    const selectedSkill = ref(null)
    const versionSwitchTarget = ref(null)
    const keyword = ref('')
    const activeFilterPopover = ref('')
    const selectedDomain = ref('')
    const selectedOwner = ref('')
    const selectedStatus = ref('')
    const loading = ref(false)
    const errorMessage = ref('')
    const detailLoading = ref(false)
    const detailError = ref('')
    const actionState = ref('')
    const runLoading = ref(false)
    const runs = ref([])
    const assetBuckets = ref({
      rules: [],
      skills: [],
      mcp: [],
      tasks: []
    })

    const isAdmin = computed(() => isManagerUser(currentUser.value))
    const activeMeta = computed(() => TYPE_META[activeType.value])
    const activeTabLabel = computed(() => activeMeta.value.label)
    const currentAssets = computed(() => assetBuckets.value[activeType.value] || [])
    const searchPlaceholder = computed(() => activeMeta.value.searchPlaceholder)
    const createButtonLabel = computed(() => activeMeta.value.createButtonLabel)
    const hintText = computed(() => activeMeta.value.hintText)
    const tableColumns = computed(() => activeMeta.value.tableColumns)
    const selectedSkillIsRule = computed(() => selectedSkill.value?.type === 'rules')
    const canManageSelected = computed(() => isAdmin.value && Boolean(selectedSkill.value))
    const canEditMarkdown = computed(() => canManageSelected.value && selectedSkillIsRule.value)
    const detailBusy = computed(() => Boolean(actionState.value))
    const showReviewNote = computed(
      () => selectedSkillIsRule.value && (selectedSkill.value?.reviewNote || selectedSkill.value?.reviewTimeLabel)
    )
    const domainOptions = computed(() => {
      const uniqueValues = [...new Set(currentAssets.value.map((item) => item.domainValue).filter(Boolean))]
      return [
        { value: '', label: '全部业务域' },
        ...uniqueValues.map((value) => ({
          value,
          label: resolveDomainLabel(value)
        }))
      ]
    })
    const ownerOptions = computed(() => {
      const uniqueOwners = [...new Set(currentAssets.value.map((item) => item.owner).filter(Boolean))]
      return [
        { value: '', label: '全部负责人' },
        ...uniqueOwners.map((value) => ({
          value,
          label: value
        }))
      ]
    })
    const selectedDomainLabel = computed(
      () => domainOptions.value.find((item) => item.value === selectedDomain.value)?.label || '业务域'
    )
    const selectedOwnerLabel = computed(
      () => ownerOptions.value.find((item) => item.value === selectedOwner.value)?.label || '负责人'
    )
    const selectedStatusLabel = computed(
      () => STATUS_OPTIONS.find((item) => item.value === selectedStatus.value)?.label || '状态'
    )
    const activeFilterTokens = computed(() => {
      const tokens = []

      if (selectedDomain.value) {
        tokens.push(`业务域：${resolveDomainLabel(selectedDomain.value)}`)
      }
      if (selectedStatus.value) {
        tokens.push(`状态：${resolveStatusMeta(selectedStatus.value).label}`)
      }
      if (selectedOwner.value) {
        tokens.push(`负责人：${selectedOwner.value}`)
      }
      if (keyword.value.trim()) {
        tokens.push(`搜索：${keyword.value.trim()}`)
      }

      return tokens
    })
    const canActivateSelected = computed(() => {
      if (!selectedSkillIsRule.value || !canManageSelected.value || detailBusy.value) {
        return false
      }

      return selectedSkill.value?.reviewStatusValue === 'approved' && selectedSkill.value?.statusValue !== 'active'
    })
    const activateBlockedReason = computed(() => {
      if (!selectedSkillIsRule.value) {
        return ''
      }
      if (!canManageSelected.value) {
        return '仅管理员可执行审核和上线。'
      }
      if (selectedSkill.value?.statusValue === 'active') {
        return '当前规则版本已经上线。'
      }
      if (selectedSkill.value?.reviewStatusValue !== 'approved') {
        return '当前规则版本未审核通过，不能上线。'
      }
      return ''
    })
    const visibleSkills = computed(() => {
      const normalizedKeyword = keyword.value.trim().toLowerCase()

      return currentAssets.value.filter((item) => {
        const matchesKeyword = normalizedKeyword
          ? [item.name, item.code, item.summary, item.owner, item.scope]
              .filter(Boolean)
              .some((value) => String(value).toLowerCase().includes(normalizedKeyword))
          : true
        const matchesDomain = selectedDomain.value ? item.domainValue === selectedDomain.value : true
        const matchesOwner = selectedOwner.value ? item.owner === selectedOwner.value : true
        const matchesStatus = selectedStatus.value ? item.statusValue === selectedStatus.value : true

        return matchesKeyword && matchesDomain && matchesOwner && matchesStatus
      })
    })

    watch(
      selectedSkill,
      (value) => {
        emit('detail-open-change', Boolean(value))
      },
      { immediate: true }
    )

    watch(activeType, () => {
      selectedSkill.value = null
      versionSwitchTarget.value = null
      resetFilters()
      loadAssets({ force: true }).catch((error) => {
        errorMessage.value = error?.message || '资产数据加载失败，请稍后重试。'
      })
    })

    function resetFilters() {
      keyword.value = ''
      selectedDomain.value = ''
      selectedOwner.value = ''
      selectedStatus.value = ''
      activeFilterPopover.value = ''
    }

    function toggleFilterPopover(name) {
      activeFilterPopover.value = activeFilterPopover.value === name ? '' : name
    }

    function closeFilterPopover() {
      activeFilterPopover.value = ''
    }

    function selectFilter(name, value) {
      if (name === 'domain') {
        selectedDomain.value = value
      }
      if (name === 'owner') {
        selectedOwner.value = value
      }
      if (name === 'status') {
        selectedStatus.value = value
      }
      closeFilterPopover()
    }

    function handleDocumentClick(event) {
      const target = event.target
      if (!(target instanceof Element)) {
        closeFilterPopover()
        return
      }
      if (!target.closest('.picker-filter')) {
        closeFilterPopover()
      }
    }

    function resolveActor() {
      return currentUser.value?.name || currentUser.value?.username || 'system'
    }

    async function loadRuns(options = {}) {
      if (runLoading.value && !options.force) {
        return
      }

      runLoading.value = true
      try {
        const payload = await fetchAgentRuns({ limit: 50 })
        runs.value = Array.isArray(payload) ? payload : []
      } finally {
        runLoading.value = false
      }
    }

    async function loadAssets(options = {}) {
      loading.value = true
      errorMessage.value = ''

      try {
        const payload = await fetchAgentAssets({ assetType: activeMeta.value.assetType })
        assetBuckets.value = {
          ...assetBuckets.value,
          [activeType.value]: Array.isArray(payload) ? payload.map(buildListItem) : []
        }
      } catch (error) {
        assetBuckets.value = {
          ...assetBuckets.value,
          [activeType.value]: []
        }
        errorMessage.value = error?.message || '资产数据加载失败，请稍后重试。'
        if (!options.silent) {
          toast(errorMessage.value)
        }
      } finally {
        loading.value = false
      }
    }

    async function refreshCurrentAssets() {
      await loadAssets({ force: true, silent: true })
    }

    async function loadSelectedAssetDetail(assetId) {
      detailLoading.value = true
      detailError.value = ''

      try {
        if (!runs.value.length) {
          await loadRuns()
        }
        const detail = await fetchAgentAssetDetail(assetId)
        selectedSkill.value = buildDetailViewModel(detail, runs.value)
      } catch (error) {
        detailError.value = error?.message || '资产详情加载失败，请稍后重试。'
        toast(detailError.value)
      } finally {
        detailLoading.value = false
      }
    }

    function openAssetDetail(asset) {
      selectedSkill.value = {
        ...asset,
        fields: [],
        promptSections: [],
        outputRules: [],
        tests: [],
        triggers: [],
        tools: [],
        history: [],
        markdownContent: '',
        displayVersion: asset.version,
        loading: true,
        reviewStatusLabel: '加载中',
        reviewStatusTone: 'draft'
      }
      versionSwitchTarget.value = null
      loadSelectedAssetDetail(asset.id).catch(() => {})
    }

    function closeDetail() {
      selectedSkill.value = null
      detailError.value = ''
      detailLoading.value = false
      versionSwitchTarget.value = null
    }

    function openVersionSwitch(version) {
      if (!selectedSkill.value || version.version === selectedSkill.value.displayVersion) {
        return
      }
      versionSwitchTarget.value = version
    }

    function cancelVersionSwitch() {
      versionSwitchTarget.value = null
    }

    function confirmVersionSwitch() {
      if (!selectedSkill.value || !versionSwitchTarget.value) {
        return
      }

      selectedSkill.value.displayVersion = versionSwitchTarget.value.version
      if (typeof versionSwitchTarget.value.content === 'string') {
        selectedSkill.value.markdownContent = versionSwitchTarget.value.content
      }
      versionSwitchTarget.value = null
    }

    async function saveRuleMarkdown() {
      if (!selectedSkill.value || !selectedSkillIsRule.value || !canEditMarkdown.value || detailBusy.value) {
        return
      }

      if (!normalizeText(selectedSkill.value.markdownContent)) {
        toast('规则 Markdown 内容不能为空。')
        return
      }

      const nextVersion = incrementVersion(selectedSkill.value.currentVersion)
      actionState.value = 'save-markdown'

      try {
        await createAgentAssetVersion(
          selectedSkill.value.id,
          {
            version: nextVersion,
            content: selectedSkill.value.markdownContent,
            content_type: 'markdown',
            change_note: '通过任务规则中心保存 Markdown 规则内容。',
            created_by: resolveActor()
          },
          { actor: resolveActor() }
        )
        await refreshCurrentAssets()
        await loadSelectedAssetDetail(selectedSkill.value.id)
        toast(`规则 Markdown 已保存为 ${nextVersion}。`)
      } catch (error) {
        toast(error?.message || '规则 Markdown 保存失败，请稍后重试。')
      } finally {
        actionState.value = ''
      }
    }

    async function reviewSelectedRule(reviewStatus) {
      if (!selectedSkill.value || !selectedSkillIsRule.value || !canManageSelected.value || detailBusy.value) {
        return
      }

      actionState.value = `review-${reviewStatus}`

      try {
        await createAgentAssetReview(
          selectedSkill.value.id,
          {
            version: selectedSkill.value.displayVersion || selectedSkill.value.currentVersion,
            reviewer: resolveActor(),
            review_status: reviewStatus,
            review_note: buildReviewNote(reviewStatus)
          },
          { actor: resolveActor() }
        )
        await refreshCurrentAssets()
        await loadSelectedAssetDetail(selectedSkill.value.id)
        toast(`当前规则版本已标记为${resolveReviewMeta(reviewStatus).label}。`)
      } catch (error) {
        toast(error?.message || '规则审核提交失败，请稍后重试。')
      } finally {
        actionState.value = ''
      }
    }

    async function activateSelectedRule() {
      if (!selectedSkill.value || !selectedSkillIsRule.value || !canManageSelected.value || detailBusy.value) {
        return
      }

      actionState.value = 'activate'

      try {
        await activateAgentAsset(selectedSkill.value.id, { actor: resolveActor() })
        await refreshCurrentAssets()
        await loadSelectedAssetDetail(selectedSkill.value.id)
        toast('规则已正式上线。')
      } catch (error) {
        toast(error?.message || '规则上线失败，请稍后重试。')
      } finally {
        actionState.value = ''
      }
    }

    onMounted(() => {
      document.addEventListener('click', handleDocumentClick)
      loadAssets({ force: true }).catch(() => {})
      loadRuns().catch(() => {})
    })

    onBeforeUnmount(() => {
      document.removeEventListener('click', handleDocumentClick)
    })

    return {
      tabs,
      activeType,
      activeTabLabel,
      selectedSkill,
      versionSwitchTarget,
      keyword,
      createButtonLabel,
      hintText,
      searchPlaceholder,
      tableColumns,
      visibleSkills,
      loading,
      errorMessage,
      detailLoading,
      detailError,
      selectedDomain,
      selectedOwner,
      selectedStatus,
      selectedDomainLabel,
      selectedOwnerLabel,
      selectedStatusLabel,
      domainOptions,
      ownerOptions,
      statusOptions: STATUS_OPTIONS,
      activeFilterPopover,
      activeFilterTokens,
      canManageSelected,
      canEditMarkdown,
      canActivateSelected,
      activateBlockedReason,
      selectedSkillIsRule,
      detailBusy,
      actionState,
      showReviewNote,
      openAssetDetail,
      closeDetail,
      resetFilters,
      toggleFilterPopover,
      selectFilter,
      closeFilterPopover,
      openVersionSwitch,
      cancelVersionSwitch,
      confirmVersionSwitch,
      saveRuleMarkdown,
      reviewSelectedRule,
      activateSelectedRule,
      loadAssets
    }
  }
}
