import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { useReports } from '@/contexts/ReportsContext'
import { useLocale } from '@/contexts/LocaleContext'
import { listReports } from '@/api/reports'
import type { ReportSummary } from '@/api/types'
import Card from '@/components/ui/Card'
import Badge from '@/components/ui/Badge'
import Skeleton from '@/components/ui/Skeleton'
import KpiCard from '@/components/ui/KpiCard'
import ScoreChip from '@/components/ui/ScoreChip'
import ScoreBadge from '@/components/ui/ScoreBadge'
import PathBar from '@/components/ui/PathBar'
import EvalRunCard from '@/components/ui/EvalRunCard'
import ModelGroupHeader from '@/components/ui/ModelGroupHeader'
import EmptyState from '@/components/common/EmptyState'
import {
  FileText,
  Cpu,
  Database,
  Clock,
  Inbox,
  FolderOpen,
} from 'lucide-react'
import { cn } from '@/lib/utils'

// ------------------------------------------------------------------ //
// Helpers                                                              //
// ------------------------------------------------------------------ //

/** Format timestamp to YYYY-MM-DD HH:MM:SS */
function formatTimestamp(ts: string): string {
  return ts.replace('T', ' ').slice(0, 19)
}

/** Format timestamp to short form MM-DD HH:MM */
function formatTimestampShort(ts: string): string {
  return ts.replace('T', ' ').slice(5, 16)
}

// ------------------------------------------------------------------ //
// CompactRunRow (Grouped view)                                         //
// ------------------------------------------------------------------ //
interface CompactRunRowProps {
  report: ReportSummary
  onClick: () => void
}

function CompactRunRow({ report, onClick }: CompactRunRowProps) {
  const dsScores = report.dataset_scores

  return (
    <button
      onClick={onClick}
      className="flex items-center gap-3 py-2.5 px-3 rounded-[var(--radius-sm)] hover:bg-[var(--bg-card2)] transition-colors w-full text-left"
    >
      {report.timestamp && (
        <span className="type-caption-mono text-[var(--text-muted)] shrink-0 w-[110px]">
          {formatTimestampShort(report.timestamp)}
        </span>
      )}
      <div className="flex flex-wrap gap-1 flex-1 min-w-0">
        {dsScores && Object.keys(dsScores).length > 0 ? (
          Object.entries(dsScores).map(([ds, s]) => <ScoreChip key={ds} label={ds} score={s} />)
        ) : (
          <span className="type-caption-mono text-[var(--text-muted)]">{report.dataset_name}</span>
        )}
      </div>
      <ScoreBadge score={report.score} className="shrink-0 !text-xs !px-2" />
    </button>
  )
}

// ------------------------------------------------------------------ //
// View toggle (segmented control)                                      //
// ------------------------------------------------------------------ //
type DashboardView = 'timeline' | 'grouped' | 'byDataset'

interface ViewToggleProps {
  value: DashboardView
  onChange: (v: DashboardView) => void
  labels: Record<DashboardView, string>
}

function ViewToggle({ value, onChange, labels }: ViewToggleProps) {
  const items: DashboardView[] = ['timeline', 'grouped', 'byDataset']
  return (
    <div className="inline-flex rounded-[var(--radius-sm)] border border-[var(--border-md)] overflow-hidden">
      {items.map((key) => (
        <button
          key={key}
          onClick={() => onChange(key)}
          className={cn(
            'px-3.5 py-1.5 type-button-sm transition-colors cursor-pointer',
            value === key
              ? 'bg-[var(--accent)] text-[var(--text-on-filled)]'
              : 'bg-[var(--bg-card2)] text-[var(--text-muted)] hover:text-[var(--text)]',
          )}
        >
          {labels[key]}
        </button>
      ))}
    </div>
  )
}

// ------------------------------------------------------------------ //
// KPI Skeleton                                                        //
// ------------------------------------------------------------------ //
function KpiSkeleton() {
  return (
    <div className="grid grid-cols-2 lg:grid-cols-4 gap-3">
      {Array.from({ length: 4 }).map((_, i) => (
        <div
          key={i}
          className="rounded-[var(--radius)] border border-[var(--border)] bg-[var(--bg-card)] p-5"
        >
          <Skeleton width={40} height={40} className="mb-3" />
          <Skeleton width={60} height={28} className="mb-1" />
          <Skeleton width={100} height={14} />
        </div>
      ))}
    </div>
  )
}

// ------------------------------------------------------------------ //
// Dashboard Page                                                      //
// ------------------------------------------------------------------ //
export default function DashboardPage() {
  const { t } = useLocale()
  const { rootPath, setRootPath } = useReports()
  const navigate = useNavigate()

  const [pathInput, setPathInput] = useState(rootPath || './outputs')
  const [scanning, setScanning] = useState(false)
  const [reports, setReports] = useState<ReportSummary[]>([])
  const [scanned, setScanned] = useState(false)

  // Evaluation list state
  const [view, setView] = useState<DashboardView>('timeline')
  const evalListRef = useRef<HTMLDivElement>(null)
  const [search, setSearch] = useState('')
  const [sortBy, setSortBy] = useState('time')
  const [expandedGroups, setExpandedGroups] = useState<Set<string>>(new Set())

  // Scan for reports using listReports API
  const handleScan = useCallback(async () => {
    const trimmed = pathInput.trim()
    if (!trimmed) return
    setRootPath(trimmed)
    setScanning(true)
    try {
      const res = await listReports({ rootPath: trimmed, pageSize: 1000, sortBy: 'time', sortOrder: 'desc' })
      setReports(res.reports)
      setScanned(true)
    } catch {
      setReports([])
      setScanned(true)
    } finally {
      setScanning(false)
    }
  }, [pathInput, setRootPath])

  // Auto-scan if rootPath is already set on mount
  useEffect(() => {
    if (rootPath && !scanned) {
      setPathInput(rootPath)
      handleScan()
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  // KPI stats
  const kpiStats = useMemo(() => {
    const totalEvals = reports.length
    const models = new Set(reports.map((r) => r.model_name))
    const datasets = new Set(reports.map((r) => r.dataset_name))
    const latest = reports.length > 0
      ? formatTimestamp(reports[0].timestamp || reports[0].name)
      : t('dashboard.neverText')
    return { totalEvals, models: models.size, datasets: datasets.size, latest }
  }, [reports, t])

  // Filtered & sorted reports
  const sortedReports = useMemo(() => {
    let filtered = reports
    if (search) {
      const q = search.toLowerCase()
      filtered = reports.filter(r =>
        r.model_name.toLowerCase().includes(q) ||
        r.dataset_name.toLowerCase().includes(q)
      )
    }
    return [...filtered].sort((a, b) => {
      if (sortBy === 'time') return (b.timestamp || '').localeCompare(a.timestamp || '')
      if (sortBy === 'score') return (b.score ?? 0) - (a.score ?? 0)
      if (sortBy === 'model') return a.model_name.localeCompare(b.model_name)
      return 0
    })
  }, [reports, search, sortBy])

  // Grouped by model
  const grouped = useMemo(() => {
    const map = new Map<string, ReportSummary[]>()
    for (const r of sortedReports) {
      const list = map.get(r.model_name) || []
      list.push(r)
      map.set(r.model_name, list)
    }
    return Array.from(map.entries())
  }, [sortedReports])

  // Grouped by dataset
  const groupedByDataset = useMemo(() => {
    const map = new Map<string, ReportSummary[]>()
    for (const r of sortedReports) {
      const list = map.get(r.dataset_name) || []
      list.push(r)
      map.set(r.dataset_name, list)
    }
    return Array.from(map.entries())
  }, [sortedReports])

  const toggleGroup = (model: string) => {
    setExpandedGroups(prev => {
      const next = new Set(prev)
      if (next.has(model)) next.delete(model)
      else next.add(model)
      return next
    })
  }

  const navigateToReport = (report: ReportSummary) => {
    navigate(`/reports/${encodeURIComponent(report.name)}?root_path=${encodeURIComponent(rootPath)}`)
  }

  const hasData = scanned && reports.length > 0

  const viewLabels: Record<DashboardView, string> = {
    timeline: t('dashboard.timelineView'),
    grouped: t('dashboard.groupedView'),
    byDataset: t('dashboard.byDatasetView'),
  }

  return (
    <div className="flex flex-col gap-5 min-h-0">
      {/* ── Path Bar ── */}
      <PathBar
        value={pathInput}
        onChange={setPathInput}
        onSubmit={handleScan}
        placeholder={t('dashboard.pathPlaceholder')}
        submitLabel={t('dashboard.scanBtn')}
        scanningLabel={t('dashboard.scanning')}
        scanning={scanning}
        disabled={!pathInput.trim()}
      />

      {/* ── KPI Cards ── */}
      {scanning ? (
        <KpiSkeleton />
      ) : (
        <div className="grid grid-cols-2 lg:grid-cols-4 gap-3">
          <KpiCard
            icon={<FileText size={18} strokeWidth={2} />}
            value={String(kpiStats.totalEvals)}
            label={t('dashboard.totalEvaluations')}
            gradient="var(--kpi-grad-0)"
            delay={0}
            onClick={() => { setView('timeline'); evalListRef.current?.scrollIntoView({ behavior: 'smooth' }) }}
          />
          <KpiCard
            icon={<Cpu size={18} strokeWidth={2} />}
            value={String(kpiStats.models)}
            label={t('dashboard.modelsEvaluated')}
            gradient="var(--kpi-grad-1)"
            delay={60}
            onClick={() => { setView('grouped'); evalListRef.current?.scrollIntoView({ behavior: 'smooth' }) }}
          />
          <KpiCard
            icon={<Database size={18} strokeWidth={2} />}
            value={String(kpiStats.datasets)}
            label={t('dashboard.datasetsUsed')}
            gradient="var(--kpi-grad-2)"
            delay={120}
            onClick={() => { setView('byDataset'); evalListRef.current?.scrollIntoView({ behavior: 'smooth' }) }}
          />
          <KpiCard
            icon={<Clock size={18} strokeWidth={2} />}
            value={kpiStats.latest.length > 20 ? kpiStats.latest.slice(0, 20) + '…' : kpiStats.latest}
            label={t('dashboard.latestEval')}
            gradient="var(--kpi-grad-3)"
            delay={180}
            onClick={() => reports.length > 0 && navigateToReport(reports[0])}
          />
        </div>
      )}

      {/* ── Loading skeleton for content ── */}
      {scanning && (
        <Card title={t('dashboard.evaluations')}>
          <Skeleton lines={8} height={14} />
        </Card>
      )}

      {/* ── Unified Evaluation List ── */}
      {hasData && !scanning && (
        <div ref={evalListRef}>
          <Card title={t('dashboard.evaluations')} badge={<Badge>{sortedReports.length}</Badge>}>
            {/* Controls bar */}
            <div className="flex items-center gap-3 flex-wrap mb-4">
              <ViewToggle value={view} onChange={setView} labels={viewLabels} />

              {/* Search */}
              <input
                type="text"
                placeholder={t('dashboard.searchPlaceholder')}
                value={search}
                onChange={e => setSearch(e.target.value)}
                className="flex-1 min-w-[160px] max-w-[300px] px-3 py-1.5 type-body-xs rounded-[var(--radius-sm)] bg-[var(--bg-deep)] border border-[var(--border)] text-[var(--text)] placeholder-[var(--text-dim)]"
              />

              {/* Sort */}
              <select
                value={sortBy}
                onChange={e => setSortBy(e.target.value)}
                className="px-3 py-1.5 type-body-xs rounded-[var(--radius-sm)] bg-[var(--bg-deep)] border border-[var(--border)] text-[var(--text)]"
              >
                <option value="time">{t('dashboard.sortTime')}</option>
                <option value="score">{t('dashboard.sortScore')}</option>
                <option value="model">{t('dashboard.sortModel')}</option>
              </select>
            </div>

            {/* List content */}
            <div className="overflow-y-auto max-h-[calc(100vh-300px)]">
              {sortedReports.length === 0 ? (
                <div className="text-center py-8 type-body-sm text-[var(--text-muted)]">
                  {t('dashboard.noEvals')}
                </div>
              ) : view === 'timeline' ? (
                /* ── Timeline view ── */
                <div className="flex flex-col gap-3">
                  {sortedReports.map((report) => (
                    <EvalRunCard
                      key={`${report.name}-${report.dataset_name}`}
                      report={report}
                      onClick={() => navigateToReport(report)}
                    />
                  ))}
                </div>
              ) : view === 'grouped' ? (
                /* ── Grouped view ── */
                <div className="flex flex-col gap-2">
                  {grouped.map(([model, runs]) => {
                    const expanded = expandedGroups.has(model)
                    const bestScore = Math.max(...runs.map(r => r.score))

                    return (
                      <div key={model} className="rounded-[var(--radius)] border border-[var(--border)] bg-[var(--bg-card)] overflow-hidden">
                        <ModelGroupHeader
                          title={model}
                          count={runs.length}
                          runsLabel={t('dashboard.runs')}
                          bestScore={bestScore}
                          bestScoreLabel={t('dashboard.bestScore')}
                          expanded={expanded}
                          onToggle={() => toggleGroup(model)}
                        />

                        {expanded && (
                          <div className="border-t border-[var(--border)]">
                            {runs.map((report) => (
                              <CompactRunRow
                                key={`${report.name}-${report.dataset_name}`}
                                report={report}
                                onClick={() => navigateToReport(report)}
                              />
                            ))}
                          </div>
                        )}
                      </div>
                    )
                  })}
                </div>
              ) : view === 'byDataset' ? (
                /* ── By Dataset view ── */
                <div className="flex flex-col gap-2">
                  {groupedByDataset.map(([dataset, runs]) => {
                    const expanded = expandedGroups.has(dataset)
                    const bestScore = Math.max(...runs.map(r => r.score))

                    return (
                      <div key={dataset} className="rounded-[var(--radius)] border border-[var(--border)] bg-[var(--bg-card)] overflow-hidden">
                        <ModelGroupHeader
                          title={dataset}
                          count={runs.length}
                          runsLabel={t('dashboard.runs')}
                          bestScore={bestScore}
                          bestScoreLabel={t('dashboard.bestScore')}
                          expanded={expanded}
                          onToggle={() => toggleGroup(dataset)}
                        />

                        {expanded && (
                          <div className="border-t border-[var(--border)]">
                            {runs.map((report) => (
                              <CompactRunRow
                                key={`${report.name}-${report.dataset_name}`}
                                report={report}
                                onClick={() => navigateToReport(report)}
                              />
                            ))}
                          </div>
                        )}
                      </div>
                    )
                  })}
                </div>
              ) : null}
            </div>
          </Card>
        </div>
      )}

      {/* ── Empty state after scan ── */}
      {scanned && !hasData && !scanning && (
        <div className="rounded-[var(--radius)] border border-[var(--border)] bg-[var(--bg-card)]">
          <EmptyState
            icon={<Inbox size={28} strokeWidth={1.5} />}
            title={t('dashboard.noReportsYet')}
            hint={t('dashboard.noReportsHint')}
          />
        </div>
      )}

      {/* ── Welcome state (before any scan) ── */}
      {!scanned && !scanning && (
        <div className="rounded-[var(--radius)] border border-[var(--border)] bg-[var(--bg-card)]">
          <EmptyState
            variant="welcome"
            icon={<FolderOpen size={28} strokeWidth={1.5} />}
            title={t('dashboard.welcomeTitle')}
            hint={t('dashboard.welcomeDesc')}
          />
        </div>
      )}
    </div>
  )
}
