import Image from "next/image";
import Link from "next/link";

type ClampOpts = { maxIntrinsic: number };

/**
 * Clamps intrinsic w/h while preserving aspect ratio.
 * This helps prevent Next/Image from treating a tiny thumbnail as a large asset.
 */
function clampDims(w: number, h: number, { maxIntrinsic }: ClampOpts) {
  const W = Math.max(1, w);
  const H = Math.max(1, h);
  const maxSide = Math.max(W, H);
  if (maxSide <= maxIntrinsic) return { w: W, h: H };

  const scale = maxIntrinsic / maxSide;
  return {
    w: Math.max(1, Math.round(W * scale)),
    h: Math.max(1, Math.round(H * scale)),
  };
}

export type ArtworkImageCardProps = {
  href: string;
  src: string;
  alt: string;

  /**
   * Provide real dimensions if you have them.
   * For tile mode, we still pass intrinsic sizes, but clamp them.
   */
  width?: number;
  height?: number;

  /**
   * tile: uses `fill` + container aspect ratio (best for masonry/grid)
   * hero: uses width/height when available (best for single page)
   */
  mode?: "tile" | "hero";

  /**
   * For tile mode only.
   * Example: "4 / 3" or `${w} / ${h}`
   */
  aspectRatio?: string;

  className?: string;
  imageClassName?: string;

  /**
   * Controls intrinsic clamp for thumbnails:
   * you asked: “max the double of 160” => 320 default.
   */
  maxThumbIntrinsic?: number;

  sizes?: string;
  priority?: boolean;
  style?: React.CSSProperties;
  linkClassName?: string;
};

export function ArtworkImageCard({
  href,
  src,
  alt,
  width,
  height,
  mode = "tile",
  aspectRatio = "4 / 3",
  className,
  imageClassName,
  maxThumbIntrinsic = 320,
  sizes,
  priority,
  style,
}: ArtworkImageCardProps) {
  const w = width ?? 0;
  const h = height ?? 0;

  const isHero = mode === "hero";
  const hasDims = w > 0 && h > 0;

  // Clamp only for non-hero (thumbnail-like) usage
  const clamped = !isHero && hasDims ? clampDims(w, h, { maxIntrinsic: maxThumbIntrinsic }) : null;

  return (
    <div
      style={style}
      className={[
        "group rounded-lg overflow-hidden bg-background relative",
        // IMPORTANT: put the border here so the --dom hover works again
        "border border-transparent transition-colors duration-150 hover:border-(--dom)",
        "hover:shadow-lg transition-shadow",
        className ?? "",
      ].join(" ")}
    >
      <div
        className="relative w-full bg-muted items-center justify-center"
        style={mode === "tile" ? { aspectRatio } : undefined}
      >
        <Link href={href} className="block">
          {isHero ? (
            <Image
              src={src}
              alt={alt}
              // If we have dimensions, use them; otherwise fallback to fill.
              width={hasDims ? w : undefined}
              height={hasDims ? h : undefined}
              fill={!hasDims}
              className={["object-cover transition duration-300", imageClassName ?? ""].join(" ")}
              sizes={sizes}
              priority={priority}
              quality={100}
            />
          ) : (
            <Image
              src={src}
              alt={alt}
              // Pass clamped intrinsic sizes when possible
              width={clamped?.w ?? 320}
              height={clamped?.h ?? 240}
              className={["w-full h-full object-cover select-none", imageClassName ?? ""].join(" ")}
              loading={priority ? "eager" : "lazy"}
              sizes={sizes}
              priority={priority}
              quality={100}
            />
          )}
        </Link>
      </div>
    </div>
  );
}
