export const FLOW_RUN_DETAIL_REFRESH_TIMEOUT_MS = 3000

const FLOW_DURATION_MS_FIELDS = [
  'duration_ms',
  'elapsed_ms',
  'latency_ms',
  'total_duration_ms',
  'execution_time_ms'
]
const FLOW_DURATION_SECOND_FIELDS = [
  'duration_seconds',
  'elapsed_seconds',
  'latency_seconds',
  'execution_time_seconds'
]
const FLOW_DURATION_AUTO_FIELDS = ['duration', 'elapsed', 'latency', 'execution_time']
const FLOW_STARTED_AT_FIELDS = ['started_at', 'start_time', 'created_at', 'queued_at']
const FLOW_FINISHED_AT_FIELDS = ['finished_at', 'completed_at', 'ended_at', 'end_time', 'updated_at']

export function formatFlowDuration(ms) {
  if (ms === null || ms === undefined || ms === '') {
    return '--'
  }
  const numericValue = Number(ms)
  if (!Number.isFinite(numericValue) || numericValue <= 0) {
    return '--'
  }
  if (numericValue < 1000) {
    return `${Math.max(0.1, numericValue / 1000).toFixed(1)}s`
  }
  if (numericValue < 10000) {
    return `${(numericValue / 1000).toFixed(1)}s`
  }
  return `${Math.round(numericValue / 1000)}s`
}

function parseFlowTimestamp(value) {
  if (value === null || value === undefined || value === '') {
    return 0
  }
  if (typeof value === 'number' && Number.isFinite(value)) {
    return value > 0 && value < 10000000000 ? Math.round(value * 1000) : Math.round(value)
  }
  const timestamp = new Date(value).getTime()
  return Number.isFinite(timestamp) ? timestamp : 0
}

function normalizeDurationValue(value, unit = 'ms') {
  if (value === null || value === undefined || value === '') {
    return null
  }

  let numericValue = Number(value)
  let normalizedUnit = unit
  if (typeof value === 'string') {
    const text = value.trim()
    const match = text.match(/^(\d+(?:\.\d+)?)\s*(ms|毫秒|s|秒)?$/i)
    if (match) {
      numericValue = Number(match[1])
      if (match[2]) {
        normalizedUnit = ['s', '秒'].includes(match[2].toLowerCase()) ? 'seconds' : 'ms'
      }
    }
  }

  if (!Number.isFinite(numericValue) || numericValue <= 0) {
    return null
  }
  if (normalizedUnit === 'seconds') {
    return Math.round(numericValue * 1000)
  }
  if (normalizedUnit === 'auto') {
    return Math.round(numericValue <= 300 ? numericValue * 1000 : numericValue)
  }
  return Math.round(numericValue)
}

function readFirstDurationField(source, fields, unit) {
  if (!source || typeof source !== 'object') {
    return null
  }
  for (const field of fields) {
    if (!Object.prototype.hasOwnProperty.call(source, field)) {
      continue
    }
    const durationMs = normalizeDurationValue(source[field], unit)
    if (durationMs) {
      return durationMs
    }
  }
  return null
}

function resolveDurationFromFields(source) {
  return (
    readFirstDurationField(source, FLOW_DURATION_MS_FIELDS, 'ms')
    || readFirstDurationField(source, FLOW_DURATION_SECOND_FIELDS, 'seconds')
    || readFirstDurationField(source, FLOW_DURATION_AUTO_FIELDS, 'auto')
  )
}

function readFirstTimestampField(source, fields) {
  if (!source || typeof source !== 'object') {
    return 0
  }
  for (const field of fields) {
    const timestamp = parseFlowTimestamp(source[field])
    if (timestamp) {
      return timestamp
    }
  }
  return 0
}

export function resolveStartedTimestamp(source) {
  return readFirstTimestampField(source, FLOW_STARTED_AT_FIELDS)
}

export function resolveFinishedTimestamp(source) {
  return readFirstTimestampField(source, FLOW_FINISHED_AT_FIELDS)
}

function resolveTimeRangeDurationMs(source) {
  const startedAt = resolveStartedTimestamp(source)
  const finishedAt = resolveFinishedTimestamp(source)
  return finishedAt > startedAt ? finishedAt - startedAt : null
}

export function resolveSemanticPhaseDurations(run) {
  const runStart = resolveStartedTimestamp(run)
  const toolCalls = Array.isArray(run?.tool_calls) ? run.tool_calls : []
  const firstToolStartedAt = toolCalls
    .map((item) => resolveStartedTimestamp(item))
    .filter((value) => value > 0)
    .sort((left, right) => left - right)[0] || 0
  const runFinishedAt = resolveFinishedTimestamp(run)
  const semanticFinishedAt = firstToolStartedAt || runFinishedAt

  if (!runStart || !semanticFinishedAt || semanticFinishedAt <= runStart) {
    return { intentMs: null, extractionMs: null }
  }

  const totalMs = semanticFinishedAt - runStart
  const intentMs = Math.max(120, Math.round(totalMs * 0.35))
  const extractionMs = Math.max(160, totalMs - intentMs)
  return {
    intentMs,
    extractionMs
  }
}

export function resolveToolCallDurationMs(toolCall, index, toolCalls, run) {
  const response = toolCall?.response_json && typeof toolCall.response_json === 'object'
    ? toolCall.response_json
    : {}
  const explicitDuration = resolveDurationFromFields(toolCall)
    || resolveTimeRangeDurationMs(toolCall)
    || resolveDurationFromFields(response)
    || resolveTimeRangeDurationMs(response)
  if (explicitDuration) {
    return explicitDuration
  }

  const startedAt = resolveStartedTimestamp(toolCall)
  if (!startedAt) {
    return null
  }

  const nextStartedAt = resolveStartedTimestamp(toolCalls[index + 1])
  const runFinishedAt = resolveFinishedTimestamp(run)
  const finishedAt = nextStartedAt > startedAt ? nextStartedAt : (runFinishedAt > startedAt ? runFinishedAt : 0)

  if (!finishedAt || finishedAt <= startedAt) {
    return null
  }

  return finishedAt - startedAt
}

export function summarizeVisibleToolText(value) {
  const text = String(value || '')
    .replace(/\|[^\n]*\|/g, '')
    .replace(/\*\*/g, '')
    .split('\n')
    .map((line) => line.trim())
    .find(Boolean) || ''
  if (!text) {
    return ''
  }
  return text.length > 80 ? `${text.slice(0, 80)}...` : text
}
