"use client"

import {
  CheckCircle2,
  Clock,
  FileText,
  Inbox,
  Loader2,
  Plus,
  SearchCheck,
  XCircle,
  type LucideIcon,
} from "lucide-react"

import type { DeepdexQueueModule } from "@/components/deepdex/types"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@/components/ui/empty"
import { Skeleton } from "@/components/ui/skeleton"
import { TableCell, TableRow } from "@/components/ui/table"
import { cn } from "@/lib/utils"

export type QueueModule = DeepdexQueueModule

export const QUEUE_MODULE_META: Record<
  QueueModule,
  { label: string; description: string; emptyTitle: string; emptyDescription: string }
> = {
  deepdex: {
    label: "Deepdex",
    description: "Documents extracted by OCR. Move a term sheet to Structure or Accumulator for review.",
    emptyTitle: "No documents in the queue",
    emptyDescription: "Upload documents to extract their content, then move them to Structure or Accumulator.",
  },
  structure: {
    label: "Structure",
    description: "Structured-product term sheets, reviewed and saved to the structure master.",
    emptyTitle: "No structure files in the queue",
    emptyDescription: "Upload term sheets to extract structured products, then review and save them.",
  },
  accumulator: {
    label: "Accumulator",
    description: "Accumulator term sheets, reviewed and saved to the accumulator master.",
    emptyTitle: "No accumulator files in the queue",
    emptyDescription: "Upload accumulator term sheets to extract them, then review and save them.",
  },
}

type StatusStyle = { label: string; icon: LucideIcon; className: string; spin?: boolean }

const STATUS_STYLES: Record<string, StatusStyle> = {
  pending: {
    label: "Queued",
    icon: Clock,
    className: "border-border bg-muted/50 text-muted-foreground",
  },
  processing: {
    label: "Processing",
    icon: Loader2,
    spin: true,
    className: "border-sky-500/30 bg-sky-500/10 text-sky-600 dark:text-sky-400",
  },
  pending_review: {
    label: "Ready for review",
    icon: SearchCheck,
    className: "border-amber-500/30 bg-amber-500/10 text-amber-600 dark:text-amber-400",
  },
  completed: {
    label: "Completed",
    icon: CheckCircle2,
    className: "border-emerald-500/30 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400",
  },
  failed: {
    label: "Failed",
    icon: XCircle,
    className: "border-destructive/30 bg-destructive/10 text-destructive",
  },
}

/** Human label for a queue status, falling back to the raw value for anything new. */
export function queueStatusLabel(status: string): string {
  return STATUS_STYLES[status]?.label ?? status.replace(/_/g, " ")
}

export function QueueStatusBadge({ status }: { status: string }) {
  const style = STATUS_STYLES[status]
  if (!style) return <Badge variant="outline">{queueStatusLabel(status)}</Badge>
  const Icon = style.icon
  return (
    <Badge variant="outline" className={cn("gap-1.5 font-medium", style.className)}>
      <Icon className={cn("size-3", style.spin && "animate-spin")} />
      {style.label}
    </Badge>
  )
}

/** "2026-10-06 13:21:26" -> "2026-10-06 13:21" (seconds are noise in a list); the full value stays in the tooltip. */
export function formatQueueTimestamp(value: string): string {
  const trimmed = (value ?? "").trim()
  return trimmed.length >= 16 ? trimmed.slice(0, 16) : trimmed || "—"
}

export function QueueFileName({
  name,
  errorMessage,
  reviewReasons = [],
}: {
  name: string
  errorMessage?: string | null
  /** Structure uploads the validation rules held back from automatic publishing, and why. */
  reviewReasons?: string[]
}) {
  return (
    <div className="flex min-w-0 items-start gap-2">
      <FileText className="mt-0.5 size-4 shrink-0 text-muted-foreground" />
      <div className="min-w-0">
        <p className="truncate font-medium" title={name}>
          {name}
        </p>
        {errorMessage ? <p className="mt-0.5 line-clamp-2 text-xs text-destructive">{errorMessage}</p> : null}
        {reviewReasons.length > 0 ? (
          <p
            className="mt-0.5 line-clamp-2 text-xs text-amber-600 dark:text-amber-500"
            title={reviewReasons.join("\n")}
          >
            Needs manual review: {reviewReasons.join(" ")}
          </p>
        ) : null}
      </div>
    </div>
  )
}

export function QueueEmptyState({ module, onAddFiles }: { module: QueueModule; onAddFiles: () => void }) {
  const meta = QUEUE_MODULE_META[module]
  return (
    <div className="p-6">
      <Empty className="border border-border/60 bg-muted/10 py-14">
        <EmptyHeader>
          <EmptyMedia variant="icon" className="size-12 rounded-xl [&_svg:not([class*='size-'])]:size-6">
            <Inbox />
          </EmptyMedia>
          <EmptyTitle className="text-base">{meta.emptyTitle}</EmptyTitle>
          <EmptyDescription>{meta.emptyDescription}</EmptyDescription>
        </EmptyHeader>
        <EmptyContent>
          <Button onClick={onAddFiles}>
            <Plus className="size-4" />
            Add files
          </Button>
        </EmptyContent>
      </Empty>
    </div>
  )
}

/** Placeholder rows shown while the first page loads, so the card keeps its shape instead of collapsing to a line of text. */
export function QueueTableSkeletonRows({ columns, rows = 5 }: { columns: number; rows?: number }) {
  return (
    <>
      {Array.from({ length: rows }).map((_, row) => (
        <TableRow key={`skeleton-${row}`}>
          {Array.from({ length: columns }).map((__, col) => (
            <TableCell key={`skeleton-${row}-${col}`}>
              <Skeleton className={cn("h-4", col === 1 ? "w-56" : "w-20")} />
            </TableCell>
          ))}
        </TableRow>
      ))}
    </>
  )
}

/** "2 ready for review · 1 processing · 1 failed", for the rows currently listed. */
export function QueueStatusSummary({ counts }: { counts: Record<string, number> }) {
  const order = ["pending_review", "processing", "pending", "failed", "completed"]
  const parts = order.filter((status) => (counts[status] ?? 0) > 0)
  if (parts.length === 0) return null
  return (
    <div className="flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-muted-foreground">
      {parts.map((status) => {
        const style = STATUS_STYLES[status]
        const Icon = style?.icon
        return (
          <span key={status} className="inline-flex items-center gap-1.5">
            {Icon ? <Icon className={cn("size-3.5", style.spin && "animate-spin")} /> : null}
            <span className="font-medium text-foreground">{counts[status]}</span>
            {queueStatusLabel(status).toLowerCase()}
          </span>
        )
      })}
    </div>
  )
}
