import { useEffect, useState } from "react";
import { invoke } from "@tauri-apps/api/core";
import { ImageOff } from "lucide-react";
import { useToast } from "./Toast";

interface Props {
  /** Text-to-image prompt. Changing it triggers a new generation. */
  prompt: string | null;
  /** Bump to force a regenerate with the same prompt. */
  nonce?: number;
  className?: string;
  /** Aspect for the placeholder box while loading/empty. */
  aspect?: string;
}

/**
 * Generates and caches an image for `prompt` via the Ollama image model.
 * Results are cached on disk by the backend, so re-renders are instant.
 * macOS-only: on other OSes the backend returns an error and we show a
 * placeholder instead of a confusing timeout.
 */
export function GeneratedImage({ prompt, nonce = 0, className = "", aspect = "aspect-square" }: Props) {
  const [dataUrl, setDataUrl] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [unsupported, setUnsupported] = useState(false);
  const [expanded, setExpanded] = useState(false);
  const { addToast } = useToast();

  useEffect(() => {
    if (!prompt) return;
    let cancelled = false;
    setLoading(true);
    setUnsupported(false);
    invoke<string>("generate_image", { req: { prompt } })
      .then((url) => {
        if (!cancelled) setDataUrl(url);
      })
      .catch((e) => {
        const msg = String(e);
        if (!cancelled) {
          if (msg.includes("macOS-only")) setUnsupported(true);
          else addToast(`Image failed: ${msg}`, "error");
        }
      })
      .finally(() => !cancelled && setLoading(false));
    return () => {
      cancelled = true;
    };
  }, [prompt, nonce]);

  if (!prompt) return null;

  const box = `relative ${aspect} w-full rounded-lg overflow-hidden border border-[var(--color-border-glass)] bg-[var(--color-bg-deep)] flex items-center justify-center ${className}`;

  if (unsupported) {
    return (
      <div className={box}>
        <div className="flex flex-col items-center gap-1 text-[var(--color-text-dim)]">
          <ImageOff size={20} />
          <span className="text-[10px] text-center px-2">Image gen is macOS-only via Ollama</span>
        </div>
      </div>
    );
  }

  if (loading) {
    return (
      <div className={box}>
        <div className="absolute inset-0 skeleton" />
        <span className="relative text-[10px] text-[var(--color-text-dim)]">Painting…</span>
      </div>
    );
  }

  return dataUrl ? (
    <div className={box}>
      <img src={dataUrl} alt={prompt} className="w-full h-full object-cover cursor-zoom-in" onClick={() => setExpanded(true)} />
      {expanded && (
        <div
          className="fixed inset-0 z-[60] bg-black/80 flex items-center justify-center p-8"
          onClick={() => setExpanded(false)}
          aria-label="Close image preview"
        >
          <img src={dataUrl} alt={prompt} className="max-w-full max-h-full rounded-lg object-contain" />
        </div>
      )}
    </div>
  ) : null;
}