import { useState, useEffect, useCallback } from 'react'
import { motion, AnimatePresence } from 'framer-motion'
import {
  Dna, Brain, DollarSign, Scale, Hash, Shield, Film, Image,
  RefreshCw, Lock, Unlock, Loader2, AlertTriangle, Check, Play,
  FileText, TrendingUp, Activity, Eye,
} from 'lucide-react'

const API_BASE = ''

const GLYPHS = {
  dna: '◇', ml: '⟡', valuation: '$', profile: '§', kpi: '#',
  password: '🔒', gif: '⌁', video: '▶', reindex: '↻',
}

export default function FileIntelligence({ fileId, onBack }) {
  const [files, setFiles] = useState([])
  const [selectedId, setSelectedId] = useState(fileId)
  const [activeTab, setActiveTab] = useState('dna')
  const [loading, setLoading] = useState(false)

  useEffect(() => {
    fetch(`${API_BASE}/files`).then(r => r.json()).then(d => {
      setFiles(d.files || [])
      if (!selectedId && d.files?.length > 0) setSelectedId(d.files[0].file_id)
    }).catch(() => {})
  }, [])

  useEffect(() => { if (fileId) setSelectedId(fileId) }, [fileId])

  const tabs = [
    { id: 'dna', label: 'DNA', icon: Dna },
    { id: 'ml', label: 'ML', icon: Brain },
    { id: 'valuation', label: 'Valuation', icon: DollarSign },
    { id: 'profile', label: 'Profile', icon: Scale },
    { id: 'kpi', label: 'KPIs', icon: Hash },
    { id: 'password', label: 'Password', icon: Shield },
    { id: 'gif', label: 'KPI GIF', icon: Image },
    { id: 'video', label: 'Video', icon: Film },
    { id: 'reindex', label: 'Reindex', icon: RefreshCw },
  ]

  return (
    <div className="p-6 h-full overflow-y-auto thin-scrollbar">
      {/* File selector + back */}
      <div className="flex items-center gap-2 mb-4 flex-wrap">
        {onBack && (
          <button onClick={onBack} className="flex items-center gap-1 text-xs text-secondary hover:text-text px-2 py-1.5 rounded-lg glass transition-all">
            ← Back
          </button>
        )}
        {files.map(f => (
          <button
            key={f.file_id}
            onClick={() => setSelectedId(f.file_id)}
            className={`px-3 py-1.5 rounded-lg text-xs font-mono transition-all ${selectedId === f.file_id ? 'glass-orange text-primary' : 'glass text-secondary hover:text-text'}`}
          >
            {f.filename}
          </button>
        ))}
      </div>

      {/* Tabs */}
      <div className="flex items-center gap-1 mb-4 flex-wrap">
        {tabs.map(tab => (
          <button
            key={tab.id}
            onClick={() => setActiveTab(tab.id)}
            className={`flex items-center gap-1.5 px-3 py-2 rounded-xl text-xs transition-all ${activeTab === tab.id ? 'glass-orange text-primary font-medium' : 'glass text-secondary hover:text-text'}`}
          >
            <tab.icon className="w-3.5 h-3.5" />
            {tab.label}
          </button>
        ))}
      </div>

      <AnimatePresence mode="wait">
        <motion.div
          key={activeTab}
          initial={{ opacity: 0, y: 10 }}
          animate={{ opacity: 1, y: 0 }}
          exit={{ opacity: 0, y: -10 }}
          transition={{ duration: 0.2 }}
        >
          {selectedId && activeTab === 'dna' && <DNAPanel fileId={selectedId} />}
          {selectedId && activeTab === 'ml' && <MLPanel fileId={selectedId} />}
          {selectedId && activeTab === 'valuation' && <ValuationPanel fileId={selectedId} />}
          {selectedId && activeTab === 'profile' && <ProfilePanel fileId={selectedId} />}
          {selectedId && activeTab === 'kpi' && <KPIPanel fileId={selectedId} />}
          {selectedId && activeTab === 'password' && <PasswordPanel fileId={selectedId} />}
          {selectedId && activeTab === 'gif' && <GIFPanel fileId={selectedId} />}
          {selectedId && activeTab === 'video' && <VideoPanel fileId={selectedId} />}
          {selectedId && activeTab === 'reindex' && <ReindexPanel fileId={selectedId} />}
          {!selectedId && (
            <div className="flex items-center justify-center py-12 text-secondary text-sm">No file selected.</div>
          )}
        </motion.div>
      </AnimatePresence>
    </div>
  )
}

// ─── DNA Panel ──────────────────────────────────────────────────────────

function DNAPanel({ fileId }) {
  const [data, setData] = useState(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetch(`${API_BASE}/dna/${fileId}`).then(r => r.json()).then(d => setData(d)).catch(() => setData({ error: 'Failed' })).finally(() => setLoading(false))
  }, [fileId])

  if (loading) return <LoadingSpinner label="Extracting DNA fingerprint..." />
  if (data?.error) return <ErrorBox msg={data.error} />

  const genes = data.genes || {}
  const complexity = data.complexity_score || 0

  return (
    <div className="space-y-4">
      <div className="glass rounded-2xl p-5">
        <div className="flex items-center gap-3 mb-4">
          <span className="text-primary text-lg font-mono">{GLYPHS.dna}</span>
          <Dna className="w-5 h-5 text-primary" />
          <span className="text-sm font-semibold">Structural DNA</span>
          <span className="ml-auto text-[10px] font-mono text-secondary/40">{data.genome_size || 0} bytes</span>
        </div>
        <div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-4">
          <StatBox label="Species" value={data.species || '—'} mono />
          <StatBox label="Complexity" value={`${complexity}/100`} mono />
          <StatBox label="DNA Sequence" value={data.dna_sequence ? `${data.dna_sequence.slice(0, 20)}...` : '—'} mono />
          <StatBox label="Genome Size" value={`${data.genome_size || 0} bytes`} mono />
        </div>
        <div className="pt-3 border-t border-white/5">
          <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-3">Genes (10 structural metrics)</div>
          <div className="grid grid-cols-2 md:grid-cols-5 gap-2">
            {Object.entries(genes).map(([k, v]) => (
              <div key={k} className="glass rounded-xl p-3">
                <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-1">{k.replace(/_/g, ' ')}</div>
                <div className="text-sm font-mono text-text">{typeof v === 'number' ? v.toLocaleString() : String(v).slice(0, 20)}</div>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  )
}

// ─── ML Panel ───────────────────────────────────────────────────────────

function MLPanel({ fileId }) {
  const [data, setData] = useState(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetch(`${API_BASE}/ml/${fileId}`).then(r => r.json()).then(d => setData(d)).catch(() => setData({ error: 'Failed' })).finally(() => setLoading(false))
  }, [fileId])

  if (loading) return <LoadingSpinner label="Running ML inference..." />
  if (data?.error) return <ErrorBox msg={data.error} />

  const ml = data.ml || {}
  if (!ml.available) return (
    <div className="glass rounded-2xl p-8 text-center">
      <AlertTriangle className="w-6 h-6 text-warning mx-auto mb-3" />
      <div className="text-sm text-secondary">ML unavailable — {ml.error || 'unknown error'}</div>
    </div>
  )

  return (
    <div className="space-y-4">
      <div className="glass rounded-2xl p-5">
        <div className="flex items-center gap-3 mb-4">
          <span className="text-primary text-lg font-mono">{GLYPHS.ml}</span>
          <Brain className="w-5 h-5 text-primary" />
          <span className="text-sm font-semibold">ML Insights</span>
          <span className="ml-auto text-[10px] font-mono px-2 py-1 rounded-lg glass-orange text-primary">{ml.engine || 'sklearn'}</span>
        </div>

        {/* TF-IDF */}
        {ml.tfidf_top_terms?.length > 0 && (
          <div className="mb-4">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">TF-IDF Top Terms</div>
            <div className="flex flex-wrap gap-1.5">
              {ml.tfidf_top_terms.map((t, i) => (
                <span key={i} className="text-[10px] px-2 py-1 rounded-lg glass-orange text-primary font-mono">
                  {t.term} <span className="text-secondary/40">{t.score}</span>
                </span>
              ))}
            </div>
          </div>
        )}

        {/* Topics */}
        {ml.topics?.length > 0 && (
          <div className="mb-4">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">Topics</div>
            <div className="space-y-2">
              {ml.topics.map((t, i) => (
                <div key={i} className="flex items-center gap-3 py-2 px-3 rounded-lg bg-white/3">
                  <span className="text-[10px] font-mono text-primary flex-shrink-0">T{t.topic_id}</span>
                  <div className="flex-1 flex flex-wrap gap-1">
                    {t.keywords?.map((kw, j) => (
                      <span key={j} className="text-[10px] px-1.5 py-0.5 rounded bg-white/5 text-secondary font-mono">{kw}</span>
                    ))}
                  </div>
                  <span className="text-[10px] font-mono text-secondary/40 flex-shrink-0">{t.chunk_count} chunks · {t.strength}</span>
                </div>
              ))}
            </div>
          </div>
        )}

        {/* Clusters */}
        {ml.clusters && Object.keys(ml.clusters).length > 0 && (
          <div className="mb-4">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">Clusters</div>
            <div className="grid grid-cols-1 md:grid-cols-3 gap-2">
              {Object.entries(ml.clusters).map(([k, c]) => (
                <div key={k} className="glass rounded-xl p-3">
                  <div className="text-[10px] font-mono text-primary mb-1">{k}</div>
                  <div className="text-xs text-secondary mb-1">{c.size} chunks</div>
                  <div className="flex flex-wrap gap-1">
                    {c.centroid_terms?.map((t, i) => (
                      <span key={i} className="text-[9px] px-1.5 py-0.5 rounded bg-white/5 text-secondary font-mono">{t}</span>
                    ))}
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}

        {/* Anomalies */}
        {ml.anomalies?.length > 0 && (
          <div className="mb-4">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">Anomalies ({ml.anomalies.length})</div>
            <div className="space-y-1">
              {ml.anomalies.map((a, i) => (
                <div key={i} className="flex items-center gap-2 py-1.5 px-2 rounded-lg bg-warning/5 text-[10px] font-mono">
                  <AlertTriangle className="w-3 h-3 text-warning flex-shrink-0" />
                  <span className="text-warning">Chunk #{a.chunk_idx}</span>
                  <span className="text-secondary/60 truncate">{a.reason}</span>
                </div>
              ))}
            </div>
          </div>
        )}

        {/* Inferred KPIs */}
        {ml.inferred_kpis?.length > 0 && (
          <div>
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">Inferred KPIs</div>
            <div className="grid grid-cols-1 md:grid-cols-2 gap-2">
              {ml.inferred_kpis.map((k, i) => (
                <div key={i} className="flex items-center gap-2 py-1.5 px-2 rounded-lg bg-white/3">
                  <span className="text-[10px] font-mono text-primary flex-shrink-0">{k.name}</span>
                  <span className="text-[10px] font-mono text-text flex-1 truncate">{k.value}</span>
                  <span className="text-[9px] font-mono text-secondary/40">{k.method}</span>
                </div>
              ))}
            </div>
          </div>
        )}

        {/* LLM Extrapolation */}
        {ml.llm_extrapolation && (
          <div className="mt-4 pt-3 border-t border-white/5">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">LLM Extrapolation</div>
            <div className="space-y-2 text-xs">
              {ml.llm_extrapolation.inferred_purpose && <div className="text-secondary"><span className="text-primary font-mono">Purpose:</span> {ml.llm_extrapolation.inferred_purpose}</div>}
              {ml.llm_extrapolation.hidden_value && <div className="text-secondary"><span className="text-primary font-mono">Hidden Value:</span> {ml.llm_extrapolation.hidden_value}</div>}
              {ml.llm_extrapolation.counterparty_risk && <div className="text-secondary"><span className="text-critical font-mono">Risk:</span> {ml.llm_extrapolation.counterparty_risk}</div>}
              {ml.llm_extrapolation.monetization_vector && <div className="text-secondary"><span className="text-success font-mono">Monetization:</span> {ml.llm_extrapolation.monetization_vector}</div>}
            </div>
          </div>
        )}
      </div>
    </div>
  )
}

// ─── Valuation Panel ────────────────────────────────────────────────────

function ValuationPanel({ fileId }) {
  const [data, setData] = useState(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetch(`${API_BASE}/valuation/${fileId}`).then(r => r.json()).then(d => setData(d)).catch(() => setData({ error: 'Failed' })).finally(() => setLoading(false))
  }, [fileId])

  if (loading) return <LoadingSpinner label="Computing valuation..." />
  if (data?.error) return <ErrorBox msg={data.error} />

  const v = data.valuation || {}

  return (
    <div className="space-y-4">
      <div className="glass rounded-2xl p-5">
        <div className="flex items-center gap-3 mb-4">
          <span className="text-primary text-lg font-mono">{GLYPHS.valuation}</span>
          <DollarSign className="w-5 h-5 text-primary" />
          <span className="text-sm font-semibold">Valuation</span>
        </div>
        <div className="grid grid-cols-2 md:grid-cols-4 gap-3 mb-4">
          <ValueBox label="Build Cost" value={v.build_cost?.estimated_usd} glyph="⌁" />
          <ValueBox label="Replacement" value={v.replacement_cost?.estimated_usd} glyph="↻" />
          <ValueBox label="Insurance" value={v.insurance_value?.estimated_usd} glyph="◆" />
          <ValueBox label="Depreciated" value={v.depreciation?.depreciated_value_usd} glyph="▼" sub={`${v.depreciation?.remaining_value_pct || 0}% remaining`} />
        </div>
        <div className="grid grid-cols-2 md:grid-cols-3 gap-3">
          <div className="glass rounded-xl p-3">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-1">Prod Readiness</div>
            <div className="flex items-center gap-2">
              <span className="text-lg font-bold text-primary">{v.production_readiness?.grade || 'F'}</span>
              <span className="text-secondary font-mono text-xs">{v.production_readiness?.score || 0}/100</span>
            </div>
            <div className="text-[10px] text-secondary/60 mt-1">{v.production_readiness?.distance_to_prod || '—'}</div>
          </div>
          <div className="glass rounded-xl p-3">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-1">File Type</div>
            <div className="text-sm font-mono">{v.build_cost?.breakdown?.file_type || '—'}</div>
            <div className="text-[10px] text-secondary/60 mt-1">Rate: ${v.build_cost?.breakdown?.rate_per_loc || 0}/LOC</div>
          </div>
          <div className="glass rounded-xl p-3">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-1">Difficulty</div>
            <div className="text-sm font-mono capitalize">{v.replacement_cost?.difficulty || '—'}</div>
            <div className="text-[10px] text-secondary/60 mt-1">{v.replacement_cost?.time_to_rebuild?.days || 0} days to rebuild</div>
          </div>
        </div>
        {v.production_readiness?.blocking_issues?.length > 0 && (
          <div className="mt-3 flex flex-wrap gap-1.5">
            {v.production_readiness.blocking_issues.map((issue, i) => (
              <span key={i} className="text-[10px] px-2 py-1 rounded-lg bg-critical/10 text-critical font-mono">⟁ {issue}</span>
            ))}
          </div>
        )}
        {v.depreciation?.signals?.length > 0 && (
          <div className="mt-3 pt-3 border-t border-white/5">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">Depreciation Signals</div>
            <div className="flex flex-wrap gap-1.5">
              {v.depreciation.signals.map((s, i) => (
                <span key={i} className="text-[10px] px-2 py-1 rounded-lg bg-warning/10 text-warning font-mono">{s}</span>
              ))}
            </div>
          </div>
        )}
      </div>
    </div>
  )
}

// ─── Profile Panel ──────────────────────────────────────────────────────

function ProfilePanel({ fileId }) {
  const [data, setData] = useState(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetch(`${API_BASE}/profile/${fileId}`).then(r => r.json()).then(d => setData(d)).catch(() => setData({ error: 'Failed' })).finally(() => setLoading(false))
  }, [fileId])

  if (loading) return <LoadingSpinner label="Building semantic profile..." />
  if (data?.error) return <ErrorBox msg={data.error} />

  const p = data.profile || {}

  return (
    <div className="space-y-4">
      <div className="glass rounded-2xl p-5">
        <div className="flex items-center gap-3 mb-4">
          <span className="text-primary text-lg font-mono">{GLYPHS.profile}</span>
          <Scale className="w-5 h-5 text-primary" />
          <span className="text-sm font-semibold">Semantic Profile</span>
        </div>

        {/* Origin */}
        <div className="mb-4">
          <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">Origin</div>
          <div className="text-sm font-mono text-primary mb-2">{p.origin?.primary || 'unknown'}</div>
          <div className="flex flex-wrap gap-1.5">
            {p.origin?.detected?.map((o, i) => (
              <span key={i} className="text-[10px] px-2 py-1 rounded-lg bg-white/5 text-secondary font-mono">
                {o.type} ({Math.round(o.confidence * 100)}%)
              </span>
            ))}
          </div>
        </div>

        {/* Accounting + Finance */}
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
          <div className="glass rounded-xl p-3">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">Accounting</div>
            {p.accounting?.standards_detected?.length > 0 ? (
              <div className="flex flex-wrap gap-1.5">
                {p.accounting.standards_detected.map(s => (
                  <span key={s} className="text-[10px] px-2 py-1 rounded-lg bg-white/5 text-secondary font-mono uppercase">{s}</span>
                ))}
              </div>
            ) : <div className="text-xs text-secondary/40">No standards detected</div>}
            {p.accounting?.concepts_found && Object.keys(p.accounting.concepts_found).length > 0 && (
              <div className="mt-2 flex flex-wrap gap-1.5">
                {Object.entries(p.accounting.concepts_found).map(([k, v]) => (
                  <span key={k} className="text-[10px] px-2 py-1 rounded-lg bg-white/5 text-secondary font-mono">{k} ×{v}</span>
                ))}
              </div>
            )}
          </div>
          <div className="glass rounded-xl p-3">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">Finance</div>
            {p.finance?.metrics_detected && Object.keys(p.finance.metrics_detected).length > 0 ? (
              <div className="flex flex-wrap gap-1.5">
                {Object.entries(p.finance.metrics_detected).map(([k, v]) => (
                  <span key={k} className="text-[10px] px-2 py-1 rounded-lg glass-orange text-primary font-mono">{k} ×{v}</span>
                ))}
              </div>
            ) : <div className="text-xs text-secondary/40">No metrics detected</div>}
          </div>
        </div>

        {/* Collateral + Liquidity + Risk */}
        <div className="grid grid-cols-1 md:grid-cols-3 gap-3">
          <div className="glass rounded-xl p-3">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-1">Collateral</div>
            <div className="flex items-center gap-2">
              <span className="text-lg font-bold text-primary">{p.collateral?.grade || 'F'}</span>
              <span className="text-xs font-mono text-secondary">{p.collateral?.score || 0}/100</span>
            </div>
          </div>
          <div className="glass rounded-xl p-3">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-1">Liquidity</div>
            <div className="flex items-center gap-2">
              <span className="text-lg font-bold text-primary">{p.liquidity?.grade || 'F'}</span>
              <span className="text-xs font-mono text-secondary">{p.liquidity?.score || 0}/100</span>
            </div>
            <div className="text-[10px] text-secondary/60 mt-1">{p.liquidity?.time_to_liquidate || '—'}</div>
          </div>
          <div className="glass rounded-xl p-3">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-1">Risk Level</div>
            <div className="text-lg font-bold capitalize text-primary">{p.risk?.level || 'unknown'}</div>
            <div className="text-[10px] text-secondary/60 mt-1">{p.risk?.score || 0}/100</div>
          </div>
        </div>
      </div>
    </div>
  )
}

// ─── KPI Panel ──────────────────────────────────────────────────────────

function KPIPanel({ fileId }) {
  const [data, setData] = useState(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetch(`${API_BASE}/kpi/${fileId}`).then(r => r.json()).then(d => setData(d)).catch(() => setData({ error: 'Failed' })).finally(() => setLoading(false))
  }, [fileId])

  if (loading) return <LoadingSpinner label="Extracting KPIs..." />
  if (data?.error) return <ErrorBox msg={data.error} />

  const cats = data.by_category || {}

  return (
    <div className="space-y-4">
      <div className="glass rounded-2xl p-5">
        <div className="flex items-center gap-3 mb-4">
          <span className="text-primary text-lg font-mono">{GLYPHS.kpi}</span>
          <Hash className="w-5 h-5 text-primary" />
          <span className="text-sm font-semibold">KPIs ({data.total_kpis || 0})</span>
        </div>
        {Object.keys(cats).length === 0 ? (
          <div className="text-xs text-secondary/40 py-4 text-center">No KPIs extracted</div>
        ) : (
          <div className="space-y-4">
            {Object.entries(cats).map(([cat, kpis]) => (
              <div key={cat}>
                <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">{cat} ({kpis.length})</div>
                <div className="space-y-1">
                  {kpis.map((k, i) => (
                    <div key={i} className="flex items-center gap-3 py-1.5 px-2 rounded-lg hover:bg-white/5 text-[11px] font-mono">
                      <span className="text-primary flex-shrink-0 w-28 truncate">{k.name}</span>
                      <span className="text-text flex-1 truncate">{k.value}</span>
                      <span className="text-secondary/40 flex-shrink-0">L{k.line}</span>
                      <span className="text-secondary/30 flex-shrink-0">{Math.round((k.confidence || 0) * 100)}%</span>
                    </div>
                  ))}
                </div>
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  )
}

// ─── Password Panel ─────────────────────────────────────────────────────

function PasswordPanel({ fileId }) {
  const [status, setStatus] = useState(null)
  const [password, setPassword] = useState('')
  const [verifyPassword, setVerifyPassword] = useState('')
  const [result, setResult] = useState(null)
  const [verifyResult, setVerifyResult] = useState(null)
  const [loading, setLoading] = useState(false)

  useEffect(() => {
    fetch(`${API_BASE}/password/${fileId}/status`).then(r => r.json()).then(d => setStatus(d)).catch(() => setStatus({ error: 'Failed' }))
  }, [fileId])

  const setPassword_ = async () => {
    if (!password) return
    setLoading(true); setResult(null)
    try {
      const res = await fetch(`${API_BASE}/password/${fileId}`, {
        method: 'POST', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ password })
      })
      const d = await res.json()
      setResult(d)
      if (!d.error) { setStatus({ has_password: true }); setPassword('') }
    } catch (e) { setResult({ error: e.message }) }
    finally { setLoading(false) }
  }

  const verifyPwd = async () => {
    if (!verifyPassword) return
    setLoading(true); setVerifyResult(null)
    try {
      const res = await fetch(`${API_BASE}/password/${fileId}/verify`, {
        method: 'POST', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ password: verifyPassword })
      })
      const d = await res.json()
      setVerifyResult(d)
    } catch (e) { setVerifyResult({ error: e.message }) }
    finally { setLoading(false) }
  }

  const hasPwd = status?.has_password

  return (
    <div className="space-y-4">
      <div className="glass rounded-2xl p-5">
        <div className="flex items-center gap-3 mb-4">
          <span className="text-primary text-lg font-mono">{GLYPHS.password}</span>
          {hasPwd ? <Lock className="w-5 h-5 text-success" /> : <Unlock className="w-5 h-5 text-warning" />}
          <span className="text-sm font-semibold">Password Protection</span>
          <span className={`ml-auto text-[10px] font-mono px-2 py-1 rounded-lg ${hasPwd ? 'bg-success/10 text-success' : 'bg-warning/10 text-warning'}`}>
            {hasPwd ? '◆ PROTECTED' : '◌ UNPROTECTED'}
          </span>
        </div>

        {/* Set password */}
        <div className="mb-4">
          <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">{hasPwd ? 'Update Password' : 'Set Password'}</div>
          <div className="flex items-center gap-2">
            <input
              type="password"
              value={password}
              onChange={e => setPassword(e.target.value)}
              onKeyDown={e => e.key === 'Enter' && setPassword_()}
              placeholder="Enter password..."
              className="flex-1 px-3 py-2 rounded-xl glass text-xs font-mono text-text placeholder:text-secondary/30 outline-none focus:glass-orange"
            />
            <button
              onClick={setPassword_}
              disabled={loading || !password}
              className="px-4 py-2 rounded-xl glass-orange text-primary text-xs font-mono disabled:opacity-30"
            >
              {loading ? <Loader2 className="w-3 h-3 animate-spin" /> : hasPwd ? 'Update' : 'Set'}
            </button>
          </div>
          {result?.error && <div className="text-[10px] text-critical mt-2 font-mono">⟁ {result.error}</div>}
          {result?.status === 'set' && <div className="text-[10px] text-success mt-2 font-mono">◆ Password set successfully</div>}
        </div>

        {/* Verify password */}
        {hasPwd && (
          <div className="pt-3 border-t border-white/5">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">Verify Password</div>
            <div className="flex items-center gap-2">
              <input
                type="password"
                value={verifyPassword}
                onChange={e => setVerifyPassword(e.target.value)}
                onKeyDown={e => e.key === 'Enter' && verifyPwd()}
                placeholder="Enter password to verify..."
                className="flex-1 px-3 py-2 rounded-xl glass text-xs font-mono text-text placeholder:text-secondary/30 outline-none focus:glass-orange"
              />
              <button
                onClick={verifyPwd}
                disabled={loading || !verifyPassword}
                className="px-4 py-2 rounded-xl glass text-secondary text-xs font-mono hover:glass-orange disabled:opacity-30"
              >
                Verify
              </button>
            </div>
            {verifyResult?.verified && <div className="text-[10px] text-success mt-2 font-mono flex items-center gap-1"><Check className="w-3 h-3" /> Verified — access granted</div>}
            {verifyResult?.verified === false && <div className="text-[10px] text-critical mt-2 font-mono flex items-center gap-1"><AlertTriangle className="w-3 h-3" /> Incorrect password</div>}
            {verifyResult?.error && <div className="text-[10px] text-critical mt-2 font-mono">⟁ {verifyResult.error}</div>}
          </div>
        )}

        {/* Hash info */}
        {status?.hash_prefix && (
          <div className="mt-4 pt-3 border-t border-white/5">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-1">Hash</div>
            <div className="text-[10px] font-mono text-secondary/60">{status.hash_prefix}... · PBKDF2 · {status.iterations || 100000} iterations</div>
          </div>
        )}
      </div>
    </div>
  )
}

// ─── GIF Panel ──────────────────────────────────────────────────────────

function GIFPanel({ fileId }) {
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState(null)
  const [gifUrl, setGifUrl] = useState(null)

  const generate = async () => {
    setLoading(true); setError(null); setGifUrl(null)
    try {
      const res = await fetch(`${API_BASE}/kpi/${fileId}/gif`)
      if (!res.ok) {
        const d = await res.json().catch(() => ({}))
        setError(d.error || `HTTP ${res.status}`)
      } else {
        const blob = await res.blob()
        setGifUrl(URL.createObjectURL(blob))
      }
    } catch (e) { setError(e.message) }
    finally { setLoading(false) }
  }

  return (
    <div className="space-y-4">
      <div className="glass rounded-2xl p-5">
        <div className="flex items-center gap-3 mb-4">
          <span className="text-primary text-lg font-mono">{GLYPHS.gif}</span>
          <Image className="w-5 h-5 text-primary" />
          <span className="text-sm font-semibold">KPI Animated GIF</span>
        </div>
        <button
          onClick={generate}
          disabled={loading}
          className="px-4 py-2 rounded-xl glass-orange text-primary text-xs font-mono disabled:opacity-30 flex items-center gap-2"
        >
          {loading ? <><Loader2 className="w-3 h-3 animate-spin" /> Generating...</> : <><Play className="w-3 h-3" /> Generate GIF</>}
        </button>
        {error && <div className="text-[10px] text-critical mt-3 font-mono">⟁ {error}</div>}
        {gifUrl && (
          <div className="mt-4">
            <img src={gifUrl} alt="KPI Animation" className="rounded-xl max-w-full" />
            <a href={gifUrl} download={`${fileId}_kpi.gif`} className="text-[10px] text-primary hover:text-accent mt-2 inline-block font-mono">↓ Download GIF</a>
          </div>
        )}
      </div>
    </div>
  )
}

// ─── Video Panel ────────────────────────────────────────────────────────

function VideoPanel({ fileId }) {
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState(null)
  const [videoUrl, setVideoUrl] = useState(null)

  const generate = async () => {
    setLoading(true); setError(null); setVideoUrl(null)
    try {
      const res = await fetch(`${API_BASE}/video/${fileId}`)
      if (!res.ok) {
        const d = await res.json().catch(() => ({}))
        setError(d.error || `HTTP ${res.status}`)
      } else {
        const blob = await res.blob()
        setVideoUrl(URL.createObjectURL(blob))
      }
    } catch (e) { setError(e.message) }
    finally { setLoading(false) }
  }

  return (
    <div className="space-y-4">
      <div className="glass rounded-2xl p-5">
        <div className="flex items-center gap-3 mb-4">
          <span className="text-primary text-lg font-mono">{GLYPHS.video}</span>
          <Film className="w-5 h-5 text-primary" />
          <span className="text-sm font-semibold">Video Dossier</span>
        </div>
        <button
          onClick={generate}
          disabled={loading}
          className="px-4 py-2 rounded-xl glass-orange text-primary text-xs font-mono disabled:opacity-30 flex items-center gap-2"
        >
          {loading ? <><Loader2 className="w-3 h-3 animate-spin" /> Rendering video...</> : <><Play className="w-3 h-3" /> Generate Video</>}
        </button>
        {error && <div className="text-[10px] text-critical mt-3 font-mono">⟁ {error}</div>}
        {videoUrl && (
          <div className="mt-4">
            <video src={videoUrl} controls className="rounded-xl max-w-full" />
            <a href={videoUrl} download={`${fileId}_dossier.mp4`} className="text-[10px] text-primary hover:text-accent mt-2 inline-block font-mono">↓ Download Video</a>
          </div>
        )}
      </div>
    </div>
  )
}

// ─── Reindex Panel ──────────────────────────────────────────────────────

function ReindexPanel({ fileId }) {
  const [loading, setLoading] = useState(false)
  const [result, setResult] = useState(null)
  const [error, setError] = useState(null)

  const reindex = async () => {
    setLoading(true); setResult(null); setError(null)
    try {
      const res = await fetch(`${API_BASE}/reindex/${fileId}`, { method: 'POST' })
      const d = await res.json()
      if (d.error) setError(d.error)
      else setResult(d)
    } catch (e) { setError(e.message) }
    finally { setLoading(false) }
  }

  return (
    <div className="space-y-4">
      <div className="glass rounded-2xl p-5">
        <div className="flex items-center gap-3 mb-4">
          <span className="text-primary text-lg font-mono">{GLYPHS.reindex}</span>
          <RefreshCw className="w-5 h-5 text-primary" />
          <span className="text-sm font-semibold">Re-Index File</span>
        </div>
        <div className="text-xs text-secondary mb-4">
          Rebuilds the file index with the latest extraction algorithms. Use after backend updates to refresh DNA, KPIs, and all analysis layers.
        </div>
        <button
          onClick={reindex}
          disabled={loading}
          className="px-4 py-2 rounded-xl glass-orange text-primary text-xs font-mono disabled:opacity-30 flex items-center gap-2"
        >
          {loading ? <><Loader2 className="w-3 h-3 animate-spin" /> Re-indexing...</> : <><RefreshCw className="w-3 h-3" /> Re-Index Now</>}
        </button>
        {error && <div className="text-[10px] text-critical mt-3 font-mono">⟁ {error}</div>}
        {result && (
          <div className="mt-4 pt-3 border-t border-white/5">
            <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-2">Result</div>
            <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
              <StatBox label="File ID" value={result.file_id || result.new_file_id} mono />
              <StatBox label="Lines" value={result.total_lines} mono />
              <StatBox label="Chunks" value={result.total_chunks} mono />
              <StatBox label="KPIs" value={result.kpi_count} mono />
            </div>
            {result.old_file_id !== result.new_file_id && (
              <div className="text-[10px] text-warning mt-2 font-mono">⚠ File ID changed: {result.old_file_id} → {result.new_file_id}</div>
            )}
          </div>
        )}
      </div>
    </div>
  )
}

// ─── Helper components ──────────────────────────────────────────────────

function LoadingSpinner({ label }) {
  return (
    <div className="flex items-center justify-center py-12">
      <div className="flex flex-col items-center gap-3">
        <Loader2 className="w-5 h-5 text-primary animate-spin" />
        <div className="text-xs text-secondary font-mono">{label}</div>
      </div>
    </div>
  )
}

function ErrorBox({ msg }) {
  return (
    <div className="glass rounded-2xl p-8 text-center">
      <AlertTriangle className="w-6 h-6 text-critical mx-auto mb-3" />
      <div className="text-sm text-critical font-mono">{msg}</div>
    </div>
  )
}

function StatBox({ label, value, mono }) {
  return (
    <div className="glass rounded-xl p-3">
      <div className="text-[10px] uppercase tracking-wider text-secondary/50 mb-1">{label}</div>
      <div className={`text-sm ${mono ? 'font-mono' : ''} text-text`}>{value ?? '—'}</div>
    </div>
  )
}

function ValueBox({ label, value, glyph, sub }) {
  const formatted = typeof value === 'number' && value > 0 ? `$${value.toLocaleString()}` : value ? `$${value}` : '—'
  return (
    <div className="glass rounded-xl p-3">
      <div className="flex items-center gap-1.5 mb-1">
        <span className="text-primary text-xs font-mono">{glyph}</span>
        <span className="text-[10px] uppercase tracking-wider text-secondary/50">{label}</span>
      </div>
      <div className="text-sm font-bold font-mono text-text">{formatted}</div>
      {sub && <div className="text-[9px] text-secondary/40 mt-0.5">{sub}</div>}
    </div>
  )
}
