import React, { useEffect, useRef } from 'react';
import interact from 'interactjs';
import type { Annotation } from '@abcvideo/shared';

interface Props {
  annotations: Annotation[];
  currentTime: number;
  onUpdate: (id: string, pos: { x: number; y: number }) => void;
  onDelete: (id: string) => void;
  containerRef: React.RefObject<HTMLElement | null>;
}

function isVisible(a: Annotation, t: number): boolean {
  return a.type === 'memo' && t >= a.timeStart && t <= a.timeEnd;
}

export default function MemoOverlay({
  annotations,
  currentTime,
  onUpdate,
  onDelete,
}: Props) {
  const visible = annotations.filter((a) => isVisible(a, currentTime));

  return (
    <div className="absolute inset-0 pointer-events-none overflow-hidden">
      {visible.map((a) => (
        <MemoItem
          key={a.id}
          annotation={a}
          onUpdate={onUpdate}
          onDelete={onDelete}
        />
      ))}
    </div>
  );
}

function MemoItem({
  annotation: a,
  onUpdate,
  onDelete,
}: {
  annotation: Annotation;
  onUpdate: (id: string, pos: { x: number; y: number }) => void;
  onDelete: (id: string) => void;
}) {
  const elRef = useRef<HTMLDivElement>(null);
  // Track cumulative pixel offset from initial position
  const offsetRef = useRef({ x: 0, y: 0 });

  useEffect(() => {
    const el = elRef.current;
    if (!el) return;

    // Reset pixel offset when annotation changes position externally
    offsetRef.current = { x: 0, y: 0 };
    el.style.transform = 'translate(0px, 0px)';

    const interactable = interact(el).draggable({
      listeners: {
        move(event) {
          const parent = el.parentElement;
          if (!parent) return;
          const pw = parent.offsetWidth;
          const ph = parent.offsetHeight;
          offsetRef.current.x += event.dx;
          offsetRef.current.y += event.dy;
          el.style.transform = `translate(${offsetRef.current.x}px, ${offsetRef.current.y}px)`;
          const newX = Math.max(0, Math.min(100, a.position.x + (offsetRef.current.x / pw) * 100));
          const newY = Math.max(0, Math.min(100, a.position.y + (offsetRef.current.y / ph) * 100));
          onUpdate(a.id, { x: newX, y: newY });
        },
      },
    });

    return () => interactable.unset();
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [a.id]);

  return (
    <div
      ref={elRef}
      className="absolute pointer-events-auto cursor-move select-none"
      style={{
        left: `${a.position.x}%`,
        top: `${a.position.y}%`,
        willChange: 'transform',
      }}
    >
      <div
        className="rounded px-2 py-1 text-sm max-w-xs shadow-lg"
        style={{
          backgroundColor: a.style.backgroundColor ?? 'rgba(0,0,0,0.75)',
          color: a.style.color ?? '#ffffff',
          fontSize: `${a.style.fontSize ?? 14}px`,
        }}
      >
        <div className="flex items-start gap-1">
          <span className="flex-1">{a.text}</span>
          <button
            onClick={() => onDelete(a.id)}
            className="text-gray-400 hover:text-white text-xs leading-none ml-1 flex-shrink-0"
          >
            x
          </button>
        </div>
      </div>
    </div>
  );
}
