"use client";

import { Image, Rect } from "react-konva";
import type Konva from "konva";
import useImage from "use-image";

import { getImageProps } from "@/lib/studio-layer-props";
import type { Layer } from "@/lib/studio-types";

export interface ImageLayerNodeProps {
  layer: Layer;
  onSelect: () => void;
  onDragEnd: (x: number, y: number) => void;
  onTransformEnd: (node: Konva.Node) => void;
  registerNode: (id: string, node: Konva.Node | null) => void;
}

function getFlipOffsets(
  layer: Layer,
  flipHorizontal: boolean,
  flipVertical: boolean
) {
  return {
    offsetX: flipHorizontal ? layer.width : 0,
    offsetY: flipVertical ? layer.height : 0,
    scaleX: flipHorizontal ? -1 : 1,
    scaleY: flipVertical ? -1 : 1,
  };
}

function ImageLayerPlaceholder({
  layer,
  onSelect,
  onDragEnd,
  onTransformEnd,
  registerNode,
}: ImageLayerNodeProps) {
  const { cornerRadius } = getImageProps(layer.props);

  return (
    <Rect
      ref={(node) => registerNode(layer.id, node)}
      x={layer.x}
      y={layer.y}
      width={layer.width}
      height={layer.height}
      rotation={layer.rotation}
      opacity={layer.opacity}
      cornerRadius={cornerRadius}
      fill="#E5E7EB"
      stroke="#9CA3AF"
      strokeWidth={1}
      dash={[8, 4]}
      draggable
      onMouseDown={(event) => {
        event.cancelBubble = true;
        onSelect();
      }}
      onTap={(event) => {
        event.cancelBubble = true;
        onSelect();
      }}
      onDragEnd={(event) => onDragEnd(event.target.x(), event.target.y())}
      onTransformEnd={(event) => onTransformEnd(event.target)}
    />
  );
}

function ImageLayerWithSrc({
  layer,
  src,
  onSelect,
  onDragEnd,
  onTransformEnd,
  registerNode,
}: ImageLayerNodeProps & { src: string }) {
  const [image] = useImage(src, "anonymous");
  const { flipHorizontal, flipVertical, cornerRadius } = getImageProps(
    layer.props
  );
  const flip = getFlipOffsets(layer, flipHorizontal, flipVertical);

  if (!image) {
    return (
      <ImageLayerPlaceholder
        layer={layer}
        onSelect={onSelect}
        onDragEnd={onDragEnd}
        onTransformEnd={onTransformEnd}
        registerNode={registerNode}
      />
    );
  }

  return (
    <Image
      ref={(node) => registerNode(layer.id, node)}
      alt=""
      image={image}
      x={layer.x}
      y={layer.y}
      width={layer.width}
      height={layer.height}
      rotation={layer.rotation}
      opacity={layer.opacity}
      cornerRadius={cornerRadius}
      {...flip}
      draggable
      onMouseDown={(event) => {
        event.cancelBubble = true;
        onSelect();
      }}
      onTap={(event) => {
        event.cancelBubble = true;
        onSelect();
      }}
      onDragEnd={(event) => onDragEnd(event.target.x(), event.target.y())}
      onTransformEnd={(event) => onTransformEnd(event.target)}
    />
  );
}

export function ImageLayerNode(props: ImageLayerNodeProps) {
  const { src } = getImageProps(props.layer.props);
  if (!src) {
    return <ImageLayerPlaceholder {...props} />;
  }
  return <ImageLayerWithSrc {...props} src={src} />;
}
