import { useEffect, useRef } from "react";
import { Image as KonvaImage } from "react-konva";
import Konva from "konva";
import useImage from "use-image";
import type { ShapeProps } from "./types";
import { clampPositionToStage } from "../../utils/stageBounds";

const ImageObject = ({
    obj,
    isSelected,
    onSelect,
    onUpdate,
    draggable,
    stageWidth,
    stageHeight,
    onImageReady,
}: ShapeProps) => {
    const [image, status] = useImage(obj.imageUrl || "");
    const shapeRef = useRef<Konva.Image>(null);

    // Notify parent (ObjectRenderer) as soon as the image is decoded and ready.
    // This lets the masked group re-cache itself after the image content appears.
    useEffect(() => {
        if (status === "loaded" && onImageReady) {
            onImageReady();
        }
    }, [status, onImageReady]);

    if (!image) return null;

    const width = obj.width || image.width;
    const height = obj.height || image.height;
    const hasStageBounds = stageWidth != null && stageHeight != null;

    return (
        <KonvaImage
            ref={shapeRef}
            id={obj.id}
            name="canvas-object"
            x={obj.x}
            y={obj.y}
            image={image}
            width={width}
            height={height}
            stroke={isSelected ? "#3b82f6" : undefined}
            strokeWidth={isSelected ? 3 : 0}
            rotation={obj.rotation || 0}
            draggable={draggable}
            dragBoundFunc={
                draggable && hasStageBounds
                    ? (pos) =>
                          clampPositionToStage(
                              pos.x,
                              pos.y,
                              width,
                              height,
                              stageWidth!,
                              stageHeight!,
                          )
                    : undefined
            }
            onClick={(e) => {
                if (shapeRef.current) {
                    onSelect(obj.id, shapeRef.current, e);
                }
            }}
            onDragEnd={(e) => {
                const node = e.target;
                let x = node.x();
                let y = node.y();
                if (hasStageBounds) {
                    ({ x, y } = clampPositionToStage(
                        x,
                        y,
                        width,
                        height,
                        stageWidth!,
                        stageHeight!,
                    ));
                    node.position({ x, y });
                }
                onUpdate(obj.id, { x, y });
            }}
        />
    );
};

export default ImageObject;

