import { useEffect, useState, useCallback } from 'react'
import { useParams } from 'react-router-dom'
import { apiFetch } from '@core/lib/api'
import { useAppPath } from '@core/hooks/useAppPath'
import { Card, CardContent, CardHeader, CardTitle } from '@core/components/ui/card'
import { Button } from '@core/components/ui/button'
import { Badge } from '@core/components/ui/badge'
import { Skeleton } from '@core/components/ui/skeleton'
import { Progress } from '@core/components/ui/progress'
import {
  CheckCircle2,
  XCircle,
  AlertTriangle,
  Clock,
  ChevronRight,
  RefreshCw,
  FileCode2,
  Layers,
  Zap,
  Sparkles,
  GitGraph,
  Hash,
  DollarSign,
  Bot,
  Search,
  Play,
  Settings2,
} from 'lucide-react'

// ─── TYPES ────────────────────────────────────────────────────────────────────

interface ProjectStats {
  file_count: number
  chunk_count: number
  proposal_count: number
  approved_count: number
  pending_review_count: number
  total_ingestion_cost_usd: number
  last_ingested_at: string | null
}

interface EmbedStatus {
  total_chunks: number
  embedded_chunks: number
  coverage_pct: number
  unembedded_chunks: number
}

interface DocStatus {
  total_chunks: number
  documented_count: number
  undocumented_count: number
  ai_generated_count: number
  human_verified_count: number
  coverage_pct: number
}

interface CallmapStatus {
  import_links: number
  call_links: number
  export_links: number
  total_links: number
  tested_by_links?: number
}

interface ConfigStatus {
  config_items: number
  configures_links: number
}

interface DashboardData {
  project: { id: string; title: string; data: ProjectStats } | null
  embed: EmbedStatus | null
  doc: DocStatus | null
  callmap: CallmapStatus | null
  config: ConfigStatus | null
}

// ─── PIPELINE PASS STATUS CARD ────────────────────────────────────────────────

function PassCard({
  number,
  label,
  icon: Icon,
  description,
  status,
  metric,
  href,
}: {
  number: string
  label: string
  icon: React.ElementType
  description: string
  status: 'complete' | 'partial' | 'empty' | 'unknown'
  metric: string
  href?: string
}) {
  const statusConfig = {
    complete: { color: 'text-green-600', bg: 'bg-green-50 border-green-200', dot: 'bg-green-500', icon: CheckCircle2 },
    partial:  { color: 'text-amber-600', bg: 'bg-amber-50 border-amber-200',  dot: 'bg-amber-500',  icon: AlertTriangle },
    empty:    { color: 'text-slate-400', bg: 'bg-slate-50 border-slate-200',  dot: 'bg-slate-300',  icon: Clock },
    unknown:  { color: 'text-slate-400', bg: 'bg-slate-50 border-slate-200',  dot: 'bg-slate-300',  icon: Clock },
  }[status]

  const StatusIcon = statusConfig.icon

  return (
    <div className={`rounded-lg border p-3 ${statusConfig.bg} flex items-start gap-3`}>
      <div className={`mt-0.5 h-7 w-7 rounded-md flex items-center justify-center shrink-0 ${status === 'complete' ? 'bg-green-100' : status === 'partial' ? 'bg-amber-100' : 'bg-slate-100'}`}>
        <Icon className={`h-4 w-4 ${statusConfig.color}`} />
      </div>
      <div className="flex-1 min-w-0">
        <div className="flex items-center gap-1.5">
          <span className="text-xs font-bold text-muted-foreground">Pass {number}</span>
          <StatusIcon className={`h-3 w-3 ${statusConfig.color}`} />
        </div>
        <div className="text-sm font-medium truncate">{label}</div>
        <div className="text-xs text-muted-foreground">{description}</div>
        <div className={`text-xs font-mono mt-1 font-semibold ${statusConfig.color}`}>{metric}</div>
      </div>
      {href && (
        <a href={href} className="shrink-0 text-xs text-muted-foreground hover:text-foreground">
          <ChevronRight className="h-4 w-4" />
        </a>
      )}
    </div>
  )
}

// ─── STAT TILE ────────────────────────────────────────────────────────────────

function StatTile({
  label,
  value,
  sub,
  icon: Icon,
  accent = false,
}: {
  label: string
  value: string | number
  sub?: string
  icon: React.ElementType
  accent?: boolean
}) {
  return (
    <Card className={accent ? 'border-indigo-200 bg-indigo-50/50' : ''}>
      <CardContent className="pt-4 pb-3">
        <div className="flex items-start justify-between">
          <div>
            <div className={`text-2xl font-bold tabular-nums ${accent ? 'text-indigo-700' : ''}`}>{value}</div>
            <div className="text-xs text-muted-foreground mt-0.5">{label}</div>
            {sub && <div className="text-xs text-muted-foreground mt-0.5">{sub}</div>}
          </div>
          <Icon className={`h-5 w-5 mt-1 ${accent ? 'text-indigo-400' : 'text-muted-foreground/50'}`} />
        </div>
      </CardContent>
    </Card>
  )
}

// ─── COVERAGE BAR ─────────────────────────────────────────────────────────────

function CoverageBar({ label, pct, color = 'bg-indigo-500' }: { label: string; pct: number; color?: string }) {
  return (
    <div className="space-y-1">
      <div className="flex items-center justify-between text-xs">
        <span className="text-muted-foreground">{label}</span>
        <span className="font-mono font-semibold">{pct}%</span>
      </div>
      <Progress value={pct} className="h-2" />
    </div>
  )
}

// ─── DRIFT ALERT CARD ─────────────────────────────────────────────────────────

function DriftAlertCard({ projectId, appPath }: { projectId: string; appPath: (p: string) => string }) {
  const [driftChunks, setDriftChunks] = useState<any[] | null>(null)
  const [checking, setChecking] = useState(false)

  const checkDrift = async () => {
    setChecking(true)
    try {
      // Get all chunks with stored hashes for this project
      const res = await apiFetch(`/api/admin-data?action=list&entity=items&type_slug=cil_chunk&limit=200`)
      const data = await res.json()
      const chunks = (data?.data || data || []).filter(
        (c: any) => c.data?.project_id === projectId && c.data?.stored_hash
      )

      if (!chunks.length) { setDriftChunks([]); return }

      // Batch validate — send all at once
      const validateRes = await apiFetch('/api/custom_cil-validate?action=validate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          chunks: chunks.slice(0, 50).map((c: any) => ({
            chunk_id: c.id,
            chunk_name: c.data?.chunk_name || '',
            content: c.data?.code_content || '',
          })),
        }),
      })
      const vData = await validateRes.json()
      const results = vData?.results || vData?.data?.results || []
      setDriftChunks(results.filter((r: any) => r.status === 'drift_detected'))
    } finally {
      setChecking(false)
    }
  }

  return (
    <Card>
      <CardHeader className="pb-2">
        <div className="flex items-center justify-between">
          <CardTitle className="text-sm flex items-center gap-1.5">
            <Hash className="h-4 w-4" /> Hash Drift
          </CardTitle>
          <Button size="sm" variant="outline" onClick={checkDrift} disabled={checking} className="h-7 text-xs">
            {checking ? <RefreshCw className="h-3 w-3 animate-spin" /> : <Hash className="h-3 w-3" />}
            {checking ? 'Checking…' : 'Check Now'}
          </Button>
        </div>
      </CardHeader>
      <CardContent>
        {driftChunks === null && (
          <p className="text-xs text-muted-foreground">Click "Check Now" to validate all stored hashes against current code_content.</p>
        )}
        {driftChunks?.length === 0 && (
          <div className="flex items-center gap-1.5 text-sm text-green-600">
            <CheckCircle2 className="h-4 w-4" /> All hashes current
          </div>
        )}
        {driftChunks && driftChunks.length > 0 && (
          <div className="space-y-1.5">
            <div className="flex items-center gap-1.5 text-sm text-red-600 mb-2">
              <XCircle className="h-4 w-4" /> {driftChunks.length} chunk{driftChunks.length !== 1 ? 's' : ''} with drift
            </div>
            {driftChunks.slice(0, 5).map((r: any) => (
              <a
                key={r.chunk_id}
                href={appPath(`/cil/${projectId}/chunks/${r.chunk_id}`)}
                className="flex items-center gap-2 text-xs hover:bg-red-50 rounded p-1 group"
              >
                <XCircle className="h-3 w-3 text-red-500 shrink-0" />
                <span className="font-mono truncate">{r.chunk_name}</span>
                <ChevronRight className="h-3 w-3 text-muted-foreground opacity-0 group-hover:opacity-100 ml-auto" />
              </a>
            ))}
            {driftChunks.length > 5 && (
              <p className="text-xs text-muted-foreground">…and {driftChunks.length - 5} more</p>
            )}
          </div>
        )}
      </CardContent>
    </Card>
  )
}

// ─── MAIN PAGE ────────────────────────────────────────────────────────────────

export default function CILDashboardPage() {
  const { id: projectId } = useParams<{ id: string }>()
  const appPath = useAppPath()
  const [data, setData] = useState<DashboardData>({ project: null, embed: null, doc: null, callmap: null, config: null })
  const [loading, setLoading] = useState(true)

  const load = useCallback(async () => {
    if (!projectId) return
    setLoading(true)
    try {
      const [projectRes, embedRes, docRes, callmapRes, configRes] = await Promise.allSettled([
        apiFetch(`/api/custom_cil-project?action=get&id=${projectId}`).then(r => r.json()),
        apiFetch(`/api/custom_cil-embeddings?action=status&project_id=${projectId}`).then(r => r.json()),
        apiFetch(`/api/custom_cil-doc?action=gap_report&project_id=${projectId}`).then(r => r.json()),
        apiFetch(`/api/custom_cil-callmap?action=status&project_id=${projectId}`).then(r => r.json()),
        apiFetch(`/api/custom_cil-config?action=status&project_id=${projectId}`).then(r => r.json()),
      ])

      setData({
        project: projectRes.status === 'fulfilled' ? (projectRes.value?.project || projectRes.value?.data?.project) : null,
        embed:   embedRes.status === 'fulfilled'   ? (embedRes.value?.data   || embedRes.value)   : null,
        doc:     docRes.status === 'fulfilled'     ? (docRes.value?.data     || docRes.value)     : null,
        callmap: callmapRes.status === 'fulfilled' ? (callmapRes.value?.data || callmapRes.value) : null,
        config:  configRes.status === 'fulfilled'  ? (configRes.value?.data  || configRes.value)  : null,
      })
    } finally {
      setLoading(false)
    }
  }, [projectId])

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

  if (loading) {
    return (
      <div className="p-6 space-y-4">
        <Skeleton className="h-6 w-48" />
        <div className="grid grid-cols-4 gap-4">{Array.from({ length: 4 }).map((_, i) => <Skeleton key={i} className="h-24" />)}</div>
        <div className="grid grid-cols-2 gap-4">{Array.from({ length: 4 }).map((_, i) => <Skeleton key={i} className="h-32" />)}</div>
      </div>
    )
  }

  const project = data.project
  const stats: ProjectStats = project?.data || { file_count: 0, chunk_count: 0, proposal_count: 0, approved_count: 0, pending_review_count: 0, total_ingestion_cost_usd: 0, last_ingested_at: null }
  const embed   = data.embed   || { total_chunks: 0, embedded_chunks: 0, coverage_pct: 0, unembedded_chunks: 0 }
  const doc     = data.doc     || { total_chunks: 0, documented_count: 0, undocumented_count: 0, ai_generated_count: 0, human_verified_count: 0, coverage_pct: 0 }
  const callmap = data.callmap || { import_links: 0, call_links: 0, export_links: 0, total_links: 0, tested_by_links: 0 }
  const config  = data.config  || { config_items: 0, configures_links: 0 }

  const lastIngested = stats.last_ingested_at
    ? new Date(stats.last_ingested_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })
    : 'Never'

  // Determine pipeline pass status
  const pass1Status = stats.file_count > 0 ? 'complete' : 'empty'
  const pass2Status = stats.chunk_count > 0 ? 'complete' : (stats.file_count > 0 ? 'partial' : 'empty')
  const pass3Status = embed.coverage_pct === 100 ? 'complete' : (embed.embedded_chunks > 0 ? 'partial' : 'empty') as any
  const pass4Status = doc.coverage_pct === 100 ? 'complete' : (doc.documented_count > 0 ? 'partial' : 'empty') as any
  const pass4bStatus = callmap.total_links > 0 ? 'complete' : 'empty' as any
  const pass5Status = config.config_items > 0 ? (config.configures_links > 0 ? 'complete' : 'partial') : 'empty' as any

  return (
    <div className="p-6 space-y-6 max-w-5xl">
      {/* Breadcrumb */}
      <div className="flex items-center gap-2 text-sm text-muted-foreground">
        <a href={appPath('/cil')} className="hover:underline">Code Intelligence</a>
        <ChevronRight className="h-3 w-3" />
        <span>{project?.title || 'Project'}</span>
        <ChevronRight className="h-3 w-3" />
        <span>Dashboard</span>
      </div>

      {/* Header */}
      <div className="flex items-start justify-between flex-wrap gap-4">
        <div>
          <h1 className="text-2xl font-bold">{project?.title || 'Project Dashboard'}</h1>
          <p className="text-xs text-muted-foreground font-mono mt-0.5">Last ingested: {lastIngested}</p>
        </div>
        <div className="flex items-center gap-2">
          <Button size="sm" variant="outline" onClick={load} className="h-8 text-xs">
            <RefreshCw className="h-3 w-3 mr-1" /> Refresh
          </Button>
          <Button size="sm" asChild className="h-8 text-xs">
            <a href={appPath(`/cil/${projectId}/ingest`)}>
              <Play className="h-3 w-3 mr-1" /> Run Pipeline
            </a>
          </Button>
        </div>
      </div>

      {/* Top stats */}
      <div className="grid grid-cols-2 sm:grid-cols-4 gap-4">
        <StatTile label="Files" value={stats.file_count.toLocaleString()} icon={FileCode2} />
        <StatTile label="Chunks" value={stats.chunk_count.toLocaleString()} icon={Layers} accent />
        <StatTile
          label="Pending Review"
          value={stats.pending_review_count}
          icon={AlertTriangle}
        />
        <StatTile
          label="LLM Cost"
          value={`$${(stats.total_ingestion_cost_usd ?? 0).toFixed(4)}`}
          sub="cumulative"
          icon={DollarSign}
        />
      </div>

      {/* Coverage bars */}
      <Card>
        <CardHeader className="pb-2">
          <CardTitle className="text-sm">Coverage</CardTitle>
        </CardHeader>
        <CardContent className="space-y-3">
          <CoverageBar label={`Embeddings — ${embed.embedded_chunks} / ${embed.total_chunks} chunks`} pct={embed.coverage_pct} color="bg-indigo-500" />
          <CoverageBar label={`Documentation — ${doc.documented_count} / ${doc.total_chunks} chunks`} pct={doc.coverage_pct} color="bg-emerald-500" />
          <div className="pt-1 grid grid-cols-3 gap-3 text-xs text-center text-muted-foreground">
            <div>
              <div className="font-semibold text-blue-600">{doc.ai_generated_count}</div>
              <div>AI Generated</div>
            </div>
            <div>
              <div className="font-semibold text-green-600">{doc.human_verified_count}</div>
              <div>Human Verified</div>
            </div>
            <div>
              <div className="font-semibold text-slate-500">{doc.undocumented_count}</div>
              <div>Undocumented</div>
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Pipeline passes */}
      <div>
        <h2 className="text-sm font-medium text-muted-foreground uppercase tracking-wide mb-3">Pipeline Status</h2>
        <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
          <PassCard
            number="1" label="Discover Files" icon={FileCode2}
            description="Walk repo, register cil_file items, compute hashes"
            status={pass1Status}
            metric={`${stats.file_count.toLocaleString()} files registered`}
            href={appPath(`/cil/${projectId}/ingest`)}
          />
          <PassCard
            number="2" label="AST Chunk" icon={Layers}
            description="Parse files, propose chunk boundaries, write markers"
            status={pass2Status}
            metric={`${stats.chunk_count.toLocaleString()} chunks · ${stats.pending_review_count} pending`}
            href={appPath(`/cil/${projectId}/ingest`)}
          />
          <PassCard
            number="3" label="Embed Chunks" icon={Zap}
            description="Semantic + structural + contract vector embeddings"
            status={pass3Status}
            metric={`${embed.coverage_pct}% coverage · ${embed.embedded_chunks} / ${embed.total_chunks}`}
            href={appPath(`/cil/${projectId}/ingest`)}
          />
          <PassCard
            number="4" label="AI Document" icon={Sparkles}
            description="LLM-generated macro / micro / contract fields"
            status={pass4Status}
            metric={`${doc.coverage_pct}% coverage · $${(stats.total_ingestion_cost_usd ?? 0).toFixed(4)} spent`}
            href={appPath(`/cil/${projectId}/ingest`)}
          />
          <PassCard
            number="4b" label="Call Map" icon={GitGraph}
            description="Import + call edges between files and chunks"
            status={pass4bStatus}
            metric={`${callmap.call_links.toLocaleString()} calls · ${callmap.import_links.toLocaleString()} imports`}
            href={appPath(`/cil/${projectId}/graph`)}
          />
          <PassCard
            number="5" label="Config Extract" icon={Settings2}
            description="Config field contracts + cil_configures links"
            status={pass5Status}
            metric={`${config.config_items.toLocaleString()} config items · ${config.configures_links.toLocaleString()} links`}
            href={appPath(`/cil/${projectId}/ingest`)}
          />
        </div>
      </div>

      {/* Link counts + drift check */}
      <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
        {/* Graph stats */}
        <Card>
          <CardHeader className="pb-2">
            <CardTitle className="text-sm flex items-center gap-1.5">
              <GitGraph className="h-4 w-4" /> Graph Links
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-2">
            {[
              { label: 'Import links (file→file)', value: callmap.import_links },
              { label: 'Call links (chunk→chunk)', value: callmap.call_links },
              { label: 'Export links', value: callmap.export_links },
              { label: 'Tested-by links', value: callmap.tested_by_links ?? 0 },
            ].map(item => (
              <div key={item.label} className="flex justify-between text-sm">
                <span className="text-muted-foreground">{item.label}</span>
                <span className="font-mono font-medium">{item.value.toLocaleString()}</span>
              </div>
            ))}
            <div className="pt-2 flex gap-2">
              <Button size="sm" variant="outline" className="flex-1 h-7 text-xs" asChild>
                <a href={appPath(`/cil/${projectId}/graph`)}>
                  <GitGraph className="h-3 w-3 mr-1" /> View Graph
                </a>
              </Button>
            </div>
          </CardContent>
        </Card>

        {/* Drift check */}
        <DriftAlertCard projectId={projectId!} appPath={appPath} />
      </div>

      {/* Quick actions */}
      <div>
        <h2 className="text-sm font-medium text-muted-foreground uppercase tracking-wide mb-3">Quick Actions</h2>
        <div className="flex flex-wrap gap-2">
          <Button size="sm" variant="outline" asChild>
            <a href={appPath(`/cil/search`)}>
              <Search className="h-3.5 w-3.5 mr-1.5" /> Search Chunks
            </a>
          </Button>
          <Button size="sm" variant="outline" asChild>
            <a href={appPath(`/cil/${projectId}/agent`)}>
              <Bot className="h-3.5 w-3.5 mr-1.5" /> Ask CIL Agent
            </a>
          </Button>
          <Button size="sm" variant="outline" asChild>
            <a href={appPath(`/cil/${projectId}/files`)}>
              <Layers className="h-3.5 w-3.5 mr-1.5" /> Browse Files
            </a>
          </Button>
          <Button size="sm" variant="outline" asChild>
            <a href={appPath(`/cil/${projectId}/ingest`)}>
              <Play className="h-3.5 w-3.5 mr-1.5" /> Run Ingestion
            </a>
          </Button>
        </div>
      </div>
    </div>
  )
}
