import { useState, useEffect, useCallback, useRef } from 'react'
import { useI18n } from '../i18n'

const MAX_POINTS = 30

const POLL_INTERVAL = 5000
const MAX_IDLE_POLLS = 3

function MiniGraph({ data, max, color, label, unit }) {
  if (!data || data.length < 2) return <div className="dash-graph-empty">collecting...</div>
  const m = max || Math.max(...data, 1)
  const w = 100
  const h = 32
  const points = data.map((v, i) => {
    const x = (i / (data.length - 1)) * w
    const y = h - (v / m) * h
    return `${x},${y}`
  }).join(' ')
  const last = data[data.length - 1]
  return (
    <div className="dash-graph-wrap">
      <div className="dash-graph-header">
        <span className="dash-graph-label">{label}</span>
        <span className="dash-graph-value" style={{ color }}>{last.toFixed(1)}{unit}</span>
      </div>
      <svg viewBox={`0 0 ${w} ${h}`} className="dash-graph-svg" preserveAspectRatio="none">
        <defs>
          <linearGradient id={`fg-${color.replace('#','').replace('var(','').replace(')','')}`} x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={color} stopOpacity="0.3" />
            <stop offset="100%" stopColor={color} stopOpacity="0.02" />
          </linearGradient>
        </defs>
        <polygon fill={`url(#fg-${color.replace('#','').replace('var(','').replace(')','')})`} points={`${points} ${w},${h} 0,${h}`} />
        <polyline fill="none" stroke={color} strokeWidth="1.5" points={points} vectorEffect="non-scaling-stroke" />
      </svg>
    </div>
  )
}

export default function Dashboard({ api, refreshRef }) {
  const { t } = useI18n()
  const [quota, setQuota] = useState(null)
  const [recentCmds, setRecentCmds] = useState([])
  const [processes, setProcesses] = useState([])
  const [metrics, setMetrics] = useState(null)
  const [copiedSet, setCopiedSet] = useState(new Set())
  const cpuRef = useRef([])
  const memRef = useRef([])
  const netRxRef = useRef([])
  const netTxRef = useRef([])

  const loadData = useCallback(async () => {
    try {
      const [quotaData, cmdData, procData, metricsData] = await Promise.all([
        api.getProvidersQuota().catch(() => null),
        api.getRecentCommands().catch(() => ({ commands: [] })),
        api.getRunningProcesses().catch(() => ({ processes: [] })),
        api.getSystemMetrics().catch(() => null),
      ])
      setQuota(quotaData?.providers || [])
      setRecentCmds(cmdData.commands || [])
      setProcesses(procData.processes || [])
      if (metricsData) {
        setMetrics(metricsData)
        cpuRef.current = [...cpuRef.current, metricsData.cpu_percent].slice(-MAX_POINTS)
        memRef.current = [...memRef.current, metricsData.mem_percent].slice(-MAX_POINTS)
        netRxRef.current = [...netRxRef.current, metricsData.net_rx_kbs].slice(-MAX_POINTS)
        netTxRef.current = [...netTxRef.current, metricsData.net_tx_kbs].slice(-MAX_POINTS)
      }
    } catch (err) {
      console.error('Dashboard load error:', err)
    }
  }, [api])

  useEffect(() => {
    loadData()
    if (refreshRef) refreshRef.current = loadData
    let active = true
    let idleTicks = 0
    const iv = setInterval(() => {
      const hidden = document.querySelector('.dash-grid')?.closest('.tab-hidden')
      if (hidden) {
        idleTicks++
        if (idleTicks >= MAX_IDLE_POLLS) return
      } else {
        idleTicks = 0
      }
      if (active) loadData()
    }, POLL_INTERVAL)
    return () => { active = false; clearInterval(iv) }
  }, [loadData, refreshRef])

  const minimax = (quota || []).find(p => p.name === 'minimax')
  const mimo = (quota || []).find(p => p.name === 'mimo')

  const EXCLUDE_CMDS = ['ls', 'cd', 'pwd', 'clear', 'exit', 'history', 'cat', 'echo', 'grep', 'export', 'alias', 'unalias', 'set', 'unset', 'source', '.', 'fg', 'bg', 'jobs', 'wait', 'true', 'false', 'yes', 'sleep', 'date', 'whoami', 'id', 'uname', 'hostname', 'uptime', 'df', 'free', 'top', 'htop', 'nano', 'vi', 'vim', 'less', 'more', 'tail', 'head', 'man', 'info', 'which', 'whereis', 'type', 'command', 'hash', 'builtin', 'help']

  const topCmds = (() => {
    const counts = {}
    for (const c of recentCmds) {
      const base = c.cmd.split(/\s+/)[0]
      if (!base || base.length < 2 || EXCLUDE_CMDS.includes(base)) continue
      if (!/^[a-zA-Z@.\/]/.test(base)) continue
      counts[base] = (counts[base] || 0) + 1
    }
    return Object.entries(counts)
      .sort((a, b) => b[1] - a[1])
      .slice(0, 5)
      .map(([cmd, count]) => ({ cmd, count }))
  })()

  const maxCount = topCmds.length > 0 ? topCmds[0].count : 1

  const copyCmd = (cmd, key) => {
    navigator.clipboard.writeText(cmd)
    setCopiedSet(prev => new Set(prev).add(key))
    setTimeout(() => setCopiedSet(prev => { const next = new Set(prev); next.delete(key); return next }), 1500)
  }

  const relativeTime = (ts) => {
    if (!ts) return ''
    const diff = Math.floor((Date.now() - new Date(ts).getTime()) / 1000)
    if (diff < 60) return `${diff}s`
    if (diff < 3600) return `${Math.floor(diff / 60)}m`
    if (diff < 86400) return `${Math.floor(diff / 3600)}h`
    return `${Math.floor(diff / 86400)}d`
  }

  const recentUnique = (() => {
    const seen = new Set()
    return recentCmds.filter(c => {
      if (seen.has(c.cmd)) return false
      seen.add(c.cmd)
      return true
    })
  })()

  return (
    <div className="dash-grid">
      {/* CPU */}
      <div className="dash-card">
        <div className="dash-card-head">
          <span className="dash-label">CPU</span>
          <span className="dash-count">{metrics ? metrics.cpu_percent.toFixed(0) : '—'}%</span>
        </div>
        <MiniGraph data={cpuRef.current} max={100} color="var(--accent)" label="CPU" unit="%" />
      </div>

      {/* RAM */}
      <div className="dash-card">
        <div className="dash-card-head">
          <span className="dash-label">RAM</span>
          <span className="dash-count">{metrics ? `${metrics.mem_used_mb.toFixed(0)}/${metrics.mem_total_mb.toFixed(0)}` : '—'}</span>
        </div>
        <MiniGraph data={memRef.current} max={100} color="#a78bfa" label="RAM" unit="%" />
      </div>

      {/* Network */}
      <div className="dash-card">
        <div className="dash-card-head">
          <span className="dash-label">Network</span>
          <span className="dash-count">{metrics ? `↓${metrics.net_rx_kbs.toFixed(0)} ↑${metrics.net_tx_kbs.toFixed(0)}` : '—'}</span>
        </div>
        <MiniGraph data={netRxRef.current} max={null} color="#34d399" label="RX" unit=" KB/s" />
        <MiniGraph data={netTxRef.current} max={null} color="#f59e0b" label="TX" unit=" KB/s" />
      </div>

      {/* API Quota */}
      <div className="dash-card">
        <div className="dash-card-head">
          <span className="dash-label">API Quota</span>
        </div>
        <div className="dash-quota-list">
          {minimax && minimax.data?.models?.map((m, i) => (
            <div key={i} className="dash-quota-row">
              <span className="dash-quota-name">{String(m.model).replace('MiniMax-', '')}</span>
              <div className="dash-bar">
                <div className="dash-bar-fill" style={{ width: `${Math.min(100, (m.used / m.total) * 100)}%` }} />
              </div>
              <span className="dash-quota-val">{m.used}/{m.total}</span>
            </div>
          ))}
          {minimax && minimax.data?.models?.length === 0 && (
            <div className="dash-quota-row">
              <span className="dash-quota-name">MiniMax</span>
              <span className="dash-quota-val" style={{ color: 'var(--text-tertiary)' }}>{minimax.error || 'no data'}</span>
            </div>
          )}
          {mimo && mimo.data?.models?.map((m, i) => (
            <div key={i} className="dash-quota-row">
              <span className="dash-quota-name">{String(m.model).replace('MiMo-', '')}</span>
              <div className="dash-bar">
                <div className="dash-bar-fill" style={{ width: `${Math.min(100, (m.used / m.total) * 100)}%` }} />
              </div>
              <span className="dash-quota-val">{m.used}/{m.total}</span>
            </div>
          ))}
          {mimo && !mimo.data?.models?.length && (
            <div className="dash-quota-row">
              <span className="dash-quota-name">MiMo</span>
              <span className="dash-quota-val" style={{ color: 'var(--text-tertiary)' }}>{mimo.error || (mimo.healthy ? '✓ configured' : 'no key')}</span>
            </div>
          )}
          {!minimax && !mimo && <span className="dash-quota-val" style={{ color: 'var(--text-tertiary)' }}>No providers</span>}
        </div>
      </div>

      {/* Running Processes */}
      <div className="dash-card">
        <div className="dash-card-head">
          <span className="dash-label">Processes</span>
          <span className="dash-count">{processes.length}</span>
        </div>
        <div className="dash-proc-list">
          {processes.length === 0 && <span className="dash-empty">No relevant processes</span>}
          {processes.map((p, i) => (
            <div key={i} className="dash-proc-row">
              <span className="dash-proc-name">{p.name}</span>
              <span className="dash-proc-res">cpu {p.cpu}% · mem {p.mem}%</span>
            </div>
          ))}
        </div>
      </div>

      {/* Recent Commands */}
      <div className="dash-card dash-cmd-card">
        <div className="dash-card-head">
          <span className="dash-label">Recent Commands</span>
          <span className="dash-count">{recentUnique.length}</span>
        </div>
        {topCmds.length > 0 && (
          <div className="dash-cmd-freq">
            <span className="dash-cmd-freq-title">Most used</span>
            {topCmds.map((c, i) => (
              <div key={i} className="dash-cmd-freq-row" onClick={() => copyCmd(c.cmd, `top-${i}`)} title={c.cmd}>
                <span className="dash-cmd-freq-name">{copiedSet.has(`top-${i}`) ? '✓ Copié' : c.cmd}</span>
                <div className="dash-cmd-freq-bar-wrap">
                  <div className="dash-cmd-freq-bar" style={{ width: `${(c.count / maxCount) * 100}%` }} />
                </div>
                <span className="dash-cmd-freq-count">{c.count}×</span>
              </div>
            ))}
          </div>
        )}
        <div className="dash-cmd-list">
          {recentUnique.length === 0 && <span className="dash-empty">No history</span>}
          {recentUnique.map((c, i) => (
            <div key={i} className="dash-cmd-row" onClick={() => copyCmd(c.cmd, `list-${i}`)} title={c.cmd + ' · click to copy'}>
              <div className="dash-cmd-left">
                <span className="dash-cmd-text">{c.cmd.length > 38 ? c.cmd.slice(0, 35) + '...' : c.cmd}</span>
                <span className="dash-cmd-time">{relativeTime(c.ts)}</span>
              </div>
              <span className="dash-cmd-copy">{copiedSet.has(`list-${i}`) ? '✓' : '⎘'}</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  )
}
