"use client";

import { AlertTriangle, Download, RefreshCw } from "lucide-react";

import { cn } from "@/lib/utils/cn";

/**
 * Error panel rendered by {@link PaperPreviewPane} when the preview
 * cannot be loaded. Maps known backend error codes to friendly copy:
 *
 * <ul>
 *   <li>{@code MANUSCRIPT_NOT_FOUND} — 404 from ReviewerPaperController
 *       when the paper row or storage blob is missing</li>
 *   <li>{@code MANUSCRIPT_PREVIEW_UNAVAILABLE} — 503 from the PDF
 *       sanitization pipeline (OpenPDF strip / watermark failure)</li>
 *   <li>{@code FORBIDDEN} — 403 when the caller is not an assigned
 *       reviewer on this paper</li>
 * </ul>
 *
 * <p>Unknown codes fall back to a generic message while still
 * surfacing the server-provided message (if any) below it.
 */
export interface PaperPreviewErrorProps {
  /** Error code from the backend ApiError body, or a client-side label. */
  code?: string | null;
  /** Raw error message from the backend, used as a subtitle fallback. */
  message?: string | null;
  /** Invoked when the user clicks the retry button. */
  onRetry?: () => void;
  /** Invoked when the user clicks the download fallback button. */
  onDownload?: () => void;
  className?: string;
}

interface ErrorCopy {
  title: string;
  body: string;
}

function copyFor(code: string | null | undefined): ErrorCopy {
  switch (code) {
    case "MANUSCRIPT_NOT_FOUND":
      return {
        title: "Manuscript not found",
        body: "The manuscript file for this paper could not be located. Please contact the editor.",
      };
    case "MANUSCRIPT_PREVIEW_UNAVAILABLE":
      return {
        title: "Preview not available",
        body: "We couldn't prepare a preview for this manuscript. Please try downloading it instead, or contact the editor.",
      };
    case "FORBIDDEN":
      return {
        title: "Access denied",
        body: "You are not authorized to view this manuscript.",
      };
    default:
      return {
        title: "Failed to load preview",
        body: "Something went wrong while loading the manuscript preview.",
      };
  }
}

export function PaperPreviewError({
  code,
  message,
  onRetry,
  onDownload,
  className,
}: PaperPreviewErrorProps) {
  const { title, body } = copyFor(code);
  const isForbidden = code === "FORBIDDEN";

  return (
    <div
      className={cn(
        "flex h-full min-h-[320px] w-full flex-col items-center justify-center gap-4 rounded-lg border border-gray-200 bg-white p-6 text-center shadow-sm",
        className
      )}
    >
      <div className="rounded-full bg-amber-100 p-3 text-amber-600">
        <AlertTriangle className="h-6 w-6" aria-hidden="true" />
      </div>
      <div className="max-w-md space-y-1">
        <h3 className="text-base font-semibold text-gray-900">{title}</h3>
        <p className="text-sm text-gray-600">{body}</p>
        {message && message !== body ? (
          <p className="text-xs text-gray-500">{message}</p>
        ) : null}
      </div>
      {!isForbidden ? (
        <div className="flex flex-col gap-2 sm:flex-row">
          {onRetry ? (
            <button
              type="button"
              onClick={onRetry}
              className="inline-flex items-center gap-2 rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50"
            >
              <RefreshCw className="h-4 w-4" aria-hidden="true" />
              Retry
            </button>
          ) : null}
          {onDownload ? (
            <button
              type="button"
              onClick={onDownload}
              className="inline-flex items-center gap-2 rounded-md bg-indigo-600 px-4 py-2 text-sm font-semibold text-white shadow hover:bg-indigo-700"
            >
              <Download className="h-4 w-4" aria-hidden="true" />
              Download instead
            </button>
          ) : null}
        </div>
      ) : null}
    </div>
  );
}

export default PaperPreviewError;
