import color from 'ansis'
import { get } from '../http'
import { resolveAppName } from '../name'

interface AppMetrics {
  name: string
  state: string
  port?: number
  pid?: number
  cpu?: number
  memory?: number
  rss?: number
  dataSize?: number
  tool?: boolean
}

function formatBytes(bytes?: number): string {
  if (bytes === undefined) return '-'
  if (bytes < 1024) return `${bytes} B`
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
  if (bytes < 1024 * 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)} MB`
  return `${(bytes / 1024 / 1024 / 1024).toFixed(2)} GB`
}

function formatRss(kb?: number): string {
  if (kb === undefined) return '-'
  if (kb < 1024) return `${kb} KB`
  if (kb < 1024 * 1024) return `${(kb / 1024).toFixed(1)} MB`
  return `${(kb / 1024 / 1024).toFixed(2)} GB`
}

function formatPercent(value?: number): string {
  if (value === undefined) return '-'
  return `${value.toFixed(1)}%`
}

function pad(str: string, len: number, right = false): string {
  if (right) return str.padStart(len)
  return str.padEnd(len)
}

export async function metricsApp(arg?: string) {
  // If arg is provided, show metrics for that app only
  if (arg) {
    const name = resolveAppName(arg)
    if (!name) return

    const metrics: AppMetrics | undefined = await get(`/api/tools/metrics/api/metrics/${name}`)
    if (!metrics) {
      console.error(`App not found: ${name}`)
      return
    }

    console.log(`${color.bold(metrics.name)} ${metrics.tool ? color.gray('[tool]') : ''}`)
    console.log(`  State:  ${metrics.state}`)
    if (metrics.pid) console.log(`  PID:    ${metrics.pid}`)
    if (metrics.port) console.log(`  Port:   ${metrics.port}`)
    if (metrics.cpu !== undefined) console.log(`  CPU:    ${formatPercent(metrics.cpu)}`)
    if (metrics.memory !== undefined) console.log(`  Memory: ${formatPercent(metrics.memory)}`)
    if (metrics.rss !== undefined) console.log(`  RSS:    ${formatRss(metrics.rss)}`)
    console.log(`  Data:   ${formatBytes(metrics.dataSize)}`)
    return
  }

  // Show metrics for all apps
  const metrics: AppMetrics[] | undefined = await get('/api/tools/metrics/api/metrics')
  if (!metrics || metrics.length === 0) {
    console.log('No apps found')
    return
  }

  // Sort: running first, then by name
  metrics.sort((a, b) => {
    if (a.state === 'running' && b.state !== 'running') return -1
    if (a.state !== 'running' && b.state === 'running') return 1
    return a.name.localeCompare(b.name)
  })

  // Calculate column widths
  const nameWidth = Math.max(4, ...metrics.map(s => s.name.length + (s.tool ? 7 : 0)))
  const stateWidth = Math.max(5, ...metrics.map(s => s.state.length))

  // Header
  console.log(
    color.gray(
      `${pad('NAME', nameWidth)}  ${pad('STATE', stateWidth)}  ${pad('PID', 7, true)}  ${pad('CPU', 7, true)}  ${pad('MEM', 7, true)}  ${pad('RSS', 10, true)}  ${pad('DATA', 10, true)}`
    )
  )

  // Rows
  for (const s of metrics) {
    const name = s.tool ? `${s.name} ${color.gray('[tool]')}` : s.name
    const stateColor = s.state === 'running' ? color.green : s.state === 'invalid' ? color.red : color.gray
    const state = stateColor(s.state)

    const pid = s.pid ? String(s.pid) : '-'
    const cpu = formatPercent(s.cpu)
    const mem = formatPercent(s.memory)
    const rss = formatRss(s.rss)
    const data = formatBytes(s.dataSize)

    console.log(
      `${pad(name, nameWidth)}  ${pad(state, stateWidth)}  ${pad(pid, 7, true)}  ${pad(cpu, 7, true)}  ${pad(mem, 7, true)}  ${pad(rss, 10, true)}  ${pad(data, 10, true)}`
    )
  }

  // Summary
  const running = metrics.filter(s => s.state === 'running')
  const totalCpu = running.reduce((sum, s) => sum + (s.cpu ?? 0), 0)
  const totalRss = running.reduce((sum, s) => sum + (s.rss ?? 0), 0)
  const totalData = metrics.reduce((sum, s) => sum + (s.dataSize ?? 0), 0)

  console.log()
  console.log(color.gray(`${running.length} running, ${formatPercent(totalCpu)} CPU, ${formatRss(totalRss)} RSS, ${formatBytes(totalData)} data`))
}
