import { memo, useEffect, useRef } from "react";
import { parseMentions } from "@/lib/ir/parser";
import { MentionChip } from "@/lib/ir/mention-chip";

interface Props {
  /** Raw text content (may contain @[type:id:label] mentions). */
  content: string;
  /** Ref to the underlying textarea for scroll sync. */
  textareaRef: React.RefObject<HTMLTextAreaElement | null>;
}

/**
 * Absolutely-positioned overlay that mirrors the textarea's text layout
 * but renders @[mention] tokens as inline chips.
 *
 * Must be a sibling of the textarea inside a `relative` container.
 * Uses `pointer-events: none` so clicks pass through to the textarea.
 */
export const MentionTextareaOverlay = memo(function MentionTextareaOverlay({
  content,
  textareaRef,
}: Props) {
  const overlayRef = useRef<HTMLDivElement>(null);

  // Sync scroll position from textarea → overlay.
  useEffect(() => {
    const ta = textareaRef.current;
    const ov = overlayRef.current;
    if (!ta || !ov) return;

    const sync = () => {
      ov.scrollTop = ta.scrollTop;
      ov.scrollLeft = ta.scrollLeft;
    };

    ta.addEventListener("scroll", sync, { passive: true });
    // Also sync on resize (auto-grow).
    const ro = new ResizeObserver(sync);
    ro.observe(ta);

    return () => {
      ta.removeEventListener("scroll", sync);
      ro.disconnect();
    };
  }, [textareaRef]);

  const segments = parseMentions(content);

  return (
    <div
      ref={overlayRef}
      aria-hidden
      className="pointer-events-none absolute inset-x-0 top-0 z-0 overflow-hidden whitespace-pre-wrap break-words px-2.5 py-2 text-sm leading-relaxed [&_span]:align-baseline"
    >
      {segments.map((seg, i) => {
        if (seg.type === "mention" && seg.mention) {
          return (
            <MentionChip
              key={`${seg.mention.entityId}-${i}`}
              entityType={seg.mention.entityType}
              entityId={seg.mention.entityId}
              entityLabel={seg.mention.entityLabel}
            />
          );
        }
        // Render text as-is; the textarea underneath handles the same wrapping.
        return <span key={i}>{seg.content}</span>;
      })}
    </div>
  );
});

// ---------------------------------------------------------------------------
// Mention-aware backspace helper
// ---------------------------------------------------------------------------

/**
 * If `selectionStart` sits at the end of a complete `@[type:id:label]` token,
 * return the { start, end } byte-offsets of that token so the caller can
 * delete it as a whole.  Otherwise returns `null`.
 */
export function mentionAtCursor(
  text: string,
  selectionStart: number,
): { start: number; end: number } | null {
  if (selectionStart <= 0) return null;

  const before = text.slice(0, selectionStart);

  // Match the *last* complete mention that ends exactly at the cursor.
  const re = /@\[([a-z_]+):([^:\]]+):([^\]]+)\]/g;
  let last: { start: number; end: number } | null = null;
  let m: RegExpExecArray | null;

  while ((m = re.exec(before)) !== null) {
    const end = m.index + m[0].length;
    if (end === selectionStart) {
      last = { start: m.index, end };
    }
  }

  return last;
}
