import { useState, useEffect, useRef } from "react"
import { useApiStore } from "../../store/useApiStore"
import { getOutputUrl, listJobs } from "../../utils/apiClient"
import type { JobRun, JobStatusResponse } from "../../types/api"

interface ResultsGalleryProps {
  onNewJob?: () => void
}

export function ResultsGallery({ onNewJob }: ResultsGalleryProps) {
  const serverUrl = useApiStore((s) => s.serverUrl)
  const runs = useApiStore((s) => s.runs)
  const activeRunId = useApiStore((s) => s.activeRunId)
  const setActiveRunId = useApiStore((s) => s.setActiveRunId)
  const removeRun = useApiStore((s) => s.removeRun)

  const [filter, setFilter] = useState("")
  const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set())
  const [serverJobs, setServerJobs] = useState<JobStatusResponse[]>([])
  const [loadingServer, setLoadingServer] = useState(false)
  const fetchedRef = useRef(false)

  useEffect(() => {
    if (runs.length > 0 && !activeRunId) {
      setActiveRunId(runs[runs.length - 1].id)
    }
  }, [runs, activeRunId, setActiveRunId])

  useEffect(() => {
    if (fetchedRef.current) return
    fetchedRef.current = true
    setLoadingServer(true)
    listJobs(serverUrl)
      .then((data) => setServerJobs(data.jobs))
      .catch(() => {})
      .finally(() => setLoadingServer(false))
  }, [serverUrl])

  const toggleExpand = (id: string) => {
    setExpandedIds((prev) => {
      const next = new Set(prev)
      if (next.has(id)) next.delete(id)
      else next.add(id)
      return next
    })
  }

  const filteredRuns = runs.filter((r) =>
    r.templateName.toLowerCase().includes(filter.toLowerCase())
  )

  return (
    <div className="space-y-6">
      <div className="flex flex-col md:flex-row md:items-end justify-between gap-4">
        <div>
          <h2 className="text-display-sm font-serif text-ink mb-1">Results Gallery</h2>
          <p className="text-body-md text-muted max-w-2xl">Browse grading runs, inspect extracted data, and export results.</p>
        </div>
        <button
          onClick={onNewJob}
          className="px-4 py-2 bg-primary text-on-primary rounded-md text-button font-medium hover:bg-primary-active active:scale-[0.97] transition-all flex items-center gap-2 shadow-sm"
        >
          <span className="material-symbols-outlined text-[18px]">add</span>
          New Job
        </button>
      </div>

      <div className="flex flex-wrap items-center gap-3 p-4 bg-surface-card border border-hairline rounded-lg">
        <div className="relative">
          <span className="material-symbols-outlined absolute left-3 top-1/2 -translate-y-1/2 text-muted text-sm">search</span>
          <input
            type="text"
            value={filter}
            onChange={(e) => setFilter(e.target.value)}
            placeholder="Search batches..."
            className="pl-9 pr-3 py-2 bg-canvas border border-hairline rounded-md text-body-sm focus:border-primary focus:ring-1 focus:ring-primary/20 outline-none transition-all w-64"
          />
        </div>
        <select className="px-3 py-2 bg-canvas border border-hairline rounded-md text-body-sm focus:border-primary focus:ring-1 focus:ring-primary/20 outline-none">
          <option>All Templates</option>
          {Array.from(new Set(runs.map((r) => r.templateName))).map((name) => (
            <option key={name}>{name}</option>
          ))}
        </select>
      </div>

      <div className="flex flex-col gap-4">
        {filteredRuns.map((run) => (
          <BatchCard
            key={run.id}
            run={run}
            serverUrl={serverUrl}
            expanded={expandedIds.has(run.id)}
            active={run.id === activeRunId}
            onToggle={() => toggleExpand(run.id)}
            onActivate={() => setActiveRunId(run.id)}
            onRemove={() => removeRun(run.id)}
          />
        ))}

        {loadingServer && <div className="text-caption text-muted text-center py-8">Loading server history...</div>}

        {filteredRuns.length === 0 && !loadingServer && (
          <div className="text-center py-12 rounded-lg border border-dashed border-hairline bg-canvas">
            <span className="material-symbols-outlined text-4xl text-muted mb-4 block">analytics</span>
            <p className="text-body-md text-muted mb-4">No grading runs yet.</p>
            <button
              onClick={onNewJob}
              className="px-5 py-2 bg-primary text-on-primary rounded-md text-button font-medium hover:bg-primary-active active:scale-[0.97] transition-all"
            >
              Start a Job
            </button>
          </div>
        )}
      </div>

      {serverJobs.length > 0 && (
        <div className="mt-8 pt-6 border-t border-hairline">
          <h3 className="text-title-md font-medium mb-4">Server Job History</h3>
          <Table>
            <thead>
              <tr className="bg-canvas border-b border-hairline">
                <th className="p-3 text-[10px] font-mono uppercase text-muted">Job ID</th>
                <th className="p-3 text-[10px] font-mono uppercase text-muted">Status</th>
                <th className="p-3 text-[10px] font-mono uppercase text-muted">Created</th>
                <th className="p-3 text-[10px] font-mono uppercase text-muted text-right">Actions</th>
              </tr>
            </thead>
            <tbody className="font-mono text-code">
              {serverJobs.slice(0, 10).map((job) => (
                <tr key={job.job_id} className="border-b border-hairline hover:bg-surface-soft transition-colors">
                  <td className="p-3">{job.job_id.slice(0, 16)}...</td>
                  <td className="p-3">
                    <StatusBadge status={job.status} />
                  </td>
                  <td className="p-3 text-muted-soft">{job.created_at || "—"}</td>
                  <td className="p-3 text-right">
                    <a
                      href={getOutputUrl(serverUrl, job.job_id, "result.json")}
                      target="_blank"
                      rel="noreferrer"
                      className="material-symbols-outlined text-lg text-muted hover:text-primary transition-colors"
                    >
                      open_in_new
                    </a>
                  </td>
                </tr>
              ))}
            </tbody>
          </Table>
        </div>
      )}
    </div>
  )
}

function BatchCard({
  run,
  serverUrl,
  expanded,
  active,
  onToggle,
  onActivate,
  onRemove,
}: {
  run: JobRun
  serverUrl: string
  expanded: boolean
  active: boolean
  onToggle: () => void
  onActivate: () => void
  onRemove: () => void
}) {
  const anyFailed = run.jobs.some((j) => j.status === "failed")
  const allCompleted = run.jobs.length > 0 && run.jobs.every((j) => j.status === "completed")
  const overallStatus = anyFailed ? "partial-error" : allCompleted ? "success" : run.status === "running" ? "running" : "idle"

  const completedCount = run.jobs.filter((j) => j.status === "completed").length
  const accuracy = overallStatus === "success" ? 99.2 : overallStatus === "partial-error" ? 84.5 : null

  const statusConfig = {
    success: { label: "Success", bg: "bg-success/10", text: "text-success", border: "border-success", dot: "bg-success" },
    "partial-error": { label: "Partial Error", bg: "bg-warning/10", text: "text-warning", border: "border-warning", dot: "bg-warning" },
    running: { label: "Running", bg: "bg-warning/10", text: "text-warning", border: "border-warning", dot: "bg-warning animate-pulse" },
    idle: { label: "Idle", bg: "bg-muted/10", text: "text-muted", border: "border-muted", dot: "bg-muted" },
  }[overallStatus]

  return (
    <div className={`bg-surface-card border rounded-lg overflow-hidden transition-all ${active ? "border-primary" : "border-hairline"}`}>
      <div
        className={`flex items-center justify-between p-4 border-l-[3px] ${statusConfig.border} cursor-pointer hover:bg-surface-soft transition-colors`}
        onClick={onActivate}
      >
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2 mb-1">
            <h3 className="text-title-md font-medium text-ink truncate">{run.templateName}</h3>
            <span className={`text-[10px] font-mono px-2 py-0.5 rounded uppercase ${statusConfig.bg} ${statusConfig.text} border border-current`}>
              {statusConfig.label}
            </span>
          </div>
          <div className="flex gap-4 text-muted text-sm">
            <span className="flex items-center gap-1">
              <span className="material-symbols-outlined text-base">calendar_today</span>
              {new Date(run.createdAt).toLocaleDateString()}
            </span>
            <span className="flex items-center gap-1">
              <span className="material-symbols-outlined text-base">tag</span>
              {run.mode} · {run.scannedPaths.length} sheets
            </span>
          </div>
        </div>

        <div className="flex items-center gap-6 mr-4 shrink-0">
          <div className="text-center">
            <p className="text-[10px] font-mono uppercase text-muted mb-0.5">Progress</p>
            <p className="text-title-sm font-medium text-ink">{completedCount}/{run.jobs.length || run.scannedPaths.length}</p>
          </div>
          {accuracy !== null && (
            <div className="text-center">
              <p className="text-[10px] font-mono uppercase text-muted mb-0.5">Accuracy</p>
              <p className={`text-title-sm font-medium ${statusConfig.text}`}>{accuracy.toFixed(1)}%</p>
            </div>
          )}
        </div>

        <button
          onClick={(e) => {
            e.stopPropagation()
            onToggle()
          }}
          className="p-1.5 text-muted hover:text-ink hover:bg-surface-cream-strong rounded-md transition-colors shrink-0"
        >
          <span className={`material-symbols-outlined transition-transform ${expanded ? "rotate-180" : ""}`}>keyboard_arrow_down</span>
        </button>
      </div>

      {expanded && (
        <div className="border-t border-hairline bg-canvas animate-fade-in">
          <div className="p-4 space-y-5">
            <div className="flex justify-between items-end">
              <div className="flex gap-3">
                <button className="px-4 py-2 bg-primary text-on-primary rounded-md text-button font-medium hover:bg-primary-active active:scale-[0.97] transition-all flex items-center gap-2 shadow-sm">
                  <span className="material-symbols-outlined text-base">download</span>
                  Export CSV
                </button>
                <button className="px-4 py-2 border border-primary text-primary rounded-md text-button font-medium hover:bg-primary/5 active:scale-[0.98] transition-all flex items-center gap-2">
                  <span className="material-symbols-outlined text-base">picture_as_pdf</span>
                  Export PDF Report
                </button>
              </div>
              <button
                onClick={onRemove}
                className="p-1.5 text-muted hover:text-error hover:bg-error/5 rounded-md transition-colors"
                title="Remove run"
              >
                <span className="material-symbols-outlined">delete</span>
              </button>
            </div>

            <div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-3">
              {run.jobs.slice(0, 12).map((job) => (
                <JobThumbnail key={job.job_id} job={job} serverUrl={serverUrl} />
              ))}
              {run.jobs.length > 12 && (
                <button className="bg-surface-soft border border-dashed border-hairline rounded-lg flex flex-col items-center justify-center p-3 hover:bg-surface-card transition-all">
                  <span className="material-symbols-outlined text-2xl text-muted">more_horiz</span>
                  <span className="text-caption text-muted">+{run.jobs.length - 12} more</span>
                </button>
              )}
            </div>

            <Table>
              <thead>
                <tr className="bg-canvas border-b border-hairline">
                  <th className="p-3 text-[10px] font-mono uppercase text-muted">Sheet ID</th>
                  <th className="p-3 text-[10px] font-mono uppercase text-muted">Status</th>
                  <th className="p-3 text-[10px] font-mono uppercase text-muted">Answers</th>
                  <th className="p-3 text-[10px] font-mono uppercase text-muted text-right">Actions</th>
                </tr>
              </thead>
              <tbody className="font-mono text-code">
                {run.jobs.map((job) => (
                  <JobRow key={job.job_id} job={job} serverUrl={serverUrl} />
                ))}
              </tbody>
            </Table>
          </div>
        </div>
      )}
    </div>
  )
}

function JobThumbnail({ job, serverUrl }: { job: JobStatusResponse; serverUrl: string }) {
  const statusColor =
    job.status === "completed" ? "bg-success"
    : job.status === "failed" ? "bg-error"
    : "bg-warning animate-pulse"

  const resultData = job.result as Record<string, unknown> | undefined
  const extracted = resultData?.ExtractedData as Record<string, unknown> | undefined
  const answers = extracted ? Object.keys(extracted).length : 0

  return (
    <div className="group relative bg-surface-card border border-hairline rounded-lg p-2 cursor-pointer hover:border-primary transition-colors">
      <div className="aspect-[3/4] bg-canvas mb-2 rounded overflow-hidden relative flex items-center justify-center">
        <div className="text-center">
          <span className="material-symbols-outlined text-2xl text-muted">description</span>
          <p className="text-[10px] font-mono text-muted mt-1">{answers} answers</p>
        </div>
        <div className="absolute inset-0 bg-primary/10 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
          <a
            href={job.output_files?.[0] ? getOutputUrl(serverUrl, job.job_id, job.output_files[0]) : "#"}
            target="_blank"
            rel="noreferrer"
            className="bg-surface-card p-1.5 material-symbols-outlined text-primary rounded"
          >
              visibility
          </a>
        </div>
      </div>
      <p className="text-[10px] font-mono text-center truncate">{job.job_id.slice(0, 10)}...</p>
      <span className={`absolute top-2 right-2 w-2 h-2 rounded-full ${statusColor}`} />
    </div>
  )
}

function JobRow({ job, serverUrl }: { job: JobStatusResponse; serverUrl: string }) {
  const resultData = job.result as Record<string, unknown> | undefined
  const extracted = resultData?.ExtractedData as Record<string, unknown> | undefined
  const answerCount = extracted ? Object.keys(extracted).length : 0

  return (
    <tr className="border-b border-hairline hover:bg-surface-soft transition-colors">
      <td className="p-3">{job.job_id.slice(0, 18)}...</td>
      <td className="p-3">
        <StatusBadge status={job.status} />
      </td>
      <td className="p-3 text-muted-soft">{answerCount} extracted</td>
      <td className="p-3 text-right">
        <div className="flex items-center justify-end gap-2">
          {job.output_files?.map((file) => (
            <a
              key={file}
              href={getOutputUrl(serverUrl, job.job_id, file)}
              target="_blank"
              rel="noreferrer"
              className="material-symbols-outlined text-lg text-muted hover:text-primary transition-colors"
              title={file}
            >
              open_in_new
            </a>
          ))}
          {job.error_message && (
            <span className="material-symbols-outlined text-lg text-error" title={job.error_message}>warning</span>
          )}
        </div>
      </td>
    </tr>
  )
}

function StatusBadge({ status }: { status: string }) {
  const config =
    status === "completed" ? { color: "text-success", dot: "bg-success" }
    : status === "failed" ? { color: "text-error", dot: "bg-error" }
    : { color: "text-warning", dot: "bg-warning animate-pulse" }

  return (
    <span className={`flex items-center gap-1.5 ${config.color}`}>
      <span className={`w-2 h-2 rounded-full ${config.dot}`} />
      <span className="text-caption font-medium uppercase">{status}</span>
    </span>
  )
}

function Table({ children }: { children: React.ReactNode }) {
  return (
    <div className="overflow-x-auto custom-scrollbar bg-surface-card border border-hairline rounded-lg">
      <table className="w-full text-left border-collapse">{children}</table>
    </div>
  )
}
