const PROFILE_TYPE_LABELS = {
  expense: '费用申请',
  process_quality: '流程质量',
  ai_usage: 'AI 协作',
  approval: '审核行为'
}

const STATUS_LABELS = {
  succeeded: '已完成',
  success: '已完成',
  running: '进行中',
  blocked: '待确认',
  failed: '失败'
}

const STATUS_TONES = {
  succeeded: 'success',
  success: 'success',
  running: 'warning',
  blocked: 'warning',
  failed: 'danger'
}

const AGENT_LABELS = {
  hermes: 'Hermes 数字员工',
  user_agent: '智能问答助手',
  orchestrator: '智能编排服务',
  system: '系统服务'
}

const AGENT_SHORT_LABELS = {
  hermes: 'Hermes',
  user_agent: '问答助手',
  orchestrator: '编排服务',
  system: '系统服务'
}

const RADAR_COLORS = [
  '#3a7ca5',
  '#0f9f8f',
  '#f59e0b',
  '#7c3aed',
  '#dc2626',
  '#2563eb',
  '#16a34a',
  '#db2777'
]

const FINANCIAL_RADAR_CODES = [
  'expense_intensity',
  'application_rhythm',
  'travel_entertainment',
  'material_completeness',
  'process_pressure'
]

const GOVERNANCE_RADAR_CODES = [
  'ai_collaboration',
  'approval_efficiency',
  'approval_control'
]

export const USER_PROFILE_RADAR_VIEW_OPTIONS = [
  {
    value: 'financial_risk',
    label: '财务风险视角',
    shortLabel: '财务风险',
    description: '费用、材料和流程相关维度'
  },
  {
    value: 'collaboration_governance',
    label: '协作治理视角',
    shortLabel: '协作治理',
    description: 'AI 协作和审批治理维度'
  },
  {
    value: 'all_behavior',
    label: '全部行为视角',
    shortLabel: '全部行为',
    description: '展示全部可用画像维度'
  }
]

const TAG_ACCENT_COUNT = 8

const SOURCE_LABELS = {
  user_message: '用户对话',
  schedule: '定时任务',
  system_event: '系统事件',
  workbench: '个人工作台',
  detail: '单据详情',
  documents_application: '单据中心'
}

const SCENARIO_LABELS = {
  knowledge: '知识库问答',
  expense: '费用报销',
  reimbursement: '费用报销',
  expense_application: '费用申请',
  application: '费用申请',
  budget: '预算查询',
  audit: '风险审核',
  approval: '审批处理',
  policy: '制度问答',
  travel: '差旅费用',
  entertainment: '业务招待',
  accounts_receivable: '应收查询',
  accounts_payable: '应付查询'
}

const INTENT_LABELS = {
  query: '查询',
  explain: '解释',
  compare: '对比',
  risk_check: '风险检查',
  draft: '草稿生成',
  operate: '操作办理',
  review: '审核',
  submit: '提交'
}

const JOB_TYPE_LABELS = {
  knowledge_index_sync: '知识库索引同步',
  llm_wiki_sync: '知识库归纳同步',
  employee_behavior_profile_scan: '用户画像测算',
  workbench_on_demand: '工作台画像测算',
  global_risk_scan: '财务风险图谱巡检',
  weekly_expense_report: '周费用报告'
}

export function buildUserProfileMetricCards(profile, runs = [], currentUser = {}) {
  const index = indexProfiles(profile)
  const aiMetrics = metricsOf(index.ai_usage)
  const userRuns = filterRunsByCurrentUser(runs, currentUser)
  const windowedUserRuns = filterRunsByProfileWindow(userRuns, profile)
  const durationMs = resolveUsageDurationMs(aiMetrics, windowedUserRuns)
  const durationDisplay = formatDurationMetric(durationMs)
  const commonAgent = resolveCommonAgent(windowedUserRuns)
  const tokenCount = resolveNumber(aiMetrics.exact_token_count) || resolveNumber(aiMetrics.estimated_token_count)
  const tokenDisplay = formatTokenCount(tokenCount)
  const aiRunCount = resolveNumber(aiMetrics.ai_run_count) || windowedUserRuns.length

  return [
    {
      key: 'usage-duration',
      label: '使用时长',
      value: durationDisplay.value,
      unit: durationDisplay.unit,
      hint: resolveUsageDurationHint(aiMetrics, profile),
      icon: 'mdi mdi-timer-sand',
      tone: 'primary'
    },
    {
      key: 'common-agent',
      label: '常用智能体',
      value: commonAgent.label,
      unit: '',
      hint: commonAgent.count ? `${commonAgent.count} 次调用，占比 ${commonAgent.share}` : '暂无智能体调用记录',
      icon: 'mdi mdi-account-tie-voice-outline',
      tone: 'cyan'
    },
    {
      key: 'ai-usage',
      label: 'AI 使用次数',
      value: formatNumber(aiRunCount),
      unit: '次',
      hint: `近${resolveWindowDays(profile)}天智能协作记录`,
      icon: 'mdi mdi-robot-outline',
      tone: 'violet'
    },
    {
      key: 'token-usage',
      label: 'Token 消耗',
      value: tokenDisplay.value,
      unit: tokenDisplay.unit,
      hint: resolveTokenHint(aiMetrics),
      icon: 'mdi mdi-lightning-bolt-outline',
      tone: 'amber'
    }
  ]
}

export function buildUserProfileSummaryMetrics(profile, runs = [], currentUser = {}) {
  return buildUserProfileMetricCards(profile, runs, currentUser).slice(0, 4)
}

export function normalizeUserProfileTags(profile, limit = 8) {
  return (Array.isArray(profile?.profile_tags) ? profile.profile_tags : [])
    .map((tag) => ({
      code: normalizeText(tag.code || tag.label),
      label: normalizeText(tag.label),
      displayLabel: normalizeText(tag.display_label || tag.displayLabel || tag.label),
      category: normalizeCode(tag.category),
      tone: resolveTagTone(tag),
      score: clampScore(tag.score),
      reason: normalizeText(tag.reason) || '画像算法已识别该行为特征。',
      confidence: resolveNumber(tag.confidence),
      radarDimensions: normalizeRadarDimensions(tag)
    }))
    .filter((tag) => tag.code && tag.displayLabel)
    .sort((left, right) => right.score - left.score)
    .slice(0, limit)
    .map((tag, index) => ({
      ...tag,
      colorIndex: index % TAG_ACCENT_COUNT
    }))
}

export function normalizeUserProfileRadarDimensions(profile) {
  const dimensions = Array.isArray(profile?.radar?.dimensions) ? profile.radar.dimensions : []
  if (dimensions.length) {
    return withRadarColors(
      dimensions.map((item) => ({
        code: normalizeText(item.code || item.label),
        label: normalizeText(item.label || item.code),
        score: clampScore(item.score)
      }))
    )
  }

  return withRadarColors(
    (Array.isArray(profile?.profiles) ? profile.profiles : [])
      .map((item) => ({
        code: normalizeText(item.profile_type),
        label: PROFILE_TYPE_LABELS[item.profile_type] || normalizeText(item.profile_label || item.profile_type),
        score: clampScore(item.score)
      }))
      .filter((item) => item.code && item.label)
  )
}

export function filterUserProfileRadarDimensions(dimensions, viewKey) {
  const items = Array.isArray(dimensions) ? dimensions : []
  const codes = resolveRadarViewCodes(viewKey)
  if (!codes.length) {
    return items
  }

  const filtered = items.filter((item) => codes.includes(normalizeCode(item?.code)))
  return filtered.length ? filtered : items
}

export function filterUserProfileTagsByRadarView(tags, viewKey) {
  const items = Array.isArray(tags) ? tags : []
  const codes = resolveRadarViewCodes(viewKey)
  if (!codes.length) {
    return items
  }

  return items.filter((tag) => {
    const dimensions = Array.isArray(tag?.radarDimensions) ? tag.radarDimensions : []
    if (dimensions.some((code) => codes.includes(normalizeCode(code)))) {
      return true
    }
    return resolveFallbackTagRadarCodes(tag).some((code) => codes.includes(code))
  })
}

export function resolveUserProfileDefaultRadarView(profile) {
  const profileTypes = new Set(
    (Array.isArray(profile?.profiles) ? profile.profiles : [])
      .map((item) => normalizeCode(item?.profile_type))
      .filter(Boolean)
  )
  if (profileTypes.has('expense') || profileTypes.has('process_quality')) {
    return 'financial_risk'
  }
  if (profileTypes.has('ai_usage') || profileTypes.has('approval')) {
    return 'collaboration_governance'
  }

  const dimensions = normalizeUserProfileRadarDimensions(profile)
  const financialScore = sumRadarScores(dimensions, FINANCIAL_RADAR_CODES)
  const governanceScore = sumRadarScores(dimensions, GOVERNANCE_RADAR_CODES)
  if (financialScore > 0 || governanceScore > 0) {
    return financialScore >= governanceScore ? 'financial_risk' : 'collaboration_governance'
  }
  return 'all_behavior'
}

export function buildProfileOperationsFromAgentRuns(runs, currentUser, limit = 5) {
  const identities = resolveCurrentUserIdentities(currentUser)
  return (Array.isArray(runs) ? runs : [])
    .filter((run) => belongsToCurrentUser(run, identities))
    .sort((left, right) => Date.parse(right.started_at || 0) - Date.parse(left.started_at || 0))
    .slice(0, limit)
    .map((run, index) => ({
      id: normalizeText(run.run_id || run.id) || `operation-${index + 1}`,
      time: formatOperationTime(run.started_at),
      action: resolveOperationAction(run),
      target: resolveOperationTarget(run),
      channel: resolveOperationChannel(run),
      status: STATUS_LABELS[normalizeCode(run.status)] || normalizeText(run.status) || '未知',
      tone: STATUS_TONES[normalizeCode(run.status)] || 'info'
    }))
}

export function resolveCurrentUserProfileError(error) {
  return normalizeText(error?.message) || '用户画像读取失败，请稍后重试。'
}

function indexProfiles(profile) {
  return Object.fromEntries(
    (Array.isArray(profile?.profiles) ? profile.profiles : [])
      .map((item) => [normalizeText(item.profile_type), item])
      .filter(([key]) => key)
  )
}

function metricsOf(profile) {
  return profile?.metrics && typeof profile.metrics === 'object' ? profile.metrics : {}
}

function resolveRadarViewCodes(viewKey) {
  if (viewKey === 'financial_risk') {
    return FINANCIAL_RADAR_CODES
  }
  if (viewKey === 'collaboration_governance') {
    return GOVERNANCE_RADAR_CODES
  }
  return []
}

function resolveFallbackTagRadarCodes(tag) {
  const category = normalizeCode(tag?.category)
  if (['expense', 'travel', 'entertainment', 'process'].includes(category)) {
    return FINANCIAL_RADAR_CODES
  }
  if (['ai', 'approval'].includes(category)) {
    return GOVERNANCE_RADAR_CODES
  }
  return []
}

function normalizeRadarDimensions(tag) {
  const dimensions = Array.isArray(tag?.radar_dimensions)
    ? tag.radar_dimensions
    : Array.isArray(tag?.radarDimensions)
      ? tag.radarDimensions
      : []
  return dimensions.map((item) => normalizeCode(item)).filter(Boolean)
}

function sumRadarScores(dimensions, codes) {
  const codeSet = new Set(codes)
  return (Array.isArray(dimensions) ? dimensions : [])
    .filter((item) => codeSet.has(normalizeCode(item?.code)))
    .reduce((total, item) => total + clampScore(item?.score), 0)
}

function hasProfileDurationMetric(metrics) {
  return (
    Object.prototype.hasOwnProperty.call(metrics || {}, 'usage_duration_ms')
    || Object.prototype.hasOwnProperty.call(metrics || {}, 'online_duration_ms')
    || Object.prototype.hasOwnProperty.call(metrics || {}, 'ai_run_duration_ms')
  )
}

function resolveUsageDurationMs(metrics, fallbackRuns) {
  if (!hasProfileDurationMetric(metrics)) {
    return sumRunDurationMs(fallbackRuns)
  }
  return resolveNumber(metrics.usage_duration_ms)
    || resolveNumber(metrics.online_duration_ms)
    || resolveNumber(metrics.ai_run_duration_ms)
}

function resolveUsageDurationHint(metrics, profile) {
  const days = resolveWindowDays(profile)
  if (normalizeCode(metrics?.usage_duration_mode) === 'online_session') {
    return `近${days}天在线会话累计`
  }
  if (normalizeCode(metrics?.usage_duration_mode) === 'agent_run_fallback') {
    return `近${days}天智能体运行累计`
  }
  return `近${days}天使用行为累计`
}

function filterRunsByCurrentUser(runs, currentUser) {
  const identities = resolveCurrentUserIdentities(currentUser)
  return (Array.isArray(runs) ? runs : []).filter((run) => belongsToCurrentUser(run, identities))
}

function filterRunsByProfileWindow(runs, profile) {
  const cutoff = Date.now() - resolveWindowDays(profile) * 24 * 60 * 60 * 1000
  return (Array.isArray(runs) ? runs : []).filter((run) => {
    const startedAt = Date.parse(run?.started_at || '')
    return Number.isFinite(startedAt) && startedAt >= cutoff
  })
}

function belongsToCurrentUser(run, identities) {
  if (!identities.size) {
    return false
  }
  const userId = normalizeText(run?.user_id).toLowerCase()
  return Boolean(userId && identities.has(userId))
}

function resolveCurrentUserIdentities(user = {}) {
  return new Set(
    [
      user.username,
      user.email,
      user.name,
      user.employeeNo,
      user.employee_no
    ]
      .map((item) => normalizeText(item).toLowerCase())
      .filter(Boolean)
  )
}

function resolveCommonAgent(runs) {
  const counts = new Map()
  for (const run of runs) {
    const code = normalizeCode(run?.agent || run?.route_json?.selected_agent || 'system') || 'system'
    counts.set(code, (counts.get(code) || 0) + 1)
  }

  const [code = '', count = 0] = Array.from(counts.entries())
    .sort((left, right) => right[1] - left[1])[0] || []

  if (!code || !count) {
    return { label: '暂无', count: 0, share: '0%' }
  }

  return {
    label: AGENT_SHORT_LABELS[code] || translateKnownValue(code, AGENT_LABELS, '智能体') || '智能体',
    count,
    share: formatPercent(count / Math.max(1, runs.length))
  }
}

function sumRunDurationMs(runs) {
  return runs.reduce((total, run) => total + resolveRunDurationMs(run), 0)
}

function resolveRunDurationMs(run) {
  const startedAt = Date.parse(run?.started_at || '')
  const finishedAt = Date.parse(run?.finished_at || '')
  if (Number.isFinite(startedAt) && Number.isFinite(finishedAt) && finishedAt > startedAt) {
    return Math.min(finishedAt - startedAt, 24 * 60 * 60 * 1000)
  }

  return (Array.isArray(run?.tool_calls) ? run.tool_calls : []).reduce(
    (total, tool) => total + Math.max(0, resolveNumber(tool?.duration_ms)),
    0
  )
}

function resolveOperationAction(run) {
  const semanticText = normalizeText(run?.semantic_parse?.raw_query)
  if (semanticText) {
    return `${resolveOperationBusinessLabel(run)}：${semanticText}`
  }
  return translateKnownValue(run?.result_summary, JOB_TYPE_LABELS, '')
    || translateKnownValue(run?.route_json?.job_type, JOB_TYPE_LABELS, '执行系统任务')
    || '执行智能财务任务'
}

function resolveOperationTarget(run) {
  return translateKnownValue(run?.route_json?.task_title, JOB_TYPE_LABELS, '')
    || translateKnownValue(run?.route_json?.asset_name, JOB_TYPE_LABELS, '')
    || translateKnownValue(run?.semantic_parse?.scenario, SCENARIO_LABELS, '业务操作')
    || translateKnownValue(run?.task_id, JOB_TYPE_LABELS, '系统任务')
    || '个人工作台'
}

function resolveOperationChannel(run) {
  const agent = translateKnownValue(run?.agent, AGENT_LABELS, '智能服务') || 'Hermes 数字员工'
  const source = translateKnownValue(run?.source, SOURCE_LABELS, '系统入口')
  return source ? `${agent} · ${source}` : agent
}

function resolveOperationBusinessLabel(run) {
  const scenario = translateKnownValue(run?.semantic_parse?.scenario, SCENARIO_LABELS, '业务操作')
  const intent = translateKnownValue(run?.semantic_parse?.intent, INTENT_LABELS, '')
  if (scenario && intent) {
    return `${scenario}${intent}`
  }
  return scenario || intent || '发起'
}

function resolveTagTone(tag) {
  const polarity = normalizeText(tag?.polarity || tag?.tone).toLowerCase()
  if (['risk', 'danger', 'negative'].includes(polarity)) {
    return 'risk'
  }
  if (['positive', 'success'].includes(polarity)) {
    return 'positive'
  }
  return 'behavior'
}

function resolveWindowDays(profile) {
  const days = Number(profile?.window_days || 90)
  return Number.isFinite(days) && days > 0 ? Math.round(days) : 90
}

function resolveTokenHint(metrics) {
  const mode = normalizeText(metrics.token_count_mode)
  return mode === 'estimated_token_count' ? '按运行载荷估算' : '模型调用累计'
}

function formatTokenCount(value) {
  const count = resolveNumber(value)
  if (count >= 10000) {
    return { value: trimNumber(count / 10000, 2), unit: '万' }
  }
  return { value: formatNumber(count), unit: 'tokens' }
}

function formatDurationMetric(totalMs) {
  const seconds = Math.round(Math.max(0, resolveNumber(totalMs)) / 1000)
  if (seconds < 60) {
    return { value: formatNumber(seconds), unit: '秒' }
  }
  const minutes = seconds / 60
  if (minutes < 60) {
    return { value: trimNumber(minutes, minutes >= 10 ? 0 : 1), unit: '分钟' }
  }
  const hours = minutes / 60
  return { value: trimNumber(hours, hours >= 10 ? 0 : 1), unit: '小时' }
}

function withRadarColors(items) {
  return items.map((item, index) => ({
    ...item,
    color: item.color || RADAR_COLORS[index % RADAR_COLORS.length]
  }))
}

function formatOperationTime(value) {
  const date = new Date(value)
  if (Number.isNaN(date.getTime())) {
    return '时间未知'
  }
  const now = new Date()
  const sameDay = date.toDateString() === now.toDateString()
  const yesterday = new Date(now)
  yesterday.setDate(now.getDate() - 1)
  const time = `${pad(date.getHours())}:${pad(date.getMinutes())}`
  if (sameDay) {
    return `今天 ${time}`
  }
  if (date.toDateString() === yesterday.toDateString()) {
    return `昨天 ${time}`
  }
  return `${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${time}`
}

function formatNumber(value) {
  return String(Math.round(resolveNumber(value)))
}

function formatPercent(value) {
  return `${Math.round(resolveNumber(value) * 100)}%`
}

function formatMoney(value) {
  return `¥${trimNumber(resolveNumber(value), 2)}`
}

function trimNumber(value, digits = 0) {
  const number = Number(value || 0)
  return number.toFixed(digits).replace(/\.0+$/, '').replace(/(\.\d*?)0+$/, '$1')
}

function clampScore(value) {
  const score = Math.round(resolveNumber(value))
  return Math.max(0, Math.min(100, score))
}

function resolveNumber(value) {
  const number = Number(value || 0)
  return Number.isFinite(number) ? number : 0
}

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

function normalizeCode(value) {
  return normalizeText(value).toLowerCase()
}

function translateKnownValue(value, labels, internalFallback = '') {
  const raw = normalizeText(value)
  if (!raw) {
    return ''
  }
  const mapped = labels[normalizeCode(raw)]
  if (mapped) {
    return mapped
  }
  return isInternalCode(raw) ? internalFallback : raw
}

function isInternalCode(value) {
  return /^[a-z][a-z0-9_:-]*$/i.test(normalizeText(value))
}

function pad(value) {
  return String(value).padStart(2, '0')
}
