import { useCallback, useEffect, useState } from 'react'
import { BarChart3, ChevronRight, Download, Eye, FileText, Folder, HardDrive, Loader2, RefreshCw, Server, X } from 'lucide-react'
import { cn } from '../../lib/utils'
import { subTabActive, subTabIdle } from '../../lib/tabActive'
import { HadoopAnalytics } from './HadoopAnalytics'

type HdfsEntry = {
  name: string
  path: string
  type: 'directory' | 'file'
  size?: number
  size_human?: string
  modified?: string
  owner?: string
  group?: string
  perms?: string
  replication?: number
}

type Health = {
  ok: boolean
  namenode?: string
  live_datanodes?: number
  dead_datanodes?: number
  capacity_total_human?: string
  capacity_used_human?: string
  capacity_used_pct?: number
  error?: string
}

export function HdfsView() {
  const [health, setHealth] = useState<Health | null>(null)
  const [path, setPath] = useState('/')
  const [folders, setFolders] = useState<HdfsEntry[]>([])
  const [files, setFiles] = useState<HdfsEntry[]>([])
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [preview, setPreview] = useState<{ path: string; text: string; binary: boolean; truncated: boolean } | null>(null)
  const [previewing, setPreviewing] = useState(false)
  const [tab, setTab] = useState<'files' | 'analytics'>('files')

  const loadHealth = useCallback(async () => {
    try {
      const r = await fetch('/api/storage/hdfs/health')
      if (r.ok) setHealth(await r.json())
    } catch {
      /* ignore */
    }
  }, [])

  const loadList = useCallback(async (p: string) => {
    setLoading(true)
    setError(null)
    try {
      const r = await fetch(`/api/storage/hdfs/list?path=${encodeURIComponent(p)}`)
      const j = await r.json()
      if (!j.ok) {
        setError(j.error || 'List failed')
        setFolders([])
        setFiles([])
        return
      }
      setFolders(j.folders || [])
      setFiles(j.files || [])
    } catch {
      setError('HDFS API unavailable')
    } finally {
      setLoading(false)
    }
  }, [])

  useEffect(() => {
    loadHealth()
  }, [loadHealth])

  useEffect(() => {
    loadList(path)
  }, [path, loadList])

  const openPreview = useCallback(async (p: string) => {
    setPreviewing(true)
    setPreview({ path: p, text: '', binary: false, truncated: false })
    try {
      const r = await fetch(`/api/storage/hdfs/preview?path=${encodeURIComponent(p)}`)
      const j = await r.json()
      if (j.ok) setPreview({ path: p, text: j.text, binary: j.binary, truncated: j.truncated })
      else setPreview({ path: p, text: j.error || 'Preview failed', binary: false, truncated: false })
    } catch {
      setPreview({ path: p, text: 'Preview failed', binary: false, truncated: false })
    } finally {
      setPreviewing(false)
    }
  }, [])

  const crumbs = path === '/' ? [] : path.split('/').filter(Boolean)

  return (
    <div className="panel flex h-full min-h-0 flex-1 flex-col overflow-hidden">
      <header className="flex shrink-0 flex-wrap items-center justify-between gap-2 border-b border-border px-4 py-3">
        <div>
          <h2 className="flex items-center gap-2 text-sm font-semibold text-foreground">
            <Server className="h-4 w-4 text-emerald-400" />
            Hadoop HDFS
          </h2>
          <p className="text-[10px] text-foreground-muted">
            {health?.namenode || '10.0.21.61:9870'} · {health?.live_datanodes ?? '—'} datanodes ·{' '}
            {health?.capacity_used_human || '—'} / {health?.capacity_total_human || '—'}
            {typeof health?.capacity_used_pct === 'number' ? ` (${health.capacity_used_pct}%)` : ''}
          </p>
        </div>
        <div className="flex flex-wrap items-center gap-2">
          <div className="flex gap-0.5 rounded-md border border-border p-0.5">
            <button type="button" onClick={() => setTab('files')} className={cn('inline-flex items-center gap-1 rounded px-2.5 py-1 text-[11px]', tab === 'files' ? subTabActive : subTabIdle)}>
              <HardDrive className="h-3 w-3" /> Files
            </button>
            <button type="button" onClick={() => setTab('analytics')} className={cn('inline-flex items-center gap-1 rounded px-2.5 py-1 text-[11px]', tab === 'analytics' ? subTabActive : subTabIdle)}>
              <BarChart3 className="h-3 w-3" /> Analytics
            </button>
          </div>
          <a href="http://10.0.21.61:9870" target="_blank" rel="noreferrer" className={cn('inline-flex items-center gap-1 rounded-md px-3 py-1.5 text-[11px] font-medium', subTabActive)}>
            NameNode UI
          </a>
          <button type="button" onClick={() => { loadHealth(); loadList(path) }} className={cn('rounded-md px-3 py-1.5 text-[11px]', subTabIdle)}>
            <RefreshCw className={cn('inline h-3 w-3', loading && 'animate-spin')} /> Refresh
          </button>
        </div>
      </header>

      {tab === 'analytics' && <HadoopAnalytics />}

      {tab === 'files' && (
      <div className="flex min-h-0 flex-1 flex-col p-3">
        <nav className="mb-2 flex flex-wrap items-center gap-1 text-[10px] text-foreground-muted">
          <button type="button" className="font-medium hover:text-emerald-400" onClick={() => setPath('/')}>
            HDFS root
          </button>
          {crumbs.map((c, i) => (
            <span key={i} className="inline-flex items-center gap-1">
              <ChevronRight className="h-3 w-3" />
              <button
                type="button"
                className="hover:text-emerald-400"
                onClick={() => setPath('/' + crumbs.slice(0, i + 1).join('/'))}
              >
                {c}
              </button>
            </span>
          ))}
        </nav>

        {loading && (
          <p className="flex items-center gap-2 text-[11px] text-foreground-muted">
            <Loader2 className="h-4 w-4 animate-spin" /> Loading…
          </p>
        )}
        {error && <p className="mb-2 text-[11px] text-danger">{error}</p>}

        <div className="scrollbar-thin min-h-0 flex-1 overflow-y-auto">
          <table className="w-full text-left text-[11px]">
            <thead>
              <tr className="border-b border-border text-[9px] uppercase text-foreground-faint">
                <th className="py-1.5 pr-2">Name</th>
                <th className="py-1.5 pr-2">Size</th>
                <th className="py-1.5 pr-2">Owner</th>
                <th className="py-1.5 pr-2">Perms</th>
                <th className="py-1.5 pr-2">Modified</th>
                <th className="py-1.5" />
              </tr>
            </thead>
            <tbody>
              {folders.map((f) => (
                <tr key={f.path} className="border-b border-border/50 hover:bg-surface-overlay/50">
                  <td className="py-1.5 pr-2">
                    <button
                      type="button"
                      className="inline-flex items-center gap-1 font-medium text-emerald-400 hover:underline"
                      onClick={() => setPath(f.path)}
                    >
                      <Folder className="h-3.5 w-3.5" /> {f.name}/
                    </button>
                  </td>
                  <td className="py-1.5 pr-2 text-foreground-faint">—</td>
                  <td className="py-1.5 pr-2 text-foreground-muted">{f.owner}</td>
                  <td className="py-1.5 pr-2 font-mono text-[9px] text-foreground-faint">{f.perms}</td>
                  <td className="py-1.5 pr-2 text-foreground-faint">{f.modified?.slice(0, 19).replace('T', ' ') || '—'}</td>
                  <td />
                </tr>
              ))}
              {files.map((o) => (
                <tr key={o.path} className="border-b border-border/50 hover:bg-surface-overlay/50">
                  <td className="max-w-[280px] truncate py-1.5 pr-2">
                    <span className="inline-flex items-center gap-1 font-mono text-[10px]">
                      <FileText className="h-3.5 w-3.5 shrink-0 text-foreground-faint" /> {o.name}
                    </span>
                  </td>
                  <td className="py-1.5 pr-2 text-foreground-muted">{o.size_human}</td>
                  <td className="py-1.5 pr-2 text-foreground-muted">{o.owner}</td>
                  <td className="py-1.5 pr-2 font-mono text-[9px] text-foreground-faint">{o.perms}</td>
                  <td className="py-1.5 pr-2 text-foreground-faint">{o.modified?.slice(0, 19).replace('T', ' ') || '—'}</td>
                  <td className="py-1.5">
                    <div className="flex items-center gap-2">
                      <button type="button" title="Preview" className="text-foreground-muted hover:text-emerald-400" onClick={() => openPreview(o.path)}>
                        <Eye className="h-3.5 w-3.5" />
                      </button>
                      <a
                        title="Download"
                        href={`/api/storage/hdfs/download?path=${encodeURIComponent(o.path)}`}
                        className="text-foreground-muted hover:text-emerald-400"
                      >
                        <Download className="h-3.5 w-3.5" />
                      </a>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
          {!loading && folders.length === 0 && files.length === 0 && !error && (
            <p className="py-8 text-center text-sm text-foreground-muted">This directory is empty.</p>
          )}
        </div>
      </div>
      )}

      {preview && (
        <div className="absolute inset-0 z-50 flex items-center justify-center bg-black/60 p-6" onClick={() => setPreview(null)}>
          <div className="flex max-h-[80vh] w-full max-w-3xl flex-col overflow-hidden rounded-lg border border-border bg-surface" onClick={(e) => e.stopPropagation()}>
            <div className="flex items-center justify-between border-b border-border px-4 py-2">
              <span className="truncate font-mono text-[11px] text-foreground">{preview.path}</span>
              <button type="button" onClick={() => setPreview(null)} className="text-foreground-muted hover:text-foreground">
                <X className="h-4 w-4" />
              </button>
            </div>
            {preview.binary && <p className="px-4 pt-2 text-[10px] text-amber-400">Binary file — showing decoded preview.</p>}
            <pre className="scrollbar-thin min-h-0 flex-1 overflow-auto whitespace-pre-wrap break-words p-4 font-mono text-[11px] leading-relaxed text-foreground-muted">
              {previewing ? 'Loading…' : preview.text}
              {preview.truncated && '\n\n… (truncated)'}
            </pre>
          </div>
        </div>
      )}
    </div>
  )
}
