"use client";

import Image from "next/image";
import { useEffect, useRef, useState } from "react";
import { cn } from "@/lib/utils";

type Props = {
  /** The catalogue/admin photo (may be missing or 404 on the media host). */
  src?: string | null;
  /** A representative industry photo used when `src` is missing or fails. */
  fallbackSrc: string;
  alt: string;
  sizes: string;
  className?: string;
  priority?: boolean;
  /**
   * How the *catalogue* photo is fitted. `contain` (default) is for product
   * shots — the whole item stays visible, never sliced at the sides; put it in
   * a square frame so the photo fills it edge to edge. `cover` is for
   * banner-style images. The fallback photo is always `cover`.
   */
  fit?: "contain" | "cover";
};

/**
 * Fills a `relative` frame with a picture, falling back to an industry photo
 * when the real one is missing or broken — including a 404 that happened
 * before hydration, when React's `onError` was not yet attached.
 */
export default function ProductTileImage({ src, fallbackSrc, alt, sizes, className, priority, fit = "contain" }: Props) {
  const initial = src && src.trim() ? src : null;
  const [failed, setFailed] = useState(!initial);
  const ref = useRef<HTMLImageElement>(null);

  useEffect(() => {
    setFailed(!initial);
  }, [initial]);

  // The browser may have given up on the image before React hydrated.
  useEffect(() => {
    const img = ref.current;
    if (img && initial && img.complete && img.naturalWidth === 0) setFailed(true);
  }, [initial]);

  const showingFallback = failed || !initial;

  return (
    <Image
      ref={ref}
      key={showingFallback ? "fallback" : "photo"}
      src={showingFallback ? fallbackSrc : (initial as string)}
      alt={alt}
      fill
      sizes={sizes}
      priority={priority}
      onError={() => setFailed(true)}
      className={cn(
        showingFallback || fit === "cover" ? "object-cover" : "bg-white object-contain",
        className
      )}
    />
  );
}
