"use client";

import { Arrow, Circle, Line, Rect } from "react-konva";
import type Konva from "konva";

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

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

export function ShapeLayerNode({
  layer,
  onSelect,
  onDragEnd,
  onTransformEnd,
  registerNode,
}: ShapeLayerNodeProps) {
  const { shape, fill, stroke, strokeWidth, cornerRadius } = getShapeProps(
    layer.props
  );

  const commonProps = {
    rotation: layer.rotation,
    opacity: layer.opacity,
    draggable: true as const,
    onMouseDown: (event: Konva.KonvaEventObject<MouseEvent>) => {
      event.cancelBubble = true;
      onSelect();
    },
    onTap: (event: Konva.KonvaEventObject<TouchEvent>) => {
      event.cancelBubble = true;
      onSelect();
    },
    onDragEnd: (event: Konva.KonvaEventObject<DragEvent>) => {
      onDragEnd(event.target.x(), event.target.y());
    },
    onTransformEnd: (event: Konva.KonvaEventObject<Event>) => {
      onTransformEnd(event.target);
    },
  };

  if (shape === "circle") {
    const radius = Math.min(layer.width, layer.height) / 2;
    return (
      <Circle
        ref={(node) => registerNode(layer.id, node)}
        x={layer.x + layer.width / 2}
        y={layer.y + layer.height / 2}
        radius={radius}
        fill={fill}
        stroke={strokeWidth > 0 ? stroke : undefined}
        strokeWidth={strokeWidth > 0 ? strokeWidth : undefined}
        {...commonProps}
      />
    );
  }

  if (shape === "line") {
    return (
      <Line
        ref={(node) => registerNode(layer.id, node)}
        x={layer.x}
        y={layer.y}
        points={[0, 0, layer.width, layer.height]}
        stroke={stroke}
        strokeWidth={Math.max(strokeWidth, 2)}
        lineCap="round"
        {...commonProps}
      />
    );
  }

  if (shape === "arrow") {
    return (
      <Arrow
        ref={(node) => registerNode(layer.id, node)}
        x={layer.x}
        y={layer.y + layer.height / 2}
        points={[0, 0, layer.width, 0]}
        fill={fill}
        stroke={stroke}
        strokeWidth={Math.max(strokeWidth, 2)}
        pointerLength={12}
        pointerWidth={12}
        {...commonProps}
      />
    );
  }

  return (
    <Rect
      ref={(node) => registerNode(layer.id, node)}
      x={layer.x}
      y={layer.y}
      width={layer.width}
      height={layer.height}
      fill={fill}
      stroke={strokeWidth > 0 ? stroke : undefined}
      strokeWidth={strokeWidth > 0 ? strokeWidth : undefined}
      cornerRadius={cornerRadius}
      {...commonProps}
    />
  );
}
