"use client";

import { useEffect, useState } from "react";
import Image, { type StaticImageData } from "next/image";

interface CmsPreviewMessage {
  type?: string;
  cmsItems?: Array<{
    section_name: string;
    input_name_en: string;
    value: unknown;
  }>;
}

interface CmsPreviewImageProps {
  /** section_name of the CMS row this image comes from (e.g. "hero_section") */
  sectionName: string;
  /** input_name_en of the CMS row this image comes from (e.g. "cover_image") */
  inputNameEn: string;
  /** Server-rendered image (a real CMS url, or the local static fallback) */
  initialSrc: string | StaticImageData;
  alt: string;
  className?: string;
  fill?: boolean;
  priority?: boolean;
  quality?: number;
  /** Index into the row's value array, for repeater fields (e.g. reviews) */
  itemIndex?: number;
  /** Sub-field to read off the array item, for repeater fields (e.g. "image") */
  itemField?: string;
}

function extractUrl(value: unknown): string | undefined {
  if (!value || typeof value !== "object") return undefined;
  const url = (value as { url?: unknown }).url;
  return typeof url === "string" && url ? url : undefined;
}

/**
 * Renders a CMS-sourced image that live-updates while this page is embedded
 * in the dashboard's website editor preview iframe, reflecting an unsaved
 * image pick (even a local data-URL preview) instantly, without ever
 * touching the database. Outside the preview iframe (real site visitors) it
 * just renders `initialSrc` through next/image as normal.
 *
 * Once a live override arrives it switches to a plain `<img>` — next/image's
 * optimizer refuses upstream hosts that resolve to a private/loopback IP
 * (true of the local backend in dev) and a data: URL override doesn't need
 * optimizing anyway, so there's nothing to gain from routing it back through
 * next/image.
 */
export default function CmsPreviewImage({
  sectionName,
  inputNameEn,
  initialSrc,
  alt,
  className,
  fill = true,
  priority,
  quality,
  itemIndex,
  itemField,
}: CmsPreviewImageProps) {
  const [overrideUrl, setOverrideUrl] = useState<string | null>(null);

  useEffect(() => {
    if (typeof window === "undefined" || window.self === window.top) return;

    function handleMessage(event: MessageEvent<CmsPreviewMessage>) {
      const data = event.data;
      if (
        !data ||
        data.type !== "CMS_PREVIEW_UPDATE" ||
        !Array.isArray(data.cmsItems)
      ) {
        return;
      }

      const item = data.cmsItems.find(
        (i) =>
          i.section_name === sectionName && i.input_name_en === inputNameEn,
      );
      if (!item) return;

      let raw: unknown = item.value;
      if (typeof itemIndex === "number") {
        if (!Array.isArray(raw)) return;
        raw = raw[itemIndex];
        if (itemField && raw && typeof raw === "object") {
          raw = (raw as Record<string, unknown>)[itemField];
        }
      }

      const url = extractUrl(raw);
      if (url) {
        setOverrideUrl(url);
      }
    }

    window.addEventListener("message", handleMessage);
    return () => window.removeEventListener("message", handleMessage);
  }, [sectionName, inputNameEn, itemIndex, itemField]);

  if (overrideUrl) {
    return (
      // eslint-disable-next-line @next/next/no-img-element
      <img
        src={overrideUrl}
        alt={alt}
        className={
          fill ? `absolute inset-0 h-full w-full ${className || ""}` : className
        }
      />
    );
  }

  return (
    <Image
      src={initialSrc}
      alt={alt}
      fill={fill}
      className={className}
      priority={priority}
      quality={quality}
      unoptimized={typeof initialSrc === "string"}
    />
  );
}
