"use client";

import Link from "next/link";
import { ArrowDown, ArrowUp, ArrowUpDown, Archive, CornerUpRight, Download, ExternalLink, Eye, FolderInput, FolderOpen, History, Link2, MoreVertical, Pencil, Tag, Trash2, Upload } from "lucide-react";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
import { Skeleton } from "@/components/ui/skeleton";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { cn } from "@/lib/utils";
import { FILE_KIND_STYLES, STATUS_LABELS, STATUS_TONES, fileKind, fileTypeLabel, formatBytes, formatDate, formatTime, initials, isImage, ownerRecordPath, ownerTypeLabel } from "./file-utils";
import { nodeIcon, pathLabel } from "./file-nodes";
import { documentDownloadUrl, documentPreviewUrl } from "./useDocuments";

export function FileIcon({ document, size = "default", className }) {
  const { icon: Icon, className: tone } = FILE_KIND_STYLES[fileKind(document)];
  return <span className={cn("grid shrink-0 place-items-center rounded-md", tone, size === "large" ? "size-14 rounded-lg" : size === "small" ? "size-7" : "size-9", className)}>
    <Icon className={size === "large" ? "size-7" : "size-4"} />
  </span>;
}

export function StatusChip({ status }) {
  return <Badge variant={STATUS_TONES[status] || "neutral"}>{STATUS_LABELS[status] || "Current"}</Badge>;
}

export function UserChip({ name }) {
  return <span className="inline-flex min-w-0 items-center gap-2">
    <Avatar className="size-6"><AvatarFallback className="text-xs font-medium">{initials(name)}</AvatarFallback></Avatar>
    <span className="truncate">{name || "Unknown"}</span>
  </span>;
}

/**
 * Row / card / details actions. onAction receives "" (view), "edit", "move", "category", "supersede", "history", or "archive".
 * Items the user cannot perform are hidden, matching the server permissions on each document.
 */
export function FileMenu({ document, onAction, canMove = true, trigger, align = "end" }) {
  const canDownload = document.permissions?.download;
  const archived = document.status === "deleted";
  const canEdit = document.permissions?.update && !archived;
  const canMoveIt = canMove && document.permissions?.move && !archived;

  return <DropdownMenu>
    <DropdownMenuTrigger asChild>
      {trigger || <Button variant="ghost" size="icon-sm" aria-label={`Actions for ${document.title}`} onClick={(event) => event.stopPropagation()}><MoreVertical /></Button>}
    </DropdownMenuTrigger>
    <DropdownMenuContent align={align} className="w-52" onClick={(event) => event.stopPropagation()}>
      <DropdownMenuItem onSelect={() => onAction("")}><Eye /> View details</DropdownMenuItem>
      {canDownload && !archived && document.previewable && <DropdownMenuItem asChild><a href={documentPreviewUrl(document.id)} target="_blank" rel="noopener"><ExternalLink /> Open in new tab</a></DropdownMenuItem>}
      {canDownload && !archived && <DropdownMenuItem asChild><a href={documentDownloadUrl(document.id)}><Download /> Download</a></DropdownMenuItem>}
      {(canEdit || canMoveIt || document.permissions?.supersede) && !archived && <DropdownMenuSeparator />}
      {canEdit && <DropdownMenuItem onSelect={() => onAction("edit")}><Pencil /> Edit details</DropdownMenuItem>}
      {canEdit && <DropdownMenuItem onSelect={() => onAction("category")}><Tag /> Set category…</DropdownMenuItem>}
      {canMoveIt && <DropdownMenuItem onSelect={() => onAction("move")}><FolderInput /> Move to…</DropdownMenuItem>}
      {document.permissions?.supersede && !archived && <DropdownMenuItem onSelect={() => onAction("supersede")}><Upload /> Upload new version</DropdownMenuItem>}
      <DropdownMenuItem onSelect={() => onAction("history")}><History /> Version history</DropdownMenuItem>
      {document.permissions?.delete && !archived && <>
        <DropdownMenuSeparator />
        <DropdownMenuItem variant="destructive" onSelect={() => onAction("archive")}><Archive /> Archive</DropdownMenuItem>
      </>}
    </DropdownMenuContent>
  </DropdownMenu>;
}

function SortHead({ label, sortKey, sort, onSort, className }) {
  if (!onSort) return <TableHead className={className}>{label}</TableHead>;
  const active = sort?.key === sortKey;
  const Icon = !active ? ArrowUpDown : sort.direction === "asc" ? ArrowUp : ArrowDown;

  return <TableHead className={className} aria-sort={active ? (sort.direction === "asc" ? "ascending" : "descending") : "none"}>
    <Button variant="ghost" size="sm" className="-ml-2 h-8 px-2 font-medium" onClick={() => onSort(sortKey)} aria-label={`Sort by ${label}`}>
      {label}<Icon className={cn("size-3.5", !active && "text-muted-foreground/60")} />
    </Button>
  </TableHead>;
}

// "Tech pack.pdf · v2 · Restricted"
function fileMeta(document) {
  return [
    document.originalFilename,
    document.version > 1 ? `v${document.version}` : null,
    document.visibility === "restricted" ? "Restricted" : null,
  ].filter(Boolean).join(" · ");
}

/** Where a file is filed ("H&M › PO-0012 › SHP-0003"), from the list row's path, else its owner. */
export function filedInLabel(document) {
  const path = pathLabel(document.path);
  if (path) return path;
  return document.owner?.label ? `${ownerTypeLabel(document)} ${document.owner.label}` : "";
}

/**
 * "Linked to" / "Filed in" cell: the record that owns the file, linked by its code, with the path under it.
 */
export function LinkedRecord({ document, compact = false }) {
  const path = ownerRecordPath(document.owner) || document.owner?.url || null;
  const label = document.owner?.label || "Unknown record";
  const type = ownerTypeLabel(document);
  const where = pathLabel(document.path);

  if (compact) {
    return <span className="inline-flex min-w-0 items-center gap-1 text-xs text-muted-foreground">
      <Link2 className="size-3 shrink-0" />
      <span className="truncate" title={where || label}>{where || <>{type} · {label}</>}</span>
    </span>;
  }

  return <div className="grid min-w-0">
    {path
      ? <Link href={path} className="truncate font-medium hover:underline" title={`Open ${type} ${label}`} onClick={(event) => event.stopPropagation()}>{label}</Link>
      : <span className="truncate">{label}</span>}
    <span className="truncate text-xs text-muted-foreground" title={where || type}>{where || type}</span>
  </div>;
}

/** Badges that explain a row: linked from elsewhere, used by records, newer version. */
export function FileBadges({ document }) {
  return <>
    {document.linked && <Badge variant="info" className="h-5 shrink-0 px-1.5 text-xs font-normal"><Link2 /> Linked</Badge>}
    {document.newerVersionId && <Badge variant="warning" className="h-5 shrink-0 px-1.5 text-xs font-normal">Newer version</Badge>}
    {document.usedIn > 0 && <Badge variant="outline" className="h-5 shrink-0 px-1.5 text-xs font-normal" title={`Used by ${document.usedIn} ${document.usedIn === 1 ? "record" : "records"}`}><Link2 /> Used {document.usedIn}×</Badge>}
  </>;
}

function FolderItemMeta({ item }) {
  const parts = [
    typeof item.count === "number" ? (item.count ? `${item.count} ${item.count === 1 ? "file" : "files"}` : "Empty") : null,
    item.sublabel,
    item.isShortcut ? "Opens where it is filed" : null,
  ].filter(Boolean);
  return <span className="truncate text-xs text-muted-foreground">{parts.join(" · ")}</span>;
}

// Menu for manual folders (sections and records have no menu; they are part of the business hierarchy).
function FolderItemMenu({ item, onFolderAction, trigger }) {
  const manual = item.manual;
  if (!manual || !onFolderAction) return null;
  return <DropdownMenu>
    <DropdownMenuTrigger asChild>
      {trigger || <Button variant="ghost" size="icon-sm" aria-label={`Actions for folder ${item.label}`} onClick={(event) => event.stopPropagation()}><MoreVertical /></Button>}
    </DropdownMenuTrigger>
    <DropdownMenuContent align="end" className="w-48" onClick={(event) => event.stopPropagation()}>
      <DropdownMenuItem onSelect={() => onFolderAction("open", item)}><FolderOpen /> Open</DropdownMenuItem>
      {manual.permissions?.update !== false && manual.id && <DropdownMenuItem onSelect={() => onFolderAction("rename", item)}><Pencil /> Rename</DropdownMenuItem>}
      {manual.permissions?.delete !== false && manual.id && <>
        <DropdownMenuSeparator />
        <DropdownMenuItem variant="destructive" onSelect={() => onFolderAction("delete", item)}><Trash2 /> Delete folder</DropdownMenuItem>
      </>}
    </DropdownMenuContent>
  </DropdownMenu>;
}

/**
 * One explorer list: child folders first (records, sections, shortcuts, manual folders), then files.
 * selection: { ids, toggle, toggleAll, all, some } or null (read-only lists such as "Linked here").
 * columns: which optional columns fit (size, type, user, path).
 */
export function FileTable({ folders = [], documents, selection, activeId, sort, onSort, onOpenFolder, onFolderAction, onOpen, columns = {}, showPath = false }) {
  const hasDocuments = documents.length > 0;

  return <div className="overflow-hidden rounded-lg border">
    <Table>
      <TableHeader className="bg-muted/40">
        <TableRow className="hover:bg-transparent">
          {selection && <TableHead className="w-10 pl-3">
            {hasDocuments && <Checkbox checked={selection.all ? true : selection.some ? "indeterminate" : false} onCheckedChange={selection.toggleAll} aria-label="Select all files on this page" />}
          </TableHead>}
          <SortHead label="Name" sortKey="title" sort={sort} onSort={onSort} className={selection ? undefined : "pl-3"} />
          {columns.type && <TableHead className="w-20">Type</TableHead>}
          {columns.size && <SortHead label="Size" sortKey="size" sort={sort} onSort={onSort} className="w-24" />}
          <SortHead label="Modified" sortKey="uploaded_at" sort={sort} onSort={onSort} className="w-36" />
          {columns.user && <TableHead className="w-40">Uploaded by</TableHead>}
          {showPath && columns.path && <TableHead className="w-48">Filed in</TableHead>}
          <TableHead className="w-12 pr-3"><span className="sr-only">Actions</span></TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {folders.map((item) => {
          const Icon = nodeIcon(item);
          return <TableRow key={item.key} className="cursor-pointer" onClick={() => onOpenFolder(item)}>
            {selection && <TableCell className="pl-3" />}
            <TableCell className={cn("max-w-0 whitespace-normal", !selection && "pl-3")}>
              <div className="flex min-w-0 items-center gap-3">
                <span className="relative grid size-9 shrink-0 place-items-center rounded-md bg-muted text-muted-foreground">
                  <Icon className="size-4" />
                  {item.isShortcut && <CornerUpRight className="absolute -right-1 -bottom-1 size-3.5 rounded-sm bg-background p-px" aria-hidden="true" />}
                </span>
                <div className="grid min-w-0">
                  <button type="button" className={cn("truncate text-left font-medium outline-none hover:underline focus-visible:underline", item.count === 0 && "text-muted-foreground")} title={`Open ${item.label}`} onClick={(event) => { event.stopPropagation(); onOpenFolder(item); }}>
                    {item.label}{item.code && item.code !== item.label && item.kind !== "organization" ? <span className="ml-1.5 font-normal text-muted-foreground">{item.code}</span> : null}
                  </button>
                  <FolderItemMeta item={item} />
                </div>
              </div>
            </TableCell>
            {columns.type && <TableCell className="text-xs font-medium text-muted-foreground">{item.isShortcut ? "Shortcut" : "Folder"}</TableCell>}
            {columns.size && <TableCell className="text-muted-foreground">—</TableCell>}
            <TableCell className="text-muted-foreground">{item.modifiedAt ? formatDate(item.modifiedAt) : "—"}</TableCell>
            {columns.user && <TableCell className="text-muted-foreground">—</TableCell>}
            {showPath && columns.path && <TableCell className="text-muted-foreground">—</TableCell>}
            <TableCell className="pr-3 text-right" onClick={(event) => event.stopPropagation()}>
              <FolderItemMenu item={item} onFolderAction={onFolderAction} />
            </TableCell>
          </TableRow>;
        })}
        {documents.map((document) => {
          const selected = selection?.ids.includes(document.id);
          const active = activeId === document.id;
          const meta = fileMeta(document);

          return <TableRow
            key={document.id}
            data-state={selected ? "selected" : undefined}
            className={cn("cursor-pointer", active && "bg-accent/60", document.status === "deleted" && "text-muted-foreground")}
            onClick={() => onOpen(document)}
          >
            {selection && <TableCell className="pl-3" onClick={(event) => event.stopPropagation()}>
              <Checkbox checked={selected} onCheckedChange={() => selection.toggle(document.id)} aria-label={`Select ${document.title}`} />
            </TableCell>}
            <TableCell className={cn("max-w-0 whitespace-normal", !selection && "pl-3")}>
              <div className="flex min-w-0 items-center gap-3">
                <FileIcon document={document} />
                <div className="grid min-w-0 gap-0.5">
                  <button type="button" className="truncate text-left font-medium outline-none hover:underline focus-visible:underline" title={document.title} onClick={(event) => { event.stopPropagation(); onOpen(document); }}>{document.title}</button>
                  <span className="flex min-w-0 items-center gap-1.5 overflow-hidden">
                    {document.type?.label && <Badge variant="secondary" className="h-5 shrink-0 px-1.5 text-xs font-normal">{document.type.label}</Badge>}
                    <FileBadges document={document} />
                    <span className="min-w-0 truncate text-xs text-muted-foreground" title={meta}>{meta}</span>
                  </span>
                  {showPath && !columns.path && <LinkedRecord document={document} compact />}
                </div>
              </div>
            </TableCell>
            {columns.type && <TableCell className="text-xs font-medium text-muted-foreground">{fileTypeLabel(document)}</TableCell>}
            {columns.size && <TableCell className="tabular-nums text-muted-foreground">{formatBytes(document.fileSize)}</TableCell>}
            <TableCell><div className="grid"><span>{formatDate(document.uploadedAt)}</span><span className="text-xs text-muted-foreground">{formatTime(document.uploadedAt)}</span></div></TableCell>
            {columns.user && <TableCell className="max-w-0"><UserChip name={document.uploadedBy?.name} /></TableCell>}
            {showPath && columns.path && <TableCell className="max-w-0"><LinkedRecord document={document} /></TableCell>}
            <TableCell className="pr-3 text-right" onClick={(event) => event.stopPropagation()}>
              <FileMenu document={document} onAction={(action) => onOpen(document, action)} />
            </TableCell>
          </TableRow>;
        })}
      </TableBody>
    </Table>
  </div>;
}

// Grid view: folder cards first, then file cards, in one grid.
export function FileGrid({ folders = [], documents, selection, activeId, onOpenFolder, onFolderAction, onOpen, showPath = false }) {
  return <div className="grid grid-cols-[repeat(auto-fill,minmax(150px,1fr))] gap-3">
    {folders.map((item) => {
      const Icon = nodeIcon(item);
      return <article
        key={item.key}
        className="group/card relative flex min-w-0 cursor-pointer flex-col overflow-hidden rounded-lg border bg-card transition-shadow hover:shadow-md"
        onClick={() => onOpenFolder(item)}
      >
        <div className="relative grid aspect-4/3 place-items-center bg-muted/50">
          <span className="relative grid size-14 place-items-center rounded-lg bg-muted text-muted-foreground">
            <Icon className="size-7" />
            {item.isShortcut && <CornerUpRight className="absolute -right-1 -bottom-1 size-4 rounded-sm bg-background p-px" aria-hidden="true" />}
          </span>
          {typeof item.count === "number" && <Badge variant="secondary" className="absolute bottom-2 left-2 h-5 px-1.5 text-xs font-normal tabular-nums">{item.count}</Badge>}
          {item.manual && <div className="absolute top-1.5 right-1.5" onClick={(event) => event.stopPropagation()}>
            <FolderItemMenu item={item} onFolderAction={onFolderAction} trigger={<Button variant="secondary" size="icon-xs" className="bg-background/90 shadow-xs" aria-label={`Actions for folder ${item.label}`}><MoreVertical /></Button>} />
          </div>}
        </div>
        <div className="grid gap-0.5 p-3">
          <button type="button" className={cn("truncate text-left text-sm font-medium outline-none focus-visible:underline", item.count === 0 && "text-muted-foreground")} title={`Open ${item.label}`} onClick={(event) => { event.stopPropagation(); onOpenFolder(item); }}>{item.label}</button>
          <FolderItemMeta item={item} />
        </div>
      </article>;
    })}
    {documents.map((document) => {
      const selected = selection?.ids.includes(document.id);
      const active = activeId === document.id;

      return <article
        key={document.id}
        className={cn("group/card relative flex min-w-0 cursor-pointer flex-col overflow-hidden rounded-lg border bg-card transition-shadow hover:shadow-md", active && "ring-2 ring-ring/40", selected && "border-primary")}
        onClick={() => onOpen(document)}
      >
        <div className="relative grid aspect-4/3 place-items-center bg-muted/50">
          {isImage(document) && document.permissions?.download && document.status !== "deleted"
            ? <img src={documentPreviewUrl(document.id)} alt="" loading="lazy" className="size-full object-cover" />
            : <FileIcon document={document} size="large" />}
          {selection && <div className={cn("absolute top-2 left-2 rounded-sm bg-background/90 p-0.5 opacity-0 transition-opacity group-hover/card:opacity-100 focus-within:opacity-100 pointer-coarse:opacity-100", selected && "opacity-100")} onClick={(event) => event.stopPropagation()}>
            <Checkbox checked={selected} onCheckedChange={() => selection.toggle(document.id)} aria-label={`Select ${document.title}`} />
          </div>}
          <div className="absolute top-1.5 right-1.5" onClick={(event) => event.stopPropagation()}>
            <FileMenu
              document={document}
              onAction={(action) => onOpen(document, action)}
              trigger={<Button variant="secondary" size="icon-xs" className="bg-background/90 shadow-xs" aria-label={`Actions for ${document.title}`}><MoreVertical /></Button>}
            />
          </div>
          {(document.linked || document.newerVersionId) && <div className="absolute bottom-2 left-2 flex gap-1"><FileBadges document={{ linked: document.linked, newerVersionId: document.newerVersionId }} /></div>}
        </div>
        <div className="grid gap-0.5 p-3">
          <button type="button" className="truncate text-left text-sm font-medium outline-none focus-visible:underline" title={document.title} onClick={(event) => { event.stopPropagation(); onOpen(document); }}>{document.title}</button>
          <span className="truncate text-xs text-muted-foreground">{[document.type?.label, fileTypeLabel(document), formatBytes(document.fileSize)].filter(Boolean).join(" · ")}</span>
          {showPath && <LinkedRecord document={document} compact />}
        </div>
      </article>;
    })}
  </div>;
}

export function FileListSkeleton({ layout = "list", rows = 6 }) {
  if (layout === "grid") {
    return <div className="grid grid-cols-[repeat(auto-fill,minmax(150px,1fr))] gap-3" aria-busy="true" aria-label="Loading files">
      {Array.from({ length: rows }).map((_, index) => <div key={index} className="overflow-hidden rounded-lg border"><Skeleton className="aspect-4/3 rounded-none" /><div className="grid gap-2 p-3"><Skeleton className="h-4 w-3/4" /><Skeleton className="h-3 w-1/2" /></div></div>)}
    </div>;
  }

  return <div className="overflow-hidden rounded-lg border" aria-busy="true" aria-label="Loading files">
    <Skeleton className="h-10 rounded-none" />
    {Array.from({ length: rows }).map((_, index) => <div key={index} className="flex items-center gap-3 border-t px-3 py-3">
      <Skeleton className="size-4" />
      <Skeleton className="size-9 rounded-md" />
      <div className="grid flex-1 gap-1.5"><Skeleton className="h-4 w-1/2" /><Skeleton className="h-3 w-1/3" /></div>
      <Skeleton className="hidden h-4 w-16 sm:block" />
      <Skeleton className="h-4 w-20" />
    </div>)}
  </div>;
}
