export interface ExecServerResultLike {
  status?: string
  phase?: string
  exit_code?: number | null
}

/** 脚本执行整体状态（execution.status） */
const EXEC_STATUS_LABELS: Record<string, string> = {
  running: '执行中',
  completed: '已完成',
  failed: '失败',
  partial: '部分成功',
  cancelled: '已取消',
}

/** 单台服务器执行状态（results[serverId].status / phase） */
const EXEC_SERVER_STATUS_LABELS: Record<string, string> = {
  success: '成功',
  failed: '失败',
  completed: '已完成',
  error: '错误',
  skipped: '已跳过',
  started: '已启动',
  timeout: '超时',
  connection_error: '连接失败',
  unknown: '未知',
  cancelled: '已取消',
  pending: '后台执行中',
  done: '已完成',
  running: '执行中',
}

const FAILED_STATUSES = new Set([
  'failed',
  'error',
  'skipped',
  'timeout',
  'connection_error',
  'unknown',
  'cancelled',
])

export function execStatusLabel(status: string): string {
  return EXEC_STATUS_LABELS[status] || status
}

/** 与后端 script_execution_store.TERMINAL_STATUSES 一致 */
const EXEC_TERMINAL_STATUSES = new Set(['completed', 'failed', 'partial', 'cancelled'])

export function isExecTerminalStatus(status: string): boolean {
  return EXEC_TERMINAL_STATUSES.has(status)
}

export function execStatusColor(status: string): string {
  if (status === 'running') return 'blue'
  if (status === 'completed') return 'green'
  if (status === 'failed') return 'red'
  if (status === 'partial') return 'orange'
  if (status === 'cancelled') return 'grey'
  return 'info'
}

/** 优先 phase（长任务 pending），其次 status */
export function execServerStatusLabel(status: string, phase?: string): string {
  const p = (phase || '').trim()
  const s = (status || '').trim()
  if (p === 'pending') return EXEC_SERVER_STATUS_LABELS.pending
  if (p === 'cancelled' || s === 'cancelled') return EXEC_SERVER_STATUS_LABELS.cancelled
  if (s && EXEC_SERVER_STATUS_LABELS[s]) return EXEC_SERVER_STATUS_LABELS[s]
  if (p && EXEC_SERVER_STATUS_LABELS[p]) return EXEC_SERVER_STATUS_LABELS[p]
  return s || p || '—'
}

export function isExecServerPending(phase?: string): boolean {
  return (phase || '').trim() === 'pending'
}

/** 与后端 _aggregate_from_results 对齐：pending 不算失败 */
export function isExecServerFailed(
  status: string,
  phase: string | undefined,
  exitCode: number | null | undefined,
): boolean {
  if (isExecServerPending(phase)) return false
  if (exitCode != null && exitCode !== 0) return true
  const s = (status || '').trim().toLowerCase()
  if (FAILED_STATUSES.has(s)) return true
  if ((phase || '').trim() === 'cancelled') return true
  return false
}

export function execServerStatusColor(
  status: string,
  phase: string | undefined,
  exitCode: number | null | undefined,
): string {
  if (isExecServerPending(phase)) return 'blue'
  if (isExecServerFailed(status, phase, exitCode)) return 'error'
  if (exitCode === 0 || ['success', 'completed', 'done'].includes((status || '').toLowerCase())) {
    return 'success'
  }
  return 'grey'
}

/** Resolve display name for a server in execution detail (API map preferred). */
export function resolveExecServerName(
  serverId: string | number,
  serverNames?: Record<string, string> | null,
  briefName?: string | null,
): string {
  const key = String(serverId)
  const fromApi = serverNames?.[key]?.trim()
  if (fromApi) return fromApi
  const brief = briefName?.trim()
  if (brief) return brief
  return `服务器 #${serverId}`
}

export function summarizeExecServerResults(
  results: Record<string, ExecServerResultLike> | undefined,
  serverIdsJson?: string,
): { total: number; success: number; failed: number; pending: number } {
  let ids: string[] = []
  if (serverIdsJson) {
    try {
      const parsed = JSON.parse(serverIdsJson) as unknown
      if (Array.isArray(parsed)) ids = parsed.map(String)
    } catch {
      ids = []
    }
  }
  if (!ids.length && results) {
    ids = Object.keys(results).filter(k => k !== '_meta' && /^\d+$/.test(k))
  }

  let success = 0
  let failed = 0
  let pending = 0
  for (const id of ids) {
    const entry = results?.[id] || {}
    const status = String(entry.status || '')
    const phase = entry.phase ? String(entry.phase) : undefined
    const exitCode = entry.exit_code ?? null
    if (isExecServerPending(phase)) {
      pending += 1
    } else if (isExecServerFailed(status, phase, exitCode)) {
      failed += 1
    } else {
      success += 1
    }
  }
  return { total: ids.length, success, failed, pending }
}