import { useEffect, useState } from 'react'
import { Clock, Activity, AlertCircle, CheckCircle, Disc, Download, FileSpreadsheet, HardDrive, Trash2, LayoutGrid, List, RotateCcw } from 'lucide-react'
import { api } from '../lib/api'
import { useToast } from '../context/ToastContext'
import { PageHeader } from '../components/ui/PageHeader'
import { Card, CardHeader, CardTitle, CardContent } from '../components/ui/Card'
import { Button } from '../components/ui/Button'
import { StatusBadge, TypeBadge } from '../components/ui/Badge'
import ConfirmDialog from '../components/ConfirmDialog'
import DeviceDiscovery from '../components/DeviceDiscovery'
import JobDetailModal from '../components/JobDetailModal'
import LiveLogSection from '../components/LiveLogSection'
import { HeroCinemaBanner } from '../components/HeroCinemaBanner'
import { RadialProgress } from '../components/ui/RadialProgress'
import { ENCODER_BADGES } from '../lib/design'

interface JobMeta {
  year?: number
  overview?: string
  poster_path?: string
  genres?: string[]
  runtime?: number
  type?: string
  source?: string
}

interface Job {
  id: string
  type: 'cd' | 'dvd' | 'bluray' | 'uhd'
  status: 'pending' | 'processing' | 'transcoding' | 'canceling' | 'completed' | 'failed'
  device: string
  startTime: string
  endTime?: string
  progress: number
  title?: string
  can_retry?: boolean
  meta?: JobMeta | null
}

function posterUrl(meta?: JobMeta | null): string | null {
  const p = meta?.poster_path
  if (!p) return null
  return p.startsWith('http') ? p : `https://image.tmdb.org/t/p/w342${p}`
}

async function fetchJobs(): Promise<Job[]> {
  try {
    const response = await api.get('/jobs')
    return response.data
  } catch {
    return []
  }
}

export default function Dashboard() {
  const [jobs, setJobs] = useState<Job[]>([])
  const [workers, setWorkers] = useState<WorkerInfo[]>([])
  const [plaetze, setPlaetze] = useState<{ name: string, frei_gb: number, gesamt_gb: number }[]>([])
  const [loading, setLoading] = useState(true)
  const [detailJobId, setDetailJobId] = useState<string | null>(null)
  const [aufraeumenOffen, setAufraeumenOffen] = useState(false)
  const [viewMode, setViewMode] = useState<'grid' | 'table'>('grid')
  const { toast } = useToast()

  const jobLoeschen = async (job: Job) => {
    try {
      await api.delete(`/jobs/${job.id}`)
      toast('success', `„${job.title || job.id.slice(0, 8)}" aus der Liste entfernt`)
      setJobs(await fetchJobs())
    } catch (e: any) {
      toast('error', e?.response?.data?.detail || 'Entfernen fehlgeschlagen')
    }
  }

  const erledigteAufraeumen = async () => {
    setAufraeumenOffen(false)
    try {
      const r = await api.delete('/jobs')
      toast('success', `${r.data.deleted} erledigte Jobs entfernt — Dateien bleiben liegen`)
      setJobs(await fetchJobs())
    } catch {
      toast('error', 'Aufräumen fehlgeschlagen')
    }
  }

  useEffect(() => {
    const loadData = async () => {
      try {
        setJobs(await fetchJobs())
      } finally {
        setLoading(false)
      }
    }

    loadData()
    api.get('/capabilities').then(r => setWorkers(r.data.workers || [])).catch(() => {})
    api.get('/system/info').then(r => setPlaetze(r.data.plaetze || [])).catch(() => {})
    const interval = setInterval(loadData, 5000)
    return () => clearInterval(interval)
  }, [])

  const aktiverJob = jobs.find(j => j.status === 'processing' || j.status === 'transcoding')

  const stats = {
    pending: jobs.filter(j => j.status === 'pending').length,
    processing: jobs.filter(j => j.status === 'processing').length,
    completed: jobs.filter(j => j.status === 'completed').length,
    failed: jobs.filter(j => j.status === 'failed').length,
  }

  if (loading) {
    return (
      <div className="flex items-center justify-center min-h-[60vh]">
        <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-amber-500"></div>
      </div>
    )
  }

  return (
    <div className="space-y-8">
      <PageHeader
        title="Dashboard"
        subtitle="Dein Heimkino-Control-Center für Discs, Rips & Medien-Server"
      />

      {/* Hero Cinema Banner (3D Spinning Disc, Live Progress & Showcase) */}
      <HeroCinemaBanner
        aktiverJob={aktiverJob}
        onDetailClick={id => setDetailJobId(id)}
        onCancelClick={id => api.post(`/jobs/${id}/cancel`).catch(() => {})}
        totalJobsCount={jobs.length}
        completedCount={stats.completed}
      />

      {/* System Telemetrie Leiste */}
      <Card>
        <CardContent className="p-4 flex flex-wrap items-center gap-x-8 gap-y-3 text-sm">
          <div className="flex items-center gap-2.5">
            <Activity size={17} className="text-amber-500" />
            <span className="text-slate-500 dark:text-slate-400 font-medium">Encoder:</span>
            {workers.length === 0 ? (
              <span className="text-slate-400 dark:text-slate-500 italic">kein Worker</span>
            ) : (
              workers.flatMap(w => w.encoders).filter((e, i, a) => a.indexOf(e) === i).map(e => (
                <span key={e} className={`text-xs px-2.5 py-0.5 rounded-md font-medium border ${
                  e.startsWith('cpu')
                    ? 'bg-slate-200/80 dark:bg-slate-800 text-slate-700 dark:text-slate-300 border-slate-300 dark:border-slate-700'
                    : 'bg-emerald-500/15 text-emerald-600 dark:text-emerald-400 border-emerald-500/30'
                }`}>
                  {ENCODER_BADGES[e]?.label || e}
                </span>
              ))
            )}
          </div>

          <div className="flex items-center gap-2.5">
            <Clock size={17} className="text-amber-500" />
            <span className="text-slate-500 dark:text-slate-400 font-medium">Aktiv:</span>
            {aktiverJob ? (
              <span className="text-slate-900 dark:text-slate-200 font-medium">
                {aktiverJob.status === 'transcoding' ? 'Komprimieren' : 'Rippen'} · {aktiverJob.progress} %
              </span>
            ) : (
              <span className="text-slate-400 dark:text-slate-500 italic">kein Job</span>
            )}
          </div>

          {plaetze.length > 0 && (
            <div className="flex items-center gap-2.5 ml-auto">
              <HardDrive size={17} className="text-amber-500" />
              <span className="text-slate-500 dark:text-slate-400 font-medium">Frei:</span>
              {plaetze.map(p => (
                <span
                  key={p.name}
                  title={`${p.name}: ${p.frei_gb} von ${p.gesamt_gb} GB frei`}
                  className={`text-xs px-2.5 py-0.5 rounded-md font-mono border ${
                    p.frei_gb < 60
                      ? 'bg-amber-500/20 text-amber-700 dark:text-amber-300 border-amber-500/30 font-semibold'
                      : 'bg-slate-200/80 dark:bg-slate-800 text-slate-700 dark:text-slate-300 border-slate-300 dark:border-slate-700'
                  }`}
                >
                  {p.name.startsWith('Media') ? 'Media' : 'Arbeit'} {p.frei_gb} GB
                </span>
              ))}
            </div>
          )}
        </CardContent>
      </Card>

      {/* Laufwerke & Disc-Erkennung */}
      <DeviceDiscovery />

      {/* Stats Cards */}
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
        <StatCard 
          icon={Clock} 
          label="Warteschlange" 
          value={stats.pending.toString()} 
          badgeStyle="bg-amber-500/15 text-amber-500 border-amber-500/20"
        />
        <StatCard 
          icon={Activity} 
          label="Bearbeitung" 
          value={stats.processing.toString()} 
          badgeStyle="bg-sky-500/15 text-sky-500 border-sky-500/20"
        />
        <StatCard 
          icon={CheckCircle} 
          label="Fertig" 
          value={stats.completed.toString()} 
          badgeStyle="bg-emerald-500/15 text-emerald-500 border-emerald-500/20"
        />
        <StatCard 
          icon={AlertCircle} 
          label="Fehler" 
          value={stats.failed.toString()} 
          badgeStyle="bg-rose-500/15 text-rose-500 border-rose-500/20"
        />
      </div>

      {/* Recent Jobs: Choice between Visual Poster Grid & Classic Table */}
      <Card className="overflow-hidden">
        <CardHeader>
          <div className="flex items-center gap-3">
            <CardTitle>Neueste Jobs</CardTitle>
            <span className="text-xs text-slate-500 dark:text-slate-400">({jobs.length} insgesamt)</span>
          </div>

          <div className="flex items-center gap-3">
            {/* View Mode Toggle Button */}
            <div className="flex items-center p-1 rounded-xl bg-slate-100 dark:bg-slate-900 border border-slate-200 dark:border-slate-800">
              <button
                onClick={() => setViewMode('grid')}
                className={`p-1.5 rounded-lg text-xs font-medium transition-all ${
                  viewMode === 'grid'
                    ? 'bg-amber-500 text-slate-950 shadow-sm font-bold'
                    : 'text-slate-500 dark:text-slate-400 hover:text-slate-900 dark:hover:text-slate-200'
                }`}
                title="Visuelle Poster-Kacheln"
              >
                <LayoutGrid size={15} />
              </button>
              <button
                onClick={() => setViewMode('table')}
                className={`p-1.5 rounded-lg text-xs font-medium transition-all ${
                  viewMode === 'table'
                    ? 'bg-amber-500 text-slate-950 shadow-sm font-bold'
                    : 'text-slate-500 dark:text-slate-400 hover:text-slate-900 dark:hover:text-slate-200'
                }`}
                title="Kompakte Liste"
              >
                <List size={15} />
              </button>
            </div>

            {jobs.length > 0 && (
              <a
                href="/api/jobs/export"
                download
                title="Job-Historie als CSV herunterladen"
                className="inline-flex items-center gap-1.5 text-xs font-medium px-3 py-1.5 rounded-xl border border-slate-200 dark:border-slate-700 bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300 hover:bg-slate-200 dark:hover:bg-slate-700 transition-colors"
              >
                <FileSpreadsheet size={13} />
                CSV
              </a>
            )}
            {jobs.some(j => j.status === 'completed' || j.status === 'failed') && (
              <Button
                variant="secondary"
                size="sm"
                onClick={() => setAufraeumenOffen(true)}
                title="Erledigte Jobs aufräumen"
              >
                <Trash2 size={13} />
                Aufräumen
              </Button>
            )}
          </div>
        </CardHeader>

        {jobs.length === 0 ? (
          <div className="text-center py-16">
            <div className="mx-auto w-16 h-16 rounded-2xl flex items-center justify-center mb-3 bg-slate-100 dark:bg-slate-800 text-slate-400">
              <Disc size={32} />
            </div>
            <div className="mb-1 font-semibold text-slate-500 dark:text-slate-400">Noch keine Jobs</div>
            <p className="text-sm text-slate-400 dark:text-slate-500">Lege eine CD, DVD oder Blu-ray ein, um zu starten</p>
          </div>
        ) : viewMode === 'grid' ? (
          /* Visual Poster Cards Grid View */
          <div className="p-6 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5">
            {jobs.slice(0, 9).map(job => {
              const poster = posterUrl(job.meta)
              return (
                <div
                  key={job.id}
                  className="group relative rounded-2xl overflow-hidden border border-slate-200/80 dark:border-slate-800/80 bg-slate-50/50 dark:bg-slate-950/80 flex flex-col justify-between transition-all hover:border-amber-500/50 hover:shadow-xl hover:shadow-amber-500/10"
                >
                  <div className="flex p-4 gap-4">
                    {poster ? (
                      <img src={poster} alt={job.title || ''} className="w-24 h-36 rounded-xl object-cover flex-shrink-0 shadow-md border border-slate-700/50 group-hover:scale-105 transition-transform duration-300" />
                    ) : (
                      <div className="w-24 h-36 rounded-xl flex items-center justify-center flex-shrink-0 bg-slate-200 dark:bg-slate-900 text-slate-400 border border-slate-300 dark:border-slate-800">
                        <Disc size={32} />
                      </div>
                    )}

                    <div className="flex-1 min-w-0 flex flex-col justify-between">
                      <div>
                        <div className="flex items-center gap-1.5 flex-wrap mb-1">
                          <TypeBadge type={job.type} />
                          <StatusBadge status={job.status} />
                        </div>
                        <button
                          onClick={() => setDetailJobId(job.id)}
                          className="text-base font-bold text-left text-slate-900 dark:text-slate-100 hover:text-amber-500 dark:hover:text-amber-400 transition-colors line-clamp-2"
                        >
                          {job.title || 'Unbekannter Titel'}
                        </button>
                        <p className="text-[11px] text-slate-500 dark:text-slate-400 mt-1 font-mono">
                          Laufwerk: {job.device}
                        </p>
                      </div>

                      <div className="pt-2 flex items-center justify-between">
                        <RadialProgress progress={job.progress} size={48} strokeWidth={5} />
                        <span className="text-[10px] text-slate-400 font-mono">
                          {new Date(job.startTime).toLocaleTimeString('de-DE')}
                        </span>
                      </div>
                    </div>
                  </div>

                  <div className="px-4 py-2.5 bg-slate-100/70 dark:bg-slate-900/90 border-t border-slate-200/80 dark:border-slate-800/80 flex items-center justify-between">
                    <Button variant="ghost" size="sm" onClick={() => setDetailJobId(job.id)}>
                      Details
                    </Button>

                    <div className="flex items-center gap-2">
                      {job.status === 'completed' && (
                        <Button variant="amber" size="sm" onClick={() => setDetailJobId(job.id)}>
                          <Download size={13} /> Download
                        </Button>
                      )}
                      {job.status === 'failed' && job.can_retry && (
                        <Button
                          variant="secondary"
                          size="sm"
                          onClick={() => {
                            api.post(`/jobs/${job.id}/retry-transcode`)
                              .then(() => toast('success', 'Kompression neu eingereiht'))
                              .catch((e: any) => toast('error', e?.response?.data?.detail || 'Fehlgeschlagen'))
                          }}
                        >
                          <RotateCcw size={13} /> Neu
                        </Button>
                      )}
                      {(job.status === 'completed' || job.status === 'failed') && (
                        <button
                          onClick={() => jobLoeschen(job)}
                          className="p-1.5 rounded-lg text-rose-500 hover:bg-rose-500/10 transition-colors"
                          title="Löschen"
                        >
                          <Trash2 size={14} />
                        </button>
                      )}
                      {(job.status === 'pending' || job.status === 'processing' || job.status === 'transcoding') && (
                        <Button variant="danger" size="sm" onClick={() => api.post(`/jobs/${job.id}/cancel`).catch(() => {})}>
                          Abbrechen
                        </Button>
                      )}
                    </div>
                  </div>
                </div>
              )
            })}
          </div>
        ) : (
          /* Table View */
          <div className="overflow-x-auto">
            <table className="w-full">
              <thead className="bg-slate-50 dark:bg-slate-950/80 border-b border-slate-200/80 dark:border-slate-800">
                <tr>
                  <th className="px-6 py-3.5 text-left text-xs font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">Typ</th>
                  <th className="px-6 py-3.5 text-left text-xs font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">Titel</th>
                  <th className="px-6 py-3.5 text-left text-xs font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">Status</th>
                  <th className="px-6 py-3.5 text-left text-xs font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">Gerät</th>
                  <th className="px-6 py-3.5 text-left text-xs font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">Fortschritt</th>
                  <th className="px-6 py-3.5 text-left text-xs font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">Startzeit</th>
                  <th className="px-6 py-3.5 text-left text-xs font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">Aktion</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-200/80 dark:divide-slate-800">
                {jobs.slice(0, 10).map(job => (
                  <tr key={job.id} className="transition-colors hover:bg-slate-50 dark:hover:bg-slate-800/40">
                    <td className="px-6 py-4 whitespace-nowrap">
                      <TypeBadge type={job.type} />
                    </td>
                    <td className="px-6 py-4 whitespace-nowrap">
                      <button
                        onClick={() => setDetailJobId(job.id)}
                        className="text-sm font-medium text-left hover:underline text-slate-900 dark:text-slate-100 hover:text-amber-500 dark:hover:text-amber-400 transition-colors"
                      >
                        {job.title || 'Unbekannt'}
                      </button>
                    </td>
                    <td className="px-6 py-4 whitespace-nowrap">
                      <StatusBadge status={job.status} />
                    </td>
                    <td className="px-6 py-4 whitespace-nowrap text-sm font-mono text-slate-500 dark:text-slate-400">
                      {job.device}
                    </td>
                    <td className="px-6 py-4 whitespace-nowrap">
                      <RadialProgress progress={job.progress} size={42} strokeWidth={4} />
                    </td>
                    <td className="px-6 py-4 whitespace-nowrap text-sm font-mono text-slate-500 dark:text-slate-400">
                      {new Date(job.startTime).toLocaleString('de-DE')}
                    </td>
                    <td className="px-6 py-4 whitespace-nowrap">
                      {job.status === 'completed' && (
                        <Button variant="secondary" size="sm" onClick={() => setDetailJobId(job.id)}>
                          <Download size={13} className="text-emerald-500" /> Download
                        </Button>
                      )}
                      {(job.status === 'completed' || job.status === 'failed') && (
                        <button
                          onClick={() => jobLoeschen(job)}
                          className="ml-2 p-1.5 rounded-lg text-rose-500 hover:bg-rose-500/10 transition-colors"
                        >
                          <Trash2 size={14} />
                        </button>
                      )}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </Card>

      <LiveLogSection />

      <JobDetailModal jobId={detailJobId} onClose={() => setDetailJobId(null)} />

      <ConfirmDialog
        isOpen={aufraeumenOffen}
        onClose={() => setAufraeumenOffen(false)}
        onConfirm={erledigteAufraeumen}
        title="Job-Liste aufräumen?"
        message="Alle fertigen und fehlgeschlagenen Jobs verschwinden aus der Liste. Die gerippten Dateien bleiben selbstverständlich liegen."
        confirmText="Aufräumen"
        type="warning"
      />
    </div>
  )
}

function StatCard({ icon: Icon, label, value, badgeStyle }: { icon: any, label: string, value: string, badgeStyle: string }) {
  return (
    <Card>
      <CardContent className="p-5 flex items-center gap-4">
        <div className={`p-3 rounded-xl border ${badgeStyle}`}>
          <Icon className="w-6 h-6" />
        </div>
        <div>
          <p className="text-xs font-medium text-slate-500 dark:text-slate-400">{label}</p>
          <p className="text-3xl font-extrabold text-slate-900 dark:text-slate-100">{value}</p>
        </div>
      </CardContent>
    </Card>
  )
}
