"use client";

import { useEffect, useRef, useState } from "react";
import Link from "next/link";
import { Archive, ArrowUpRight, Download, ExternalLink, Eye, FolderInput, Link2, Lock, Maximize2, MoreHorizontal, Pencil, Tag, Upload, X } from "lucide-react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from "@/components/ui/breadcrumb";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Separator } from "@/components/ui/separator";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { FactList } from "@/components/app/page";
import { cn } from "@/lib/utils";
import { EmptyState } from "../components/ui/page-states";
import { fileTypeLabel, formatBytes, formatDate, formatTime, isImage, ownerRecordPath, ownerTypeLabel, visibilityOptions } from "./file-utils";
import { FileIcon, FileMenu, StatusChip } from "./file-views";
import { documentDownloadUrl, documentPreviewUrl } from "./useDocuments";
import { ViaPortalBadge } from "../settings/portal/portal-access-ui";
import { GROUP_NODES } from "./file-nodes";
import { useDocumentUsages } from "./useFiles";

export function FileDetailsPlaceholder() {
  return <div className="grid h-full place-items-center p-4">
    <EmptyState compact icon={Eye} title="Select a file" detail="Preview, details, versions, and actions for the selected file appear here." />
  </div>;
}

// A button that stays focusable when disabled so its tooltip can explain why.
function ExplainedButton({ reason, children, ...props }) {
  if (!reason) return <Button {...props}>{children}</Button>;
  return <Tooltip>
    <TooltipTrigger asChild><span tabIndex={0} className={cn("inline-flex", props.className?.includes("w-full") && "w-full")}><Button {...props} disabled className={cn(props.className, "pointer-events-none")}>{children}</Button></span></TooltipTrigger>
    <TooltipContent className="max-w-64">{reason}</TooltipContent>
  </Tooltip>;
}

/**
 * Details for the active file: preview, actions, metadata, notes, and version history.
 * onAction(action) opens the edit / new version / move dialogs or the archive confirmation in the parent.
 * scrollToHistory is a counter; when it changes the version history scrolls into view.
 */
// onNavigate(node) opens a place in the explorer (the "Filed in" breadcrumb); omit it to show plain text.
export function FileDetails({ document, canMove = true, onAction, onClose, onZoom, onNavigate, scrollToHistory = 0, showClose = true }) {
  const historyRef = useRef(null);

  useEffect(() => {
    if (scrollToHistory) historyRef.current?.scrollIntoView({ behavior: "smooth", block: "start" });
  }, [scrollToHistory]);

  if (!document) return <FileDetailsPlaceholder />;

  const canDownload = document.permissions?.download;
  const archived = document.status === "deleted";
  const visibility = visibilityOptions.find((option) => option.value === document.visibility);
  const VisibilityIcon = visibility?.icon || Lock;
  const noDownloadReason = `Downloading requires the documents download permission${document.visibility === "restricted" ? " and security access for restricted files" : ""}.`;
  const versions = document.versionHistory || [];

  return <div className="grid gap-5 p-4">
    <div className="flex items-start gap-3">
      <FileIcon document={document} />
      <div className="grid min-w-0 flex-1 gap-0.5">
        <h3 className="truncate text-base font-semibold" title={document.title}>{document.title}</h3>
        <span className="text-xs text-muted-foreground">{formatBytes(document.fileSize)} · {fileTypeLabel(document)} · v{document.version}</span>
      </div>
      {showClose && <Button variant="ghost" size="icon-sm" onClick={onClose} aria-label="Close details"><X /></Button>}
    </div>

    <FilePreview document={document} onZoom={onZoom} />

    {document.newerVersionId && <Alert>
      <Upload />
      <AlertTitle>Newer version available</AlertTitle>
      <AlertDescription className="grid gap-2">
        <span>This is an older version. Records linked to it keep pointing here until someone switches them.</span>
        <Button variant="outline" size="sm" className="justify-self-start" onClick={() => onAction("newer")}>Open the newest version</Button>
      </AlertDescription>
    </Alert>}

    {archived
      ? <Alert><Archive /><AlertDescription>This file is archived. Its metadata and version history stay visible for audit; downloads are disabled.</AlertDescription></Alert>
      : <div className="grid gap-2">
        {canDownload
          ? <Button asChild className="w-full"><a href={document.previewable ? documentPreviewUrl(document.id) : documentDownloadUrl(document.id)} target={document.previewable ? "_blank" : undefined} rel="noopener"><ExternalLink /> Open file</a></Button>
          : <ExplainedButton className="w-full" reason={noDownloadReason}><Lock /> Open file</ExplainedButton>}
        <div className="flex gap-2">
          {canDownload
            ? <Button asChild variant="outline" className="flex-1"><a href={documentDownloadUrl(document.id)}><Download /> Download</a></Button>
            : <div className="flex-1"><ExplainedButton variant="outline" className="w-full" reason={noDownloadReason}><Download /> Download</ExplainedButton></div>}
          {document.permissions?.update && <Button variant="outline" size="icon" onClick={() => onAction("edit")} aria-label="Edit details"><Pencil /></Button>}
          <FileMenu
            document={document}
            canMove={canMove}
            onAction={onAction}
            trigger={<Button variant="outline" size="icon" aria-label={`More actions for ${document.title}`}><MoreHorizontal /></Button>}
          />
        </div>
        {!canDownload && <p className="text-xs text-muted-foreground">{noDownloadReason}</p>}
      </div>}

    <Separator />

    <section className="grid gap-2" aria-label="Filed in">
      <div className="flex items-center justify-between gap-2">
        <h4 className="text-sm font-semibold">Filed in</h4>
        {canMove && document.permissions?.move && !archived && <Button variant="link" size="sm" className="h-auto p-0 text-xs" onClick={() => onAction("move")}><FolderInput className="size-3" /> Move</Button>}
      </div>
      <FiledIn document={document} onNavigate={onNavigate} />
    </section>

    <UsedIn document={document} />

    <Separator />

    <section className="grid gap-3" aria-label="File details">
      <h4 className="text-sm font-semibold">Details</h4>
      <FactList columns={2} className="sm:grid-cols-2" items={[
        ["Category", <span key="category" className="inline-flex flex-wrap items-center gap-1.5"><Tag className="size-3.5 text-muted-foreground" />{document.type?.label || "Uncategorized"}{document.permissions?.update && !archived && <Button variant="link" size="sm" className="h-auto p-0 text-xs" onClick={() => onAction("category")}>Change</Button>}</span>],
        ["Belongs to", <span key="owner" className="grid"><span>{ownerRecordPath(document.owner) || document.owner?.url ? <Link href={ownerRecordPath(document.owner) || document.owner.url} className="hover:underline">{document.owner?.label || "Unknown"}</Link> : document.owner?.label || "Unknown"}</span><span className="text-xs font-normal capitalize text-muted-foreground">{ownerTypeLabel(document)}</span></span>],
        ["Visibility", <Tooltip key="visibility"><TooltipTrigger asChild><span className="inline-flex cursor-help items-center gap-1.5"><VisibilityIcon className="size-3.5 text-muted-foreground" />{visibility?.label || document.visibility}</span></TooltipTrigger>{visibility?.description && <TooltipContent className="max-w-64">{visibility.description}</TooltipContent>}</Tooltip>],
        ["Version", <span key="version" className="inline-flex items-center gap-1.5">v{document.version} <StatusChip status={document.status} /></span>],
        ["Size", formatBytes(document.fileSize)],
        ["Type", <span key="type" className="grid"><span>{fileTypeLabel(document)}</span><span className="truncate text-xs font-normal text-muted-foreground">{document.mimeType}</span></span>],
        ["Uploaded by", document.viaPortal
          ? <span key="uploader" className="grid justify-items-start gap-1"><span>{document.viaPortal.by?.name || document.viaPortal.by || "Portal user"}</span><ViaPortalBadge via={document.viaPortal} verb="Uploaded" /></span>
          : document.uploadedBy?.name || "Unknown"],
        ["Uploaded at", `${formatDate(document.uploadedAt)}, ${formatTime(document.uploadedAt)}`],
        ["Original file", <span key="original" className="break-all">{document.originalFilename}</span>],
      ]} />
      {visibility?.description && <p className="text-xs text-muted-foreground">{visibility.description}</p>}
    </section>

    <Separator />

    <section className="grid gap-2" aria-label="Notes">
      <h4 className="text-sm font-semibold">Notes</h4>
      {document.notes
        ? <p className="text-sm whitespace-pre-line">{document.notes}</p>
        : <p className="text-xs text-muted-foreground">No notes. {document.permissions?.update && !archived && <Button variant="link" size="sm" className="h-auto p-0 text-xs" onClick={() => onAction("edit")}>Add a note</Button>}</p>}
    </section>

    <Separator />

    <section className="grid scroll-mt-4 gap-2" ref={historyRef} aria-label="Version history">
      <div className="flex items-baseline justify-between gap-2">
        <h4 className="text-sm font-semibold">Version history</h4>
        <span className="text-xs text-muted-foreground">{versions.length} {document.type ? "in this category" : versions.length === 1 ? "version" : "versions"}</span>
      </div>
      <VersionHistory document={document} />
      {document.permissions?.supersede && !archived && <Button variant="outline" size="sm" className="justify-self-start" onClick={() => onAction("supersede")}><Upload /> Upload new version</Button>}
    </section>
  </div>;
}

function FilePreview({ document, onZoom }) {
  const [failed, setFailed] = useState(false);
  const canPreview = document.previewable && document.permissions?.download && document.status !== "deleted" && !failed;

  useEffect(() => { setFailed(false); }, [document.id]);

  if (!canPreview) {
    return <div className="grid aspect-[4/3] place-items-center gap-2 rounded-lg border border-dashed bg-muted/40 p-4 text-center">
      <div className="grid justify-items-center gap-2">
        <FileIcon document={document} size="large" />
        <span className="text-xs text-muted-foreground">{failed ? "Preview could not load." : !document.permissions?.download ? "Preview needs download access." : document.status === "deleted" ? "Archived files cannot be previewed." : `No preview for ${fileTypeLabel(document) === "FILE" ? "this" : fileTypeLabel(document)} files.`}</span>
      </div>
    </div>;
  }

  return <div className="group/preview relative aspect-[4/3] overflow-hidden rounded-lg border bg-muted/40">
    {isImage(document)
      ? <img src={documentPreviewUrl(document.id)} alt={`Preview of ${document.title}`} onError={() => setFailed(true)} className="size-full object-contain" />
      : <iframe src={`${documentPreviewUrl(document.id)}#toolbar=0&navpanes=0&view=FitH`} title={`Preview of ${document.title}`} tabIndex={-1} className="size-full bg-background" />}
    <div className="absolute top-2 right-2 flex gap-1">
      <Button variant="secondary" size="icon-sm" className="shadow-sm" onClick={onZoom} aria-label="Enlarge preview" title="Enlarge preview"><Maximize2 /></Button>
      <Button variant="secondary" size="icon-sm" className="shadow-sm" asChild><a href={documentPreviewUrl(document.id)} target="_blank" rel="noopener" aria-label="Open in new tab" title="Open in new tab"><ExternalLink /></a></Button>
    </div>
  </div>;
}

export function Lightbox({ document, onClose }) {
  return <Dialog open onOpenChange={(open) => { if (!open) onClose(); }}>
    <DialogContent className="flex h-[calc(100dvh-2rem)] max-w-[calc(100vw-2rem)] flex-col gap-3 p-4 sm:max-w-[calc(100vw-2rem)]">
      <DialogHeader className="flex-row items-center justify-between gap-3 pr-8 text-left">
        <div className="grid min-w-0">
          <DialogTitle className="truncate text-base">{document.title}</DialogTitle>
          <DialogDescription className="truncate">{document.originalFilename}</DialogDescription>
        </div>
        {document.permissions?.download && <Button asChild variant="outline" size="sm"><a href={documentDownloadUrl(document.id)}><Download /> Download</a></Button>}
      </DialogHeader>
      <div className="min-h-0 flex-1 overflow-hidden rounded-md border bg-muted/40">
        {isImage(document)
          ? <img src={documentPreviewUrl(document.id)} alt={`Preview of ${document.title}`} className="size-full object-contain" />
          : <iframe src={documentPreviewUrl(document.id)} title={`Preview of ${document.title}`} className="size-full bg-background" />}
      </div>
    </DialogContent>
  </Dialog>;
}

function VersionHistory({ document }) {
  const versions = document.versionHistory || [];

  if (!versions.length) return <p className="text-xs text-muted-foreground">No version history yet.</p>;

  return <ol className="grid gap-1.5">
    {versions.map((version) => {
      const current = version.id === document.id;
      return <li key={version.id} className={cn("flex items-center gap-3 rounded-md border p-2", current && "border-primary/40 bg-accent/50")}>
        <span className="grid size-8 shrink-0 place-items-center rounded-md bg-muted text-xs font-semibold tabular-nums">v{version.version}</span>
        <div className="grid min-w-0 flex-1">
          <span className="truncate text-sm font-medium">{version.title}</span>
          <span className="truncate text-xs text-muted-foreground">{formatBytes(version.fileSize)} · {formatDate(version.uploadedAt)}{current ? " · this file" : ""}</span>
        </div>
        <StatusChip status={version.status} />
        {version.status !== "deleted" && document.permissions?.download && <Button variant="ghost" size="icon-sm" asChild><a href={documentDownloadUrl(version.id)} aria-label={`Download version ${version.version}`} title={`Download v${version.version}`}><Download /></a></Button>}
      </li>;
    })}
  </ol>;
}

// Breadcrumb of where the file is filed (buyer › PO › shipment › folder), clickable inside the explorer.
function FiledIn({ document, onNavigate }) {
  const path = (document.path || []).filter((item) => !GROUP_NODES.includes(item.node) || item.node === "organization" || item.node === "unfiled");
  // The path already ends with the manual folder crumbs when the file sits in one; do not repeat the folder.
  const folder = path.some((item) => item.kind === "folder") ? "" : document.folder?.name;

  if (!path.length) return <p className="text-sm">{document.owner?.label || "Unknown record"}{folder ? ` › ${folder}` : ""}</p>;

  return <Breadcrumb>
    <BreadcrumbList className="text-sm">
      {path.map((item, index) => {
        const last = index === path.length - 1 && !folder;
        return <span key={`${item.node}-${index}`} className="contents">
          {index > 0 && <BreadcrumbSeparator />}
          <BreadcrumbItem>
            {last || !onNavigate ? <BreadcrumbPage className={cn(!last && "font-normal text-muted-foreground")}>{item.label}</BreadcrumbPage>
              : <BreadcrumbLink asChild><button type="button" onClick={() => onNavigate(item.node, item.folder)}>{item.label}</button></BreadcrumbLink>}
          </BreadcrumbItem>
        </span>;
      })}
      {folder && <><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>{folder}</BreadcrumbPage></BreadcrumbItem></>}
    </BreadcrumbList>
  </Breadcrumb>;
}

// Records that reference this file (handover rows, evidence, inspection reports…), with links by code.
function UsedIn({ document }) {
  const usages = useDocumentUsages(document.usedIn || document.usages ? document.id : null, document.usages);
  if (!usages?.length) return null;

  return <section className="grid gap-2" aria-label="Used in">
    <h4 className="text-sm font-semibold">Used in · {usages.length}</h4>
    <ul className="grid gap-1">
      {usages.map((usage, index) => <li key={`${usage.code}-${usage.field}-${index}`} className="flex min-w-0 items-center gap-2 text-sm">
        <Link2 className="size-3.5 shrink-0 text-muted-foreground" />
        {usage.url
          ? <Link href={usage.url} className="min-w-0 shrink-0 truncate font-medium hover:underline">{usage.code || usage.label}</Link>
          : <span className="min-w-0 shrink-0 truncate font-medium">{usage.code || usage.label}</span>}
        {usage.field && <span className="min-w-0 truncate text-xs text-muted-foreground">{usage.field}</span>}
        {usage.url && <ArrowUpRight className="ml-auto size-3.5 shrink-0 text-muted-foreground" />}
      </li>)}
    </ul>
  </section>;
}
