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

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

    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;
    const cornerRadius = getObjectBorderRadius(obj.borderRadius);
    const clipFunc = createRoundedRectClipFunc(width, height, cornerRadius);

    const dragBoundFunc =
        draggable && hasStageBounds
            ? (pos: { x: number; y: number }) =>
                  clampPositionToStage(
                      pos.x,
                      pos.y,
                      width,
                      height,
                      stageWidth!,
                      stageHeight!,
                  )
            : undefined;

    const handleDragEnd = (e: Konva.KonvaEventObject<DragEvent>) => {
        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 });
    };

    const handleClick = (e: Konva.KonvaEventObject<MouseEvent>) => {
        const node = cornerRadius > 0 ? groupRef.current : shapeRef.current;
        if (node) {
            onSelect(obj.id, node, e);
        }
    };

    if (cornerRadius > 0) {
        return (
            <Group
                ref={groupRef}
                id={obj.id}
                name="canvas-object"
                x={obj.x}
                y={obj.y}
                rotation={obj.rotation || 0}
                draggable={draggable}
                clipFunc={clipFunc}
                dragBoundFunc={dragBoundFunc}
                onClick={handleClick}
                onDragEnd={handleDragEnd}
            >
                <KonvaImage
                    x={0}
                    y={0}
                    image={image}
                    width={width}
                    height={height}
                />
                {isSelected && (
                    <Rect
                        x={0}
                        y={0}
                        width={width}
                        height={height}
                        stroke="#3b82f6"
                        strokeWidth={3}
                        cornerRadius={cornerRadius}
                        listening={false}
                    />
                )}
            </Group>
        );
    }

    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={dragBoundFunc}
            onClick={handleClick}
            onDragEnd={handleDragEnd}
        />
    );
};

export default ImageObject;
