import { useState, useEffect, useRef, useCallback, lazy, Suspense } from 'react'
import { Network } from 'vis-network'
import { api } from '../api/client'
import { useDebounce } from '../hooks/useDebounce'
import { useWants, useDontWants, useAntiPatterns, useSchemas, useProcedures, useStrategicIntents, useKnowledgeGraph } from '../hooks/useBrainData'

const BrainGraph3D = lazy(() => import('../components/BrainGraph3D'))

// ─── Tab types ───────────────────────────────────────────────
type BrainTab = 'graph' | '3d' | 'lessons' | 'failures' | 'patterns' | 'schemas' | 'procedures' | 'wants' | 'dont_wants' | 'strategic_intents' | 'anti_patterns'

const TABS: { key: BrainTab; label: string; icon: string }[] = [
  { key: 'graph', label: 'Knowledge Graph', icon: '🧠' },
  { key: '3d', label: '3D Brain', icon: '🌐' },
  { key: 'lessons', label: 'Lessons', icon: '📚' },
  { key: 'failures', label: 'Failures', icon: '⚠️' },
  { key: 'patterns', label: 'Patterns', icon: '🔄' },
  { key: 'schemas', label: 'Schemas', icon: '🏗️' },
  { key: 'procedures', label: 'Procedures', icon: '📋' },
  { key: 'wants', label: 'Wants', icon: '🎯' },
  { key: 'dont_wants', label: "Don't Wants", icon: '🚫' },
  { key: 'strategic_intents', label: 'Strategic Intents', icon: '🧭' },
  { key: 'anti_patterns', label: 'Anti-Patterns', icon: '🛡️' },
]

// ─── Search Results ──────────────────────────────────────────
interface SearchResult {
  source?: string
  title?: string
  text?: string
  score?: number
  relevance?: number
  salience?: number
  [key: string]: unknown
}

// ─── Knowledge Graph Visualization ──────────────────────────
function KnowledgeGraphViz({ graphData }: { graphData: { nodes: number; edges: number; data: any } | null }) {
  const containerRef = useRef<HTMLDivElement>(null)
  const networkRef = useRef<Network | null>(null)

  useEffect(() => {
    if (!containerRef.current || !graphData?.data) return

    // nodes can be a dict {id: node} or an array — normalize to array
    const nodesRaw = graphData.data.nodes || {}
    const allNodes: any[] = Array.isArray(nodesRaw)
      ? nodesRaw
      : Object.entries(nodesRaw).map(([k, v]: [string, any]) => ({ id: k, ...v }))
    const allEdges: any[] = Array.isArray(graphData.data.edges)
      ? graphData.data.edges
      : Object.values(graphData.data.edges || {})

    // vis-network can't handle 8K+ nodes — show top 3000 by connectivity
    const MAX_2D_NODES = 3000
    let rawNodes = allNodes
    let rawEdges = allEdges
    if (allNodes.length > MAX_2D_NODES) {
      // Count degrees per node
      const degreeMap = new Map<string, number>()
      for (const e of allEdges) {
        const from = String(e.from ?? e.source)
        const to = String(e.to ?? e.target)
        degreeMap.set(from, (degreeMap.get(from) || 0) + 1)
        degreeMap.set(to, (degreeMap.get(to) || 0) + 1)
      }
      // Sort by degree descending, take top N
      const sorted = [...allNodes].sort((a, b) =>
        (degreeMap.get(String(b.id)) || 0) - (degreeMap.get(String(a.id)) || 0)
      )
      rawNodes = sorted.slice(0, MAX_2D_NODES)
      const nodeIdSet = new Set(rawNodes.map((n: any) => String(n.id)))
      rawEdges = allEdges.filter((e: any) =>
        nodeIdSet.has(String(e.from ?? e.source)) && nodeIdSet.has(String(e.to ?? e.target))
      )
    }

    // Color map by node type
    const typeColors: Record<string, string> = {
      lesson: '#22c55e',
      failure: '#ef4444',
      pattern: '#3b82f6',
      schema: '#a855f7',
      procedure: '#ec4899',
      want: '#f59e0b',
      dont_want: '#f97316',
      intent: '#06b6d4',
      anti_pattern: '#d62728',
      decision: '#8dd3c7',
      concept: '#64748b',
      default: '#64748b',
    }

    // Compute degree per node for size + edge glow
    const degreeMap = new Map<string, number>()
    for (const e of rawEdges) {
      const from = String(e.from ?? e.source)
      const to = String(e.to ?? e.target)
      degreeMap.set(from, (degreeMap.get(from) || 0) + 1)
      degreeMap.set(to, (degreeMap.get(to) || 0) + 1)
    }
    const maxDeg = Math.max(1, ...degreeMap.values())

    const nodes = rawNodes.map((n: any, i: number) => {
      const deg = degreeMap.get(String(n.id ?? i)) || 0
      const degRatio = Math.pow(deg / maxDeg, 0.5)
      return {
        id: n.id ?? i,
        label: truncate(n.label || n.text || n.id || `Node ${i}`, 24),
        title: n.label || n.text || n.id || '',
        color: {
          background: typeColors[n.type?.toLowerCase()] || typeColors.default,
          border: '#1e293b',
          highlight: { background: '#38bdf8', border: '#0ea5e9' },
          opacity: 0.4 + 0.6 * degRatio,
        },
        font: { color: '#e2e8f0', size: 11 },
        shape: 'dot' as const,
        size: Math.min(6 + deg * 1.5 + (n.weight || 1) * 1.5, 28),
      }
    })

    const edges = rawEdges.map((e: any, i: number) => {
      const fromDeg = degreeMap.get(String(e.from ?? e.source)) || 0
      const toDeg = degreeMap.get(String(e.to ?? e.target)) || 0
      const avgDeg = (fromDeg + toDeg) / 2
      const glow = 0.15 + 0.65 * Math.pow(avgDeg / maxDeg, 0.5)
      return {
        id: e.id ?? `e_${i}`,
        from: e.from ?? e.source,
        to: e.to ?? e.target,
        color: { color: `rgba(56,189,248,${glow.toFixed(2)})`, highlight: '#38bdf8' },
        font: { color: '#94a3b8', size: 9, strokeWidth: 0 },
        arrows: { to: { enabled: true, scaleFactor: 0.5 } },
        smooth: { enabled: true, type: 'continuous' as const, roundness: 0.2 },
        width: 0.5 + glow * 2,
      }
    })

    const options = {
      physics: {
        solver: 'forceAtlas2Based',
        forceAtlas2Based: { gravitationalConstant: -30, centralGravity: 0.005, springLength: 120 },
        stabilization: { iterations: 100 },
      },
      interaction: {
        hover: true,
        tooltipDelay: 150,
        zoomView: true,
        dragView: true,
      },
      layout: { improvedLayout: rawNodes.length < 200 },
    }

    if (networkRef.current) {
      networkRef.current.destroy()
    }

    networkRef.current = new Network(containerRef.current, { nodes, edges }, options)

    return () => {
      networkRef.current?.destroy()
      networkRef.current = null
    }
  }, [graphData])

  if (!graphData?.data) {
    return (
      <div className="flex items-center justify-center h-80 text-slate-500 text-sm">
        No graph data available. Start the API server to load the knowledge graph.
      </div>
    )
  }

  return (
    <div>
      <div className="flex items-center gap-4 mb-3">
        <span className="text-xs text-slate-400">
          {graphData.nodes > 3000
            ? `Top 3,000 of ${graphData.nodes.toLocaleString()} nodes`
            : `${graphData.nodes} nodes`}
          {' '}&middot; {graphData.edges} edges
        </span>
        <div className="flex flex-wrap gap-3">
          {Object.entries({ lesson: '#22c55e', failure: '#ef4444', pattern: '#3b82f6', schema: '#a855f7', procedure: '#ec4899', want: '#f59e0b', intent: '#06b6d4', anti_pattern: '#d62728', decision: '#8dd3c7', concept: '#64748b' }).map(([type, color]) => (
            <span key={type} className="flex items-center gap-1 text-xs text-slate-500">
              <span className="w-2 h-2 rounded-full inline-block" style={{ background: color }} />
              {type}
            </span>
          ))}
        </div>
      </div>
      <div className="relative">
        <div
          ref={containerRef}
          className="w-full h-[480px] bg-slate-900/60 rounded-lg border border-slate-700/50"
        />
        <div className="absolute bottom-3 right-3 flex flex-col gap-1.5 z-10">
          <button
            onClick={() => networkRef.current?.moveTo({ scale: (networkRef.current.getScale() || 1) * 1.3 })}
            className="w-8 h-8 rounded-lg bg-slate-800/80 border border-slate-600/50 text-slate-300
              hover:bg-slate-700/80 hover:text-white transition-colors text-sm font-bold flex items-center justify-center"
            title="Zoom in"
          >+</button>
          <button
            onClick={() => networkRef.current?.moveTo({ scale: (networkRef.current.getScale() || 1) * 0.7 })}
            className="w-8 h-8 rounded-lg bg-slate-800/80 border border-slate-600/50 text-slate-300
              hover:bg-slate-700/80 hover:text-white transition-colors text-sm font-bold flex items-center justify-center"
            title="Zoom out"
          >-</button>
          <button
            onClick={() => networkRef.current?.fit({ animation: true })}
            className="w-8 h-8 rounded-lg bg-slate-800/80 border border-slate-600/50 text-slate-300
              hover:bg-slate-700/80 hover:text-white transition-colors text-[10px] flex items-center justify-center"
            title="Fit all"
          >FIT</button>
        </div>
      </div>
    </div>
  )
}

// ─── Search Bar ──────────────────────────────────────────────
function BrainSearch() {
  const [query, setQuery] = useState('')
  const [results, setResults] = useState<SearchResult[]>([])
  const [searching, setSearching] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const debouncedQuery = useDebounce(query, 400)

  useEffect(() => {
    if (debouncedQuery.length < 2) {
      setResults([])
      setError(null)
      return
    }

    let cancelled = false
    setSearching(true)
    setError(null)

    api.searchBrain(debouncedQuery)
      .then((data: any) => {
        if (cancelled) return
        if (data.error) {
          setError(data.error)
          setResults([])
        } else if (data.results) {
          // results can be a flat array OR a nested object { index: [], predictions: [], ... }
          let flat: SearchResult[] = []
          if (Array.isArray(data.results)) {
            flat = data.results
          } else if (typeof data.results === 'object') {
            for (const [category, items] of Object.entries(data.results)) {
              if (Array.isArray(items)) {
                flat.push(...(items as any[]).map((item: any) => ({
                  ...item,
                  source: item.source || category,
                })))
              }
            }
          }
          setResults(flat)
        } else if (data.raw) {
          setResults([{ text: data.raw, source: 'raw' }])
        } else {
          setResults([])
        }
      })
      .catch((e: Error) => {
        if (!cancelled) setError(e.message)
      })
      .finally(() => {
        if (!cancelled) setSearching(false)
      })

    return () => { cancelled = true }
  }, [debouncedQuery])

  return (
    <div className="mb-6">
      <div className="relative">
        <input
          type="text"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          placeholder="Search the brain... (min 2 characters)"
          className="w-full bg-slate-800/60 border border-slate-700/50 rounded-lg px-4 py-3 pl-10
            text-sm text-slate-200 placeholder-slate-500
            focus:outline-none focus:border-sky-500/50 focus:ring-1 focus:ring-sky-500/30
            transition-colors"
          aria-label="Search brain knowledge"
        />
        <svg className="absolute left-3 top-3.5 w-4 h-4 text-slate-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
        </svg>
        {searching && (
          <span className="absolute right-3 top-3.5 text-xs text-sky-400 animate-pulse">
            Searching...
          </span>
        )}
      </div>

      {error && (
        <p className="mt-2 text-xs text-rose-400">{error}</p>
      )}

      {results.length > 0 && (
        <div className="mt-3 space-y-2 max-h-64 overflow-y-auto">
          {results.map((r, i) => (
            <div key={i} className="bg-slate-800/40 border border-slate-700/30 rounded-lg p-3">
              <div className="flex items-center gap-2">
                {r.source && (
                  <span className="text-[10px] font-medium text-sky-400 uppercase tracking-wider">
                    {r.source}
                  </span>
                )}
                {r.relevance != null && (
                  <span className="text-[10px] text-emerald-400">{(r.relevance * 100).toFixed(0)}% rel</span>
                )}
                {r.salience != null && (
                  <span className="text-[10px] text-amber-400">{r.salience.toFixed(2)} sal</span>
                )}
              </div>
              {r.title && (
                <p className="text-xs text-slate-200 font-medium mt-1">{r.title}</p>
              )}
              <p className="text-xs text-slate-400 mt-1 leading-relaxed">
                {typeof r.text === 'string' ? r.text : JSON.stringify(r)}
              </p>
            </div>
          ))}
        </div>
      )}
    </div>
  )
}

// ─── Helpers: extract readable text from raw JSON strings ───
function extractReadableText(item: string): { text: string; meta?: string } {
  if (!item.startsWith('{')) return { text: item }
  try {
    const obj = JSON.parse(item)
    const text = obj.text || obj.description || obj.title || obj.want || obj.dont_want || obj.pattern || item
    const parts: string[] = []
    if (obj.source) parts.push(obj.source)
    if (obj.section) parts.push(obj.section)
    if (obj.status) parts.push(obj.status)
    return { text, meta: parts.length ? parts.join(' · ') : undefined }
  } catch {
    return { text: item }
  }
}

// ─── Item List (reusable for lessons/failures/patterns) ─────
function ItemList({ items, loading, error, emptyMsg, total, onLoadMore }: {
  items: string[] | null
  loading: boolean
  error: string | null
  emptyMsg: string
  total?: number
  onLoadMore?: () => void
}) {
  if (loading && !items) return <p className="text-sm text-slate-500 py-4">Loading...</p>
  if (error) return <p className="text-sm text-rose-400 py-4">{error}</p>
  if (!items || items.length === 0) {
    return <p className="text-sm text-slate-500 py-4">{emptyMsg}</p>
  }

  const hasMore = total != null && items.length < total

  return (
    <div>
      {total != null && (
        <p className="text-[10px] text-slate-500 mb-2">
          Showing {items.length.toLocaleString()} of {total.toLocaleString()}
        </p>
      )}
      <div className="space-y-2 max-h-[520px] overflow-y-auto pr-1">
        {items.map((item, i) => {
          const { text, meta } = extractReadableText(item)
          return (
            <div key={i} className="bg-slate-800/40 border border-slate-700/30 rounded-lg p-3">
              {meta && (
                <span className="text-[10px] font-medium text-sky-400/70 uppercase tracking-wider">
                  {meta}
                </span>
              )}
              <p className="text-xs text-slate-300 leading-relaxed">{text}</p>
            </div>
          )
        })}
        {hasMore && onLoadMore && (
          <button
            onClick={onLoadMore}
            disabled={loading}
            className="w-full py-2 text-xs text-sky-400 hover:text-sky-300 bg-slate-800/30
              border border-slate-700/30 rounded-lg transition-colors disabled:opacity-50"
          >
            {loading ? 'Loading...' : `Load more (${(total - items.length).toLocaleString()} remaining)`}
          </button>
        )}
      </div>
    </div>
  )
}

// ─── JSON Item List (for wants, anti-patterns, etc.) ─────────
function JsonItemList({ items, labelKey, loading, error, emptyMsg }: {
  items: any[] | null
  labelKey: string
  loading: boolean
  error: string | null
  emptyMsg: string
}) {
  if (loading) return <p className="text-sm text-slate-500 py-4">Loading...</p>
  if (error) return <p className="text-sm text-rose-400 py-4">{error}</p>
  if (!items || items.length === 0) {
    return <p className="text-sm text-slate-500 py-4">{emptyMsg}</p>
  }

  return (
    <div className="space-y-2 max-h-[520px] overflow-y-auto pr-1">
      {items.map((item, i) => {
        const label = typeof item === 'string'
          ? extractReadableText(item).text
          : (item[labelKey] || item.text || item.description || item.title || item.pattern || item.want || item.dont_want || JSON.stringify(item).slice(0, 120))
        const meta = typeof item === 'object'
          ? [item.source, item.section, item.status].filter(Boolean).join(' · ')
          : undefined
        const reason = typeof item === 'object' ? item.reason : null
        return (
          <div key={i} className="bg-slate-800/40 border border-slate-700/30 rounded-lg p-3">
            {meta && (
              <span className="text-[10px] font-medium text-sky-400/70 uppercase tracking-wider">
                {meta}
              </span>
            )}
            <p className="text-xs text-slate-300 leading-relaxed">{label}</p>
            {reason && <p className="text-[10px] text-slate-500 mt-1">{reason}</p>}
          </div>
        )
      })}
    </div>
  )
}

// ─── Utility ─────────────────────────────────────────────────
function truncate(s: string, max: number): string {
  return s.length > max ? s.slice(0, max - 1) + '…' : s
}

// ─── Load-more hook for paginated markdown endpoints ────────
function usePaginatedBrain(
  fetchFn: (offset: number, limit: number) => Promise<any>,
  itemKey: string,
  pageSize = 200,
) {
  const [items, setItems] = useState<string[]>([])
  const [total, setTotal] = useState(0)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    setLoading(true)
    fetchFn(0, pageSize)
      .then((data: any) => {
        setItems(data[itemKey] || [])
        setTotal(data.count || 0)
        setError(null)
      })
      .catch((e: Error) => setError(e.message))
      .finally(() => setLoading(false))
  }, [fetchFn, itemKey, pageSize])

  const loadMore = useCallback(() => {
    setLoading(true)
    fetchFn(items.length, pageSize)
      .then((data: any) => {
        setItems(prev => [...prev, ...(data[itemKey] || [])])
        setTotal(data.count || 0)
      })
      .catch((e: Error) => setError(e.message))
      .finally(() => setLoading(false))
  }, [fetchFn, itemKey, pageSize, items.length])

  return { items, total, loading, error, loadMore }
}

// ─── Main Brain Page ─────────────────────────────────────────
export default function Brain() {
  const [activeTab, setActiveTab] = useState<BrainTab>('graph')

  const { data: graphData, loading: graphLoading, error: graphError } = useKnowledgeGraph()

  const fetchLessons = useCallback((o: number, l: number) => api.getLessons(o, l), [])
  const fetchFailures = useCallback((o: number, l: number) => api.getFailures(o, l), [])
  const fetchPatterns = useCallback((o: number, l: number) => api.getPatterns(o, l), [])

  const lessons = usePaginatedBrain(fetchLessons, 'lessons')
  const failures = usePaginatedBrain(fetchFailures, 'failures')
  const patterns = usePaginatedBrain(fetchPatterns, 'patterns')

  const { data: wantsData, loading: wantsLoading, error: wantsError } = useWants()
  const { data: dontWantsData, loading: dontWantsLoading, error: dontWantsError } = useDontWants()
  const { data: schemasData, loading: schemasLoading, error: schemasError } = useSchemas()
  const { data: proceduresData, loading: proceduresLoading, error: proceduresError } = useProcedures()
  const { data: intentsData, loading: intentsLoading, error: intentsError } = useStrategicIntents()
  const { data: antiPatternsData, loading: antiPatternsLoading, error: antiPatternsError } = useAntiPatterns()

  const renderTabContent = useCallback(() => {
    switch (activeTab) {
      case 'graph':
        return (
          <div>
            {graphLoading && !graphData && (
              <p className="text-sm text-slate-500 py-4">Loading knowledge graph...</p>
            )}
            {graphError && (
              <p className="text-sm text-rose-400 py-4">{graphError}</p>
            )}
            <KnowledgeGraphViz graphData={graphData} />
          </div>
        )
      case '3d':
        return (
          <Suspense fallback={<p className="text-sm text-slate-500 py-4 animate-pulse">Loading 3D brain...</p>}>
            <BrainGraph3D graphData={graphData} />
          </Suspense>
        )
      case 'lessons':
        return (
          <ItemList
            items={lessons.items.length ? lessons.items : null}
            loading={lessons.loading}
            error={lessons.error}
            emptyMsg="No lessons captured yet."
            total={lessons.total}
            onLoadMore={lessons.loadMore}
          />
        )
      case 'failures':
        return (
          <ItemList
            items={failures.items.length ? failures.items : null}
            loading={failures.loading}
            error={failures.error}
            emptyMsg="No failures logged yet."
            total={failures.total}
            onLoadMore={failures.loadMore}
          />
        )
      case 'patterns':
        return (
          <ItemList
            items={patterns.items.length ? patterns.items : null}
            loading={patterns.loading}
            error={patterns.error}
            emptyMsg="No patterns detected yet."
            total={patterns.total}
            onLoadMore={patterns.loadMore}
          />
        )
      case 'schemas':
        return (
          <JsonItemList
            items={schemasData?.schemas ?? null}
            labelKey="title"
            loading={schemasLoading}
            error={schemasError}
            emptyMsg="No schemas extracted yet."
          />
        )
      case 'procedures':
        return (
          <JsonItemList
            items={proceduresData?.procedures ?? null}
            labelKey="title"
            loading={proceduresLoading}
            error={proceduresError}
            emptyMsg="No procedures extracted yet."
          />
        )
      case 'wants':
        return (
          <JsonItemList
            items={wantsData?.wants ?? null}
            labelKey="want"
            loading={wantsLoading}
            error={wantsError}
            emptyMsg="No wants captured yet."
          />
        )
      case 'dont_wants':
        return (
          <JsonItemList
            items={dontWantsData?.dont_wants ?? null}
            labelKey="dont_want"
            loading={dontWantsLoading}
            error={dontWantsError}
            emptyMsg="No don't wants captured yet."
          />
        )
      case 'strategic_intents':
        return (
          <JsonItemList
            items={intentsData?.strategic_intents ?? null}
            labelKey="title"
            loading={intentsLoading}
            error={intentsError}
            emptyMsg="No strategic intents synthesized yet."
          />
        )
      case 'anti_patterns':
        return (
          <JsonItemList
            items={antiPatternsData?.anti_patterns ?? null}
            labelKey="description"
            loading={antiPatternsLoading}
            error={antiPatternsError}
            emptyMsg="No anti-patterns detected yet."
          />
        )
    }
  }, [activeTab, graphData, graphLoading, graphError,
      lessons.items, lessons.loading, lessons.error, lessons.total, lessons.loadMore,
      failures.items, failures.loading, failures.error, failures.total, failures.loadMore,
      patterns.items, patterns.loading, patterns.error, patterns.total, patterns.loadMore,
      schemasData, schemasLoading, schemasError, proceduresData, proceduresLoading, proceduresError,
      wantsData, wantsLoading, wantsError, dontWantsData, dontWantsLoading, dontWantsError,
      intentsData, intentsLoading, intentsError, antiPatternsData, antiPatternsLoading, antiPatternsError])

  return (
    <div className="min-h-screen bg-slate-950 p-6">
      <div className="max-w-7xl mx-auto">
        {/* Header */}
        <div className="flex items-center justify-between mb-6">
          <div>
            <h1 className="text-3xl font-bold text-sky-400 tracking-tight">Neural Knowledge</h1>
            <p className="text-sm text-slate-500 mt-1">
              Explore the brain's knowledge graph, lessons, failures, and patterns
            </p>
          </div>
          <div className="flex items-center gap-2">
            <span className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse" />
            <span className="text-xs text-slate-400">Live</span>
          </div>
        </div>

        {/* Search */}
        <BrainSearch />

        {/* Tabs */}
        <div className="flex gap-1 mb-4 overflow-x-auto pb-1">
          {TABS.map((tab) => (
            <button
              key={tab.key}
              onClick={() => setActiveTab(tab.key)}
              className={`flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium
                transition-colors whitespace-nowrap
                ${activeTab === tab.key
                  ? 'bg-sky-500/20 text-sky-400 border border-sky-500/30'
                  : 'text-slate-400 hover:text-slate-300 hover:bg-slate-800/40 border border-transparent'
                }`}
              aria-label={tab.label}
            >
              <span>{tab.icon}</span>
              <span>{tab.label}</span>
              {tab.key === 'lessons' && lessons.total > 0 && (
                <span className="text-[10px] bg-slate-700/50 px-1.5 py-0.5 rounded-full">
                  {lessons.total.toLocaleString()}
                </span>
              )}
              {tab.key === 'failures' && failures.total > 0 && (
                <span className="text-[10px] bg-slate-700/50 px-1.5 py-0.5 rounded-full">
                  {failures.total.toLocaleString()}
                </span>
              )}
              {tab.key === 'patterns' && patterns.total > 0 && (
                <span className="text-[10px] bg-slate-700/50 px-1.5 py-0.5 rounded-full">
                  {patterns.total.toLocaleString()}
                </span>
              )}
              {tab.key === 'schemas' && schemasData && (
                <span className="text-[10px] bg-slate-700/50 px-1.5 py-0.5 rounded-full">
                  {schemasData.count}
                </span>
              )}
              {tab.key === 'procedures' && proceduresData && (
                <span className="text-[10px] bg-slate-700/50 px-1.5 py-0.5 rounded-full">
                  {proceduresData.count}
                </span>
              )}
              {tab.key === 'wants' && wantsData && (
                <span className="text-[10px] bg-slate-700/50 px-1.5 py-0.5 rounded-full">
                  {wantsData.count}
                </span>
              )}
              {tab.key === 'dont_wants' && dontWantsData && (
                <span className="text-[10px] bg-slate-700/50 px-1.5 py-0.5 rounded-full">
                  {dontWantsData.count}
                </span>
              )}
              {tab.key === 'strategic_intents' && intentsData && (
                <span className="text-[10px] bg-slate-700/50 px-1.5 py-0.5 rounded-full">
                  {intentsData.count}
                </span>
              )}
              {tab.key === 'anti_patterns' && antiPatternsData && (
                <span className="text-[10px] bg-slate-700/50 px-1.5 py-0.5 rounded-full">
                  {antiPatternsData.count}
                </span>
              )}
              {tab.key === 'graph' && graphData && (
                <span className="text-[10px] bg-slate-700/50 px-1.5 py-0.5 rounded-full">
                  {graphData.nodes}
                </span>
              )}
            </button>
          ))}
        </div>

        {/* Tab Content */}
        <div className="glass-card p-6">
          {renderTabContent()}
        </div>
      </div>
    </div>
  )
}
