import GLib from "gi://GLib"
import { createPoll } from "ags/time"
import { exec } from "ags/process"

function readProc(path: string): string | null {
  try {
    const [ok, contents] = GLib.file_get_contents(path)
    if (ok && contents) return new TextDecoder().decode(contents)
  } catch {}
  return null
}

let prevIdle = 0
let prevTotal = 0

function getCpuUsage(): string {
  const content = readProc("/proc/stat")
  if (!content) return "?"

  const line = content.split("\n")[0]
  const parts = line.split(/\s+/).slice(1).map(Number)
  const idle = parts[3] + parts[4]
  const total = parts.reduce((a, b) => a + b, 0)

  const dIdle = idle - prevIdle
  const dTotal = total - prevTotal
  prevIdle = idle
  prevTotal = total

  if (dTotal === 0) return "0"
  return `${Math.round(((dTotal - dIdle) / dTotal) * 100)}`
}

function getRamUsage(): { pct: string; used: string; total: string } {
  const content = readProc("/proc/meminfo")
  if (!content) return { pct: "?", used: "?", total: "?" }

  const lines = content.split("\n")
  let totalKb = 0, availableKb = 0

  for (const line of lines) {
    if (line.startsWith("MemTotal:")) totalKb = parseInt(line.split(/\s+/)[1])
    if (line.startsWith("MemAvailable:")) availableKb = parseInt(line.split(/\s+/)[1])
    if (totalKb && availableKb) break
  }

  if (!totalKb) return { pct: "?", used: "?", total: "?" }
  const usedGb = ((totalKb - availableKb) / 1048576).toFixed(1)
  const totalGb = (totalKb / 1048576).toFixed(0)
  const pct = `${Math.round(((totalKb - availableKb) / totalKb) * 100)}`
  return { pct, used: usedGb, total: totalGb }
}

function getGpuInfo(): string {
  try {
    const out = exec("bash -c \"nvidia-smi --query-gpu=utilization.gpu,temperature.gpu --format=csv,noheader,nounits 2>/dev/null\"")
    const [usage, temp] = out.trim().split(", ")
    return `GPU ${usage}% · ${temp}°C`
  } catch {
    return ""
  }
}

export default function SystemStats() {
  const cpu = createPoll("0", 3000, () => getCpuUsage())
  const ram = createPoll("", 5000, () => {
    const r = getRamUsage()
    return JSON.stringify(r)
  })

  const ramLabel = ram((v: string) => {
    try {
      const r = JSON.parse(v)
      return `RAM ${r.used}/${r.total}G`
    } catch { return "RAM ?" }
  })

  const gpu = createPoll("", 5000, () => getGpuInfo())

  return (
    <box>
      <label class="cpu module" label={cpu((v: string) => `CPU ${v}%`)} />
      <label class="separator" label="│" />
      <label class="ram module" label={ramLabel} />
      <label class="separator" label="│" />
      <label class="gpu module" label={gpu((v: string) => v || "GPU ?")} />
    </box>
  )
}
