import { useCallback, useEffect, useState } from 'react'
import { View, Text, ScrollView, StyleSheet, RefreshControl } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'

import { useBind } from '@/context/BindContext'
import { apiFetch } from '@/lib/api'
import type { SystemMetricsPayload } from '@/lib/pcTypes'
import { theme } from '@/constants/theme'

function fmtBytes(n: number | undefined): string {
  if (n == null || Number.isNaN(n)) return '—'
  if (n < 1024) return `${n} B`
  if (n < 1024 ** 2) return `${(n / 1024).toFixed(1)} KB`
  if (n < 1024 ** 3) return `${(n / 1024 ** 2).toFixed(1)} MB`
  return `${(n / 1024 ** 3).toFixed(2)} GB`
}

export default function SystemScreen() {
  const { bind } = useBind()
  const [data, setData] = useState<SystemMetricsPayload | null>(null)
  const [err, setErr] = useState<string | null>(null)
  const [refreshing, setRefreshing] = useState(false)

  const load = useCallback(async () => {
    if (!bind) {
      setData(null)
      setErr(null)
      return
    }
    try {
      const res = await apiFetch(bind, '/system_metrics')
      const json = (await res.json()) as SystemMetricsPayload
      if (!res.ok) {
        setErr(json.error || `HTTP ${res.status}`)
        return
      }
      setErr(null)
      setData(json)
    } catch (e) {
      setErr(e instanceof Error ? e.message : String(e))
    }
  }, [bind])

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

  useEffect(() => {
    if (!bind) return
    const id = setInterval(() => void load(), 2000)
    return () => clearInterval(id)
  }, [bind, load])

  const onRefresh = useCallback(async () => {
    setRefreshing(true)
    await load()
    setRefreshing(false)
  }, [load])

  const m = data?.memory
  const net = data?.network

  return (
    <SafeAreaView style={styles.safe} edges={['bottom']}>
      <ScrollView
        contentContainerStyle={styles.scroll}
        refreshControl={
          bind ? (
            <RefreshControl refreshing={refreshing} onRefresh={() => void onRefresh()} tintColor={theme.accent} />
          ) : undefined
        }
      >
        <Text style={styles.h1}>系统</Text>
        <Text style={styles.lead}>本机负载与网速（与桌面端「系统」页同源）。开机启动等仅在 Windows 客户端可设置。</Text>

        {!bind && (
          <View style={styles.banner}>
            <Text style={styles.bannerText}>未绑定 PC：配对后每 2 秒刷新指标。</Text>
          </View>
        )}

        <View style={styles.card}>
          <Text style={styles.cardTitle}>本机负载与网速</Text>
          <Text style={styles.desc}>
            网速为全机网卡合计估算；下方列出检测到的 ffmpeg 进程。
          </Text>
          {err && bind ? (
            <Text style={styles.err}>{err}</Text>
          ) : null}

          <View style={styles.metricsGrid}>
            <View style={styles.block}>
              <Text style={styles.blockTitle}>CPU</Text>
              <Text style={styles.big}>{data?.cpu_percent != null ? `${data.cpu_percent.toFixed(1)}%` : '—'}</Text>
              <Text style={styles.sub}>逻辑处理器 {data?.cpu_count_logical ?? '—'} 个</Text>
            </View>
            <View style={styles.block}>
              <Text style={styles.blockTitle}>内存</Text>
              <Text style={styles.big}>{m?.percent != null ? `${m.percent.toFixed(1)}%` : '—'}</Text>
              <Text style={styles.sub}>
                {fmtBytes(m?.used)} / {fmtBytes(m?.total)}（可用 {fmtBytes(m?.available)}）
              </Text>
            </View>
            <View style={styles.block}>
              <Text style={styles.blockTitle}>全机网速</Text>
              <Text style={styles.rate}>
                ↑ {net?.up_mbps != null ? `${net.up_mbps.toFixed(2)} Mbps` : '—'}
              </Text>
              <Text style={styles.rate}>
                ↓ {net?.down_mbps != null ? `${net.down_mbps.toFixed(2)} Mbps` : '—'}
              </Text>
              <Text style={styles.sub}>含所有网卡收发合计</Text>
            </View>
          </View>

          {data?.swap && data.swap.total != null && data.swap.total > 0 ? (
            <Text style={styles.swap}>
              交换分区 {data.swap.percent != null ? `${data.swap.percent.toFixed(0)}%` : '—'} ·{' '}
              {fmtBytes(data.swap.used)} / {fmtBytes(data.swap.total)}
            </Text>
          ) : null}

          {data?.disks && data.disks.length > 0 ? (
            <View style={styles.diskSec}>
              <Text style={styles.diskTitle}>磁盘空间</Text>
              {data.disks.slice(0, 8).map((d, i) => (
                <Text key={i} style={styles.diskLine}>
                  <Text style={styles.diskMp}>{d.mountpoint}</Text> ·{' '}
                  {d.percent != null ? `${d.percent.toFixed(0)}%` : '—'} 已用 · 剩余 {fmtBytes(d.free)}
                </Text>
              ))}
            </View>
          ) : null}

          {data?.ffmpeg_processes && data.ffmpeg_processes.length > 0 ? (
            <View style={styles.ffSec}>
              <Text style={styles.diskTitle}>ffmpeg 进程</Text>
              {data.ffmpeg_processes.map((p, i) => (
                <Text key={i} style={styles.ffLine}>
                  PID {p.pid} · {p.name ?? '—'} · {fmtBytes(p.rss)}
                </Text>
              ))}
            </View>
          ) : null}
        </View>

        <View style={styles.cardMuted}>
          <Text style={styles.cardTitle}>客户端与系统集成</Text>
          <Text style={styles.muted}>开机启动、路径与 Electron 集成仅在桌面客户端可用。</Text>
        </View>
      </ScrollView>
    </SafeAreaView>
  )
}

const styles = StyleSheet.create({
  safe: { flex: 1, backgroundColor: theme.bg },
  scroll: { padding: 16, paddingBottom: 40 },
  h1: { fontSize: 20, fontWeight: '700', color: theme.text, marginBottom: 6 },
  lead: { fontSize: 14, color: theme.muted, marginBottom: 14, lineHeight: 22 },
  banner: {
    padding: 12,
    borderRadius: 10,
    backgroundColor: 'rgba(124,92,255,0.08)',
    borderWidth: 1,
    borderColor: 'rgba(124,92,255,0.22)',
    marginBottom: 14,
  },
  bannerText: { fontSize: 13, color: theme.text, lineHeight: 20 },
  card: {
    padding: 14,
    borderRadius: 12,
    backgroundColor: theme.bgCard,
    borderWidth: 1,
    borderColor: 'rgba(124,92,255,0.22)',
    marginBottom: 12,
  },
  cardMuted: {
    padding: 14,
    borderRadius: 12,
    backgroundColor: theme.bgElevated,
    borderWidth: 1,
    borderColor: theme.border,
  },
  cardTitle: { fontSize: 16, fontWeight: '600', color: theme.text, marginBottom: 8 },
  desc: { fontSize: 13, color: theme.muted, marginBottom: 12, lineHeight: 20 },
  err: { color: theme.danger, marginBottom: 10, fontSize: 13 },
  metricsGrid: { gap: 12 },
  block: {
    padding: 12,
    borderRadius: 10,
    backgroundColor: theme.bgElevated,
    borderWidth: 1,
    borderColor: theme.border,
  },
  blockTitle: { fontSize: 11, fontWeight: '700', color: theme.muted, marginBottom: 6 },
  big: { fontSize: 22, fontWeight: '700', color: theme.text },
  sub: { fontSize: 11, color: theme.muted, marginTop: 4, lineHeight: 16 },
  rate: { fontSize: 15, fontWeight: '600', color: theme.accent, fontFamily: 'monospace' },
  swap: { fontSize: 12, color: theme.muted, marginTop: 10, marginBottom: 8 },
  diskSec: { marginTop: 8 },
  diskTitle: { fontSize: 13, fontWeight: '600', color: theme.text, marginBottom: 8 },
  diskLine: { fontSize: 12, color: theme.muted, marginBottom: 6 },
  diskMp: { fontFamily: 'monospace', color: theme.text },
  ffSec: { marginTop: 12 },
  ffLine: { fontSize: 12, color: theme.muted, marginBottom: 4, fontFamily: 'monospace' },
  muted: { fontSize: 13, color: theme.muted, lineHeight: 20 },
})
