import { useEffect, useState } from 'react'
import api from '../api/client'
import { useSettingsStore } from '../stores/settings'
import StatusBadge from './StatusBadge'
import TerminalModal from './TerminalModal'
import ScriptModal from './ScriptModal'
import {
  X, Cpu, MemoryStick, HardDrive, Monitor, Server, Settings,
  Download, Trash2, RefreshCw, Package, Search, Play,
  ShieldCheck, Bot, Cable, CalendarClock,
} from 'lucide-react'

// ── Navigation ────────────────────────────────────────────────────────────────

const mainCategories = [
  { id: 'uebersicht',  label: 'Uebersicht' },
  { id: 'software',    label: 'Software' },
  { id: 'system',      label: 'System' },
]

const subTabs = {
  software: [
    { id: 'installed', label: 'Installiert',     icon: Package },
    { id: 'winget',    label: 'winget Updates',  icon: RefreshCw },
    { id: 'wupdates',  label: 'Windows Updates', icon: ShieldCheck },
  ],
  system: [
    { id: 'services',  label: 'Dienste',   icon: Settings },
    { id: 'tunnel',    label: 'Tunnel',    icon: Cable },
    { id: 'tasks',     label: 'Aufgaben',  icon: CalendarClock },
    { id: 'agent',     label: 'Agent',     icon: Bot },
  ],
}

// ── Panel Shell ───────────────────────────────────────────────────────────────

function Panel({ onClose, children }) {
  return (
    <div className="fixed inset-0 z-50 flex items-stretch justify-end bg-black/50">
      <div className="w-full max-w-5xl bg-gray-900 flex flex-col shadow-2xl border-l border-gray-700 overflow-hidden">
        {children}
      </div>
    </div>
  )
}

// ── CustomerAssign ────────────────────────────────────────────────────────────

function CustomerAssign({ agent, customers, current, onReload }) {
  const [editing, setEditing] = useState(false)
  const [saving, setSaving] = useState(false)

  const handleChange = async (e) => {
    const val = e.target.value
    setSaving(true)
    try {
      if (val === '') await api.unassignCustomer(agent.id)
      else await api.assignCustomer(agent.id, parseInt(val))
      if (onReload) onReload()
    } catch (err) {
      console.error(err)
    } finally {
      setSaving(false)
      setEditing(false)
    }
  }

  if (editing) return (
    <div className="flex items-center gap-2 mt-0.5">
      <select
        value={agent.customer_id || ''}
        onChange={handleChange}
        disabled={saving}
        className="bg-gray-900 border border-gray-700 rounded px-2 py-1 text-sm text-white focus:outline-none focus:border-sky-500"
        autoFocus
        onBlur={() => !saving && setEditing(false)}
      >
        <option value="">— Nicht zugewiesen —</option>
        {customers.sort((a, b) => a.number.localeCompare(b.number)).map(c => (
          <option key={c.id} value={c.id}>{c.number} — {c.name}</option>
        ))}
      </select>
      {saving && <span className="text-xs text-gray-500">Speichere...</span>}
    </div>
  )

  return (
    <div
      className="text-sm mt-0.5 cursor-pointer hover:underline"
      onClick={() => setEditing(true)}
      title="Kunde aendern"
    >
      {current
        ? <span className="text-sky-400">{current.number} — {current.name}</span>
        : <span className="text-gray-500 italic">Kein Kunde zugewiesen (klicken zum Zuweisen)</span>
      }
    </div>
  )
}

// ── Main Component ────────────────────────────────────────────────────────────

export default function WindowsPanel({ agentId, customers, onClose, onReload }) {
  const [data, setData] = useState(null)
  const [loading, setLoading] = useState(true)
  const [mainTab, setMainTab] = useState('uebersicht')
  const [subTab, setSubTab] = useState(null)

  useEffect(() => {
    setLoading(true)
    setMainTab('uebersicht')
    setSubTab(null)
    api.getAgent(agentId).then(setData).finally(() => setLoading(false))
  }, [agentId])

  useEffect(() => {
    if (!data) return
    const iv = setInterval(() => api.getAgent(agentId).then(setData), 30000)
    return () => clearInterval(iv)
  }, [agentId, data])

  if (loading) return <Panel onClose={onClose}><div className="p-6 text-gray-500">Laden...</div></Panel>
  if (!data) return <Panel onClose={onClose}><div className="p-6 text-red-400">Nicht gefunden</div></Panel>

  const { agent, system_data: sys, status } = data
  const win = sys?.windows
  const cust = agent.customer_id ? customers.find(c => c.id === agent.customer_id) : null
  const currentSubs = mainTab !== 'uebersicht' ? (subTabs[mainTab] || []) : []
  const activeSubTab = currentSubs.find(s => s.id === subTab)?.id ?? currentSubs[0]?.id

  const handleMainTab = (id) => {
    setMainTab(id)
    setSubTab(subTabs[id]?.[0]?.id ?? null)
  }

  const renderContent = () => {
    if (mainTab === 'uebersicht') return <OverviewTab win={win} agent={agent} status={status} />
    const t = activeSubTab
    if (t === 'installed') return <WingetListTab agentId={agentId} />
    if (t === 'winget')    return <WingetUpgradeTab agentId={agentId} />
    if (t === 'wupdates')  return <WindowsUpdatesTab agentId={agentId} />
    if (t === 'services')  return <ServicesTab win={win} />
    if (t === 'tunnel')    return <TunnelTab agentId={agentId} agent={agent} />
    if (t === 'tasks')     return <TasksTab agentId={agentId} agentName={agent.name} />
    if (t === 'agent')     return <AgentInfoTab agent={agent} status={status} />
    return null
  }

  return (
    <Panel onClose={onClose}>
      {/* Header */}
      <div className="px-6 py-4 bg-gradient-to-r from-gray-800 to-gray-900 border-b border-gray-700">
        <div className="flex items-start justify-between">
          <div>
            <div className="flex items-center gap-3">
              <Monitor className="w-5 h-5 text-blue-400" />
              <h2 className="text-lg font-bold text-white">{agent.name}</h2>
              <StatusBadge status={status} />
            </div>
            <CustomerAssign agent={agent} customers={customers} current={cust} onReload={onReload} />
            <div className="text-xs text-gray-500 mt-1">
              {win?.hostname || agent.hostname}
              {win?.os_version && <span> &middot; {win.os_version}</span>}
              {win?.domain && <span> &middot; {win.domain}</span>}
              <span> &middot; IP: {agent.ip}</span>
            </div>
          </div>
          <div className="flex items-center gap-2">
            <button
              onClick={async () => {
                if (!confirm(`Agent "${agent.name}" wirklich loeschen?`)) return
                await api.deleteAgent(agent.id)
                if (onReload) onReload()
                onClose()
              }}
              className="text-gray-500 hover:text-red-400 transition-colors"
              title="Agent loeschen"
            >
              <Trash2 className="w-4 h-4" />
            </button>
            <button onClick={onClose} className="text-gray-400 hover:text-white">
              <X className="w-5 h-5" />
            </button>
          </div>
        </div>

        {/* Haupt-Tabs */}
        <div className="flex gap-1 mt-4 overflow-x-auto text-xs">
          {mainCategories.map(cat => (
            <button key={cat.id} onClick={() => handleMainTab(cat.id)}
              className={`px-4 py-1.5 whitespace-nowrap transition-colors border-b-2 ${
                mainTab === cat.id
                  ? 'text-blue-400 border-blue-400'
                  : 'text-gray-400 hover:text-gray-200 border-transparent'
              }`}>
              {cat.label}
            </button>
          ))}
        </div>
      </div>

      {/* Content + Sidebar */}
      <div className="flex-1 flex overflow-hidden">
        {/* Sub-Navigation */}
        {mainTab !== 'uebersicht' && currentSubs.length > 0 && (
          <div className="w-44 shrink-0 bg-gray-900/50 border-r border-gray-800 overflow-y-auto py-3">
            <div className="px-4 mb-2">
              <span className="text-[10px] uppercase tracking-wider text-gray-500 font-semibold">
                {mainCategories.find(c => c.id === mainTab)?.label}
              </span>
            </div>
            {currentSubs.map(item => {
              const Icon = item.icon
              const isActive = activeSubTab === item.id
              return (
                <button key={item.id} onClick={() => setSubTab(item.id)}
                  className={`w-full flex items-center gap-2.5 px-4 py-2 text-sm transition-colors ${
                    isActive
                      ? 'text-blue-400 bg-blue-400/5 border-l-2 border-blue-400'
                      : 'text-gray-400 hover:text-white border-l-2 border-transparent'
                  }`}>
                  {Icon && <Icon className="w-4 h-4 shrink-0" />}
                  <span>{item.label}</span>
                </button>
              )
            })}
          </div>
        )}

        {/* Inhalt */}
        <div className="flex-1 overflow-y-auto p-6 space-y-4">
          {renderContent()}
        </div>
      </div>
    </Panel>
  )
}

// ── Uebersicht ────────────────────────────────────────────────────────────────

function OverviewTab({ win, agent, status }) {
  const fmt = (b) => {
    if (!b) return '—'
    if (b >= 1073741824) return `${(b / 1073741824).toFixed(1)} GB`
    return `${(b / 1048576).toFixed(0)} MB`
  }
  const fmtUptime = (s) => {
    if (!s) return '—'
    const d = Math.floor(s / 86400), h = Math.floor((s % 86400) / 3600), m = Math.floor((s % 3600) / 60)
    return d > 0 ? `${d}d ${h}h` : h > 0 ? `${h}h ${m}m` : `${m}m`
  }

  if (!win) return <div className="text-gray-500">Keine Systemdaten — Agent noch nicht verbunden oder erster Heartbeat ausstehend</div>

  const memUsed = win.memory?.total_bytes - win.memory?.available_bytes
  const memPct = win.memory?.used_percent ?? 0

  return (
    <div className="space-y-4">
      {/* Stats-Karten */}
      <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
        <StatCard icon={Cpu} label="CPU-Last" value={`${win.cpu?.load_percent?.toFixed(1) ?? '—'}%`} sub={win.cpu?.model?.split(' ').slice(-2).join(' ')} color="text-blue-400" pct={win.cpu?.load_percent} />
        <StatCard icon={MemoryStick} label="RAM" value={`${memPct.toFixed(0)}%`} sub={`${fmt(memUsed)} / ${fmt(win.memory?.total_bytes)}`} color="text-purple-400" pct={memPct} />
        <StatCard icon={Server} label="Uptime" value={fmtUptime(win.uptime_seconds)} sub="seit letztem Start" color="text-green-400" />
        <StatCard icon={Monitor} label="OS" value={win.os_version?.replace('Windows ', 'Win ') || '—'} sub={win.os_build ? `Build ${win.os_build}` : ''} color="text-gray-400" />
      </div>

      {/* CPU-Details */}
      <div className="bg-gray-800/50 rounded-lg border border-gray-700/50 p-4">
        <div className="text-xs text-gray-500 mb-2 font-semibold uppercase tracking-wide">Prozessor</div>
        <div className="text-sm text-white mb-2">{win.cpu?.model || '—'}</div>
        <div className="flex gap-6 text-xs text-gray-400">
          <span>{win.cpu?.cores ?? '—'} Kerne</span>
          <span>{win.cpu?.logical_cores ?? '—'} logische Kerne</span>
        </div>
        <div className="mt-2">
          <UsageBar pct={win.cpu?.load_percent ?? 0} color="bg-blue-500" />
        </div>
      </div>

      {/* Arbeitsspeicher */}
      <div className="bg-gray-800/50 rounded-lg border border-gray-700/50 p-4">
        <div className="text-xs text-gray-500 mb-2 font-semibold uppercase tracking-wide">Arbeitsspeicher</div>
        <div className="flex justify-between text-sm mb-1">
          <span className="text-gray-300">Belegt: {fmt(memUsed)}</span>
          <span className="text-gray-500">Gesamt: {fmt(win.memory?.total_bytes)}</span>
        </div>
        <UsageBar pct={memPct} color={memPct > 85 ? 'bg-red-500' : memPct > 65 ? 'bg-yellow-500' : 'bg-purple-500'} />
      </div>

      {/* Festplatten */}
      {win.disks?.length > 0 && (
        <div className="bg-gray-800/50 rounded-lg border border-gray-700/50 p-4">
          <div className="text-xs text-gray-500 mb-3 font-semibold uppercase tracking-wide">Laufwerke</div>
          <div className="space-y-3">
            {win.disks.map(d => (
              <div key={d.drive}>
                <div className="flex justify-between text-sm mb-1">
                  <span className="text-white font-mono">{d.drive}</span>
                  <span className="text-gray-400 text-xs">{fmt(d.total_bytes - d.free_bytes)} / {fmt(d.total_bytes)} ({d.used_percent?.toFixed(0)}%)</span>
                </div>
                <UsageBar pct={d.used_percent} color={d.used_percent > 90 ? 'bg-red-500' : d.used_percent > 75 ? 'bg-yellow-500' : 'bg-green-600'} />
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  )
}

// ── Software / winget ─────────────────────────────────────────────────────────

function WingetListTab({ agentId }) {
  const [output, setOutput] = useState(null)
  const [loading, setLoading] = useState(false)
  const [search, setSearch] = useState('')

  const load = async () => {
    setLoading(true)
    try {
      const res = await api.execCommand(agentId, 'winget list --accept-source-agreements', 30)
      setOutput(res?.output || res?.data?.output || '')
    } catch (e) {
      setOutput(`Fehler: ${e.message}`)
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => { load() }, [agentId])

  const lines = output ? output.split('\n').filter(l => l.trim() && !l.startsWith('-')) : []
  const filtered = search ? lines.filter(l => l.toLowerCase().includes(search.toLowerCase())) : lines

  return (
    <div className="space-y-3">
      <div className="flex items-center gap-2">
        <div className="relative flex-1">
          <Search className="absolute left-2.5 top-2 w-3.5 h-3.5 text-gray-500" />
          <input value={search} onChange={e => setSearch(e.target.value)}
            placeholder="Software suchen..."
            className="w-full pl-8 pr-3 py-1.5 bg-gray-800 border border-gray-700 rounded text-sm text-white focus:outline-none focus:border-blue-500" />
        </div>
        <button onClick={load} disabled={loading}
          className="flex items-center gap-1.5 px-3 py-1.5 bg-gray-700 hover:bg-gray-600 rounded text-xs text-gray-300 transition-colors">
          <RefreshCw className={`w-3.5 h-3.5 ${loading ? 'animate-spin' : ''}`} />
          Aktualisieren
        </button>
      </div>
      {loading ? (
        <div className="text-gray-500 text-sm">Lade Liste...</div>
      ) : (
        <pre className="bg-gray-950 rounded p-3 text-xs text-gray-300 font-mono overflow-x-auto whitespace-pre max-h-[500px] overflow-y-auto">
          {filtered.join('\n') || 'Keine Eintraege'}
        </pre>
      )}
    </div>
  )
}

function WingetUpgradeTab({ agentId }) {
  const [output, setOutput] = useState(null)
  const [running, setRunning] = useState(false)
  const [upgradeAll, setUpgradeAll] = useState(false)

  const check = async () => {
    setRunning(true)
    try {
      const res = await api.execCommand(agentId, 'winget upgrade --accept-source-agreements', 60)
      setOutput(res?.output || res?.data?.output || '')
    } catch (e) { setOutput(`Fehler: ${e.message}`) }
    finally { setRunning(false) }
  }

  const doUpgradeAll = async () => {
    if (!confirm('Alle verfügbaren winget-Updates installieren?')) return
    setUpgradeAll(true)
    try {
      const res = await api.execCommand(agentId,
        'winget upgrade --all --silent --accept-package-agreements --accept-source-agreements', 600)
      setOutput(res?.output || res?.data?.output || '')
    } catch (e) { setOutput(`Fehler: ${e.message}`) }
    finally { setUpgradeAll(false) }
  }

  useEffect(() => { check() }, [agentId])

  return (
    <div className="space-y-3">
      <div className="flex gap-2">
        <button onClick={check} disabled={running}
          className="flex items-center gap-1.5 px-3 py-1.5 bg-gray-700 hover:bg-gray-600 rounded text-xs text-gray-300 transition-colors">
          <RefreshCw className={`w-3.5 h-3.5 ${running ? 'animate-spin' : ''}`} />
          Pruefen
        </button>
        <button onClick={doUpgradeAll} disabled={running || upgradeAll}
          className="flex items-center gap-1.5 px-3 py-1.5 bg-blue-700 hover:bg-blue-600 rounded text-xs text-white transition-colors">
          <Download className="w-3.5 h-3.5" />
          {upgradeAll ? 'Installiere...' : 'Alle updaten'}
        </button>
      </div>
      {(running || upgradeAll) && <div className="text-gray-400 text-sm">Bitte warten...</div>}
      {output && (
        <pre className="bg-gray-950 rounded p-3 text-xs text-gray-300 font-mono overflow-x-auto whitespace-pre max-h-[500px] overflow-y-auto">
          {output}
        </pre>
      )}
    </div>
  )
}

function WindowsUpdatesTab({ agentId }) {
  const [output, setOutput] = useState(null)
  const [checking, setChecking] = useState(false)
  const [installing, setInstalling] = useState(false)

  const script = `$s = New-Object -ComObject Microsoft.Update.Session; $r = $s.CreateUpdateSearcher().Search("IsInstalled=0 and Type='Software'"); $r.Updates | ForEach-Object { $kb = if ($_.KBArticleIDs.Count -gt 0) { "KB$($_.KBArticleIDs[0])" } else { "---" }; Write-Output "$kb - $($_.Title)" }; Write-Output ""; Write-Output "Gesamt: $($r.Updates.Count) Updates ausstehend"`

  const check = async () => {
    setChecking(true)
    try {
      const res = await api.execCommand(agentId, `powershell -NonInteractive -Command "${script.replace(/"/g, '\\"')}"`, 120)
      setOutput(res?.output || res?.data?.output || 'Keine Ausgabe')
    } catch (e) { setOutput(`Fehler: ${e.message}`) }
    finally { setChecking(false) }
  }

  const install = async () => {
    if (!confirm('Windows Updates installieren? Der PC kann danach neu starten.')) return
    setInstalling(true)
    setOutput('Updates werden installiert — das kann mehrere Minuten dauern...')
    try {
      const installScript = `$s=New-Object -ComObject Microsoft.Update.Session; $r=$s.CreateUpdateSearcher().Search("IsInstalled=0 and Type='Software'"); if($r.Updates.Count -eq 0){Write-Output "Keine Updates verfuegbar"; exit}; $d=$s.CreateUpdateDownloader(); $d.Updates=$r.Updates; $d.Download(); $i=$s.CreateUpdateInstaller(); $i.Updates=$r.Updates; $ir=$i.Install(); Write-Output "Installiert: $($r.Updates.Count), ResultCode: $($ir.ResultCode)"`
      const res = await api.execCommand(agentId, `powershell -NonInteractive -Command "${installScript.replace(/"/g, '\\"')}"`, 1800)
      setOutput(res?.output || res?.data?.output || '')
    } catch (e) { setOutput(`Fehler: ${e.message}`) }
    finally { setInstalling(false) }
  }

  useEffect(() => { check() }, [agentId])

  return (
    <div className="space-y-3">
      <div className="flex gap-2">
        <button onClick={check} disabled={checking || installing}
          className="flex items-center gap-1.5 px-3 py-1.5 bg-gray-700 hover:bg-gray-600 rounded text-xs text-gray-300 transition-colors">
          <RefreshCw className={`w-3.5 h-3.5 ${checking ? 'animate-spin' : ''}`} />
          Pruefen
        </button>
        <button onClick={install} disabled={checking || installing}
          className="flex items-center gap-1.5 px-3 py-1.5 bg-blue-700 hover:bg-blue-600 rounded text-xs text-white transition-colors">
          <ShieldCheck className="w-3.5 h-3.5" />
          {installing ? 'Installiere...' : 'Jetzt installieren'}
        </button>
      </div>
      {output && (
        <pre className="bg-gray-950 rounded p-3 text-xs text-gray-300 font-mono overflow-x-auto whitespace-pre max-h-[500px] overflow-y-auto">
          {output}
        </pre>
      )}
    </div>
  )
}

// ── System-Tabs ───────────────────────────────────────────────────────────────

function ServicesTab({ win }) {
  const [search, setSearch] = useState('')
  const services = win?.services || []
  const filtered = search
    ? services.filter(s => s.name?.toLowerCase().includes(search.toLowerCase()) ||
        s.display_name?.toLowerCase().includes(search.toLowerCase()))
    : services

  if (services.length === 0) return <div className="text-gray-500 text-sm">Keine Dienstdaten verfuegbar</div>

  return (
    <div className="space-y-3">
      <input value={search} onChange={e => setSearch(e.target.value)}
        placeholder="Dienste suchen..."
        className="w-full px-3 py-1.5 bg-gray-800 border border-gray-700 rounded text-sm text-white focus:outline-none focus:border-blue-500" />
      <div className="space-y-0.5">
        {filtered.map(s => (
          <div key={s.name} className="flex items-center gap-2.5 px-2 py-1 rounded hover:bg-gray-800/50">
            <span className={`w-1.5 h-1.5 rounded-full flex-shrink-0 ${
              s.status === 'running' ? 'bg-green-400' :
              s.status === 'stopped' ? 'bg-gray-600' : 'bg-yellow-400'
            }`} />
            <span className="text-xs text-gray-300 flex-1 min-w-0 truncate">{s.display_name || s.name}</span>
            <span className="text-[10px] text-gray-600 flex-shrink-0">{s.start_type}</span>
          </div>
        ))}
      </div>
    </div>
  )
}

function TunnelTab({ agentId, agent }) {
  const [showTerminal, setShowTerminal] = useState(false)
  const [showScript, setShowScript] = useState(false)
  return (
    <div className="space-y-4">
      <div className="flex gap-3">
        <button onClick={() => setShowTerminal(true)}
          className="flex items-center gap-2 px-4 py-2 bg-gray-700 hover:bg-gray-600 rounded text-sm text-white transition-colors">
          <Play className="w-4 h-4" />
          Terminal
        </button>
        <button onClick={() => setShowScript(true)}
          className="flex items-center gap-2 px-4 py-2 bg-gray-700 hover:bg-gray-600 rounded text-sm text-white transition-colors">
          <Settings className="w-4 h-4" />
          Script
        </button>
      </div>
      {showTerminal && <TerminalModal agentId={agentId} agentName={agent?.name || ''} onClose={() => setShowTerminal(false)} />}
      {showScript && <ScriptModal agentId={agentId} agentName={agent?.name || ''} onClose={() => setShowScript(false)} />}
    </div>
  )
}

function TasksTab({ agentId, agentName }) {
  const [cmd, setCmd] = useState('')
  const [output, setOutput] = useState(null)
  const [running, setRunning] = useState(false)

  const run = async () => {
    if (!cmd.trim()) return
    setRunning(true)
    try {
      const res = await api.execCommand(agentId, cmd, 60)
      setOutput(res?.output || res?.data?.output || '')
    } catch (e) { setOutput(`Fehler: ${e.message}`) }
    finally { setRunning(false) }
  }

  return (
    <div className="space-y-3">
      <div className="flex gap-2">
        <input value={cmd} onChange={e => setCmd(e.target.value)}
          onKeyDown={e => e.key === 'Enter' && run()}
          placeholder="Befehl (PowerShell oder cmd)"
          className="flex-1 px-3 py-1.5 bg-gray-800 border border-gray-700 rounded text-sm text-white font-mono focus:outline-none focus:border-blue-500" />
        <button onClick={run} disabled={running || !cmd.trim()}
          className="flex items-center gap-1.5 px-3 py-1.5 bg-blue-700 hover:bg-blue-600 disabled:bg-gray-700 rounded text-sm text-white transition-colors">
          <Play className="w-3.5 h-3.5" />
          {running ? 'Laeuft...' : 'Ausfuehren'}
        </button>
      </div>
      {output !== null && (
        <pre className="bg-gray-950 rounded p-3 text-xs text-gray-300 font-mono overflow-x-auto whitespace-pre max-h-80 overflow-y-auto">
          {output || '(keine Ausgabe)'}
        </pre>
      )}
    </div>
  )
}

function AgentInfoTab({ agent, status }) {
  return (
    <div className="space-y-3">
      <div className="bg-gray-800/50 rounded-lg border border-gray-700/50 p-4 space-y-2">
        {[
          ['Agent-ID', agent.id],
          ['Name', agent.name],
          ['Hostname', agent.hostname],
          ['IP', agent.ip],
          ['Version', agent.agent_version || '—'],
          ['Plattform', agent.platform],
          ['Status', status],
          ['Registriert', new Date(agent.registered_at).toLocaleString('de-DE')],
        ].map(([k, v]) => (
          <div key={k} className="flex gap-4">
            <span className="text-xs text-gray-500 w-28 shrink-0">{k}</span>
            <span className="text-xs text-gray-300 font-mono break-all">{v}</span>
          </div>
        ))}
      </div>
    </div>
  )
}

// ── Hilfskomponenten ──────────────────────────────────────────────────────────

function StatCard({ icon: Icon, label, value, sub, color, pct }) {
  return (
    <div className="bg-gray-800/50 rounded-lg border border-gray-700/50 p-4">
      <div className="flex items-center gap-2 mb-1">
        <Icon className={`w-4 h-4 ${color}`} />
        <span className="text-xs text-gray-500">{label}</span>
      </div>
      <div className={`text-2xl font-bold ${color}`}>{value}</div>
      {sub && <div className="text-xs text-gray-600 mt-0.5 truncate">{sub}</div>}
      {pct !== undefined && <UsageBar pct={pct} color={color.replace('text-', 'bg-')} className="mt-2" />}
    </div>
  )
}

function UsageBar({ pct, color, className = '' }) {
  return (
    <div className={`w-full bg-gray-700 rounded-full h-1.5 ${className}`}>
      <div className={`h-1.5 rounded-full transition-all ${color}`}
        style={{ width: `${Math.min(100, pct ?? 0).toFixed(0)}%` }} />
    </div>
  )
}
