"use client";

import { useRef, useState, type PointerEvent as ReactPointerEvent } from "react";
import { X } from "lucide-react";
import { NodeViewWrapper } from "@tiptap/react";
import type { NodeViewProps } from "@tiptap/react";
import { getSticker } from "@/lib/notes/note-stickers";
import { StickerPickerButton } from "@/components/notes/sticker-picker";

function clamp(value: number, min: number, max: number) {
  return Math.min(max, Math.max(min, value));
}

export function StickerBlockView({ node, updateAttributes, editor, deleteNode }: NodeViewProps) {
  const stickerId = node.attrs.stickerId as string;
  const x = node.attrs.x as number;
  const y = node.attrs.y as number;
  const scale = node.attrs.scale as number;
  const editable = editor.isEditable;
  const sticker = getSticker(stickerId);

  const [live, setLive] = useState<{ x: number; y: number; scale: number } | null>(null);
  const liveRef = useRef<{ x: number; y: number; scale: number } | null>(null);

  const displayX = live?.x ?? x;
  const displayY = live?.y ?? y;
  const displayScale = live?.scale ?? scale;

  function handleDragPointerDown(e: ReactPointerEvent<HTMLDivElement>) {
    if (!editable) return;
    const container = e.currentTarget.closest(".tiptap") as HTMLElement | null;
    if (!container) return;
    e.preventDefault();
    e.stopPropagation();

    const containerRect = container.getBoundingClientRect();
    const startClientX = e.clientX;
    const startClientY = e.clientY;
    const startX = x;
    const startY = y;
    e.currentTarget.setPointerCapture(e.pointerId);

    function onMove(ev: PointerEvent) {
      const nextX = clamp(startX + ((ev.clientX - startClientX) / containerRect.width) * 100, 0, 100);
      const nextY = clamp(startY + ((ev.clientY - startClientY) / containerRect.height) * 100, 0, 100);
      liveRef.current = { x: nextX, y: nextY, scale };
      setLive(liveRef.current);
    }
    function onUp() {
      window.removeEventListener("pointermove", onMove);
      window.removeEventListener("pointerup", onUp);
      if (liveRef.current) updateAttributes({ x: liveRef.current.x, y: liveRef.current.y });
      liveRef.current = null;
      setLive(null);
    }
    window.addEventListener("pointermove", onMove);
    window.addEventListener("pointerup", onUp);
  }

  function handleResizePointerDown(e: ReactPointerEvent<HTMLDivElement>) {
    if (!editable) return;
    e.preventDefault();
    e.stopPropagation();

    const startClientY = e.clientY;
    const startScale = scale;
    e.currentTarget.setPointerCapture(e.pointerId);

    function onMove(ev: PointerEvent) {
      const delta = (startClientY - ev.clientY) / 80;
      const nextScale = clamp(startScale + delta, 0.5, 3);
      liveRef.current = { x, y, scale: nextScale };
      setLive(liveRef.current);
    }
    function onUp() {
      window.removeEventListener("pointermove", onMove);
      window.removeEventListener("pointerup", onUp);
      if (liveRef.current) updateAttributes({ scale: liveRef.current.scale });
      liveRef.current = null;
      setLive(null);
    }
    window.addEventListener("pointermove", onMove);
    window.addEventListener("pointerup", onUp);
  }

  return (
    <NodeViewWrapper
      className="!absolute select-none"
      style={{
        left: `${displayX}%`,
        top: `${displayY}%`,
        transform: `translate(-50%, -50%) scale(${displayScale})`,
        zIndex: 20,
        touchAction: "none",
      }}
      contentEditable={false}
    >
      <div className="group relative">
        <div
          onPointerDown={handleDragPointerDown}
          className="text-[40px] leading-none drop-shadow-[0_4px_10px_rgba(0,0,0,0.35)]"
          style={{ cursor: editable ? "grab" : "default" }}
        >
          {sticker.emoji}
        </div>

        {editable && (
          <>
            <button
              type="button"
              onClick={() => deleteNode()}
              className="absolute -right-2 -top-2 flex h-5 w-5 items-center justify-center rounded-full border border-border bg-card text-muted-foreground opacity-0 shadow transition-opacity hover:text-destructive group-hover:opacity-100"
            >
              <X className="h-3 w-3" />
            </button>

            <StickerPickerButton
              onSelect={(next) => updateAttributes({ stickerId: next.id })}
              trigger={(open) => (
                <button
                  type="button"
                  onClick={open}
                  title="Change sticker"
                  className="absolute -left-2 -bottom-2 flex h-5 w-5 items-center justify-center rounded-full border border-border bg-card text-[10px] text-muted-foreground opacity-0 shadow transition-opacity hover:text-foreground group-hover:opacity-100"
                >
                  ✎
                </button>
              )}
            />

            <div
              onPointerDown={handleResizePointerDown}
              title="Resize"
              className="absolute -bottom-2 -right-2 h-4 w-4 cursor-nwse-resize rounded-full border border-border bg-card opacity-0 shadow transition-opacity group-hover:opacity-100"
            />
          </>
        )}
      </div>
    </NodeViewWrapper>
  );
}
