import getCaretCoordinates from "textarea-caret";
import { useEffect, useRef, useState } from "react";
import type { EditorRefActions } from "./Editor";

interface Position {
  top: number;
  left: number;
}

interface Props {
  editorRef: React.RefObject<EditorRefActions | null>;
}

export const FloatingFormatToolbar: React.FC<Props> = ({ editorRef }) => {
  const [pos, setPos] = useState<Position | null>(null);
  const mouseDown = useRef(false);

  useEffect(() => {
    const onMouseDown = () => {
      mouseDown.current = true;
    };

    const onMouseUp = () => {
      mouseDown.current = false;
      const editor = editorRef.current?.getEditor();
      if (!editor || document.activeElement !== editor) {
        setPos(null);
        return;
      }
      const start = editor.selectionStart;
      const end = editor.selectionEnd;
      if (start === end) {
        setPos(null);
        return;
      }

      const rect = editor.getBoundingClientRect();
      const caret = getCaretCoordinates(editor, end);

      setPos({
        top: rect.top + caret.top - editor.scrollTop - 44,
        left: Math.min(
          Math.max(rect.left + caret.left - 80, 8),
          window.innerWidth - 220,
        ),
      });
    };

    const onSelectionChange = () => {
      if (mouseDown.current) return;
      const editor = editorRef.current?.getEditor();
      if (!editor || document.activeElement !== editor) {
        setPos(null);
        return;
      }
      if (editor.selectionStart === editor.selectionEnd) {
        setPos(null);
      }
    };

    const onKeyUp = () => {
      const editor = editorRef.current?.getEditor();
      if (!editor || document.activeElement !== editor) return;
      if (editor.selectionStart === editor.selectionEnd) {
        setPos(null);
        return;
      }
      const rect = editor.getBoundingClientRect();
      const caret = getCaretCoordinates(editor, editor.selectionEnd);
      setPos({
        top: rect.top + caret.top - editor.scrollTop - 44,
        left: Math.min(
          Math.max(rect.left + caret.left - 80, 8),
          window.innerWidth - 220,
        ),
      });
    };

    document.addEventListener("mousedown", onMouseDown);
    document.addEventListener("mouseup", onMouseUp);
    document.addEventListener("selectionchange", onSelectionChange);
    document.addEventListener("keyup", onKeyUp);
    return () => {
      document.removeEventListener("mousedown", onMouseDown);
      document.removeEventListener("mouseup", onMouseUp);
      document.removeEventListener("selectionchange", onSelectionChange);
      document.removeEventListener("keyup", onKeyUp);
    };
  }, [editorRef]);

  if (!pos) return null;

  const apply = (prefix: string, suffix: string) => {
    editorRef.current?.insertText("", prefix, suffix);
    setPos(null);
  };

  const applyLink = () => {
    const editor = editorRef.current;
    if (!editor) return;
    editor.insertText("", "[", "](url)");
    setPos(null);
  };

  return (
    <div
      className="fixed z-50 flex items-center gap-0.5 px-1.5 py-1 bg-popover border border-border rounded-lg shadow-lg select-none"
      style={{ top: pos.top, left: pos.left }}
      onMouseDown={(e) => e.preventDefault()}
    >
      <button
        className="px-2 py-0.5 text-sm font-bold hover:bg-accent rounded transition-colors"
        title="Bold (Ctrl+B)"
        onClick={() => apply("**", "**")}
      >
        B
      </button>
      <button
        className="px-2 py-0.5 text-sm italic hover:bg-accent rounded transition-colors"
        title="Italic (Ctrl+I)"
        onClick={() => apply("_", "_")}
      >
        I
      </button>
      <button
        className="px-2 py-0.5 text-sm line-through hover:bg-accent rounded transition-colors"
        title="Strikethrough"
        onClick={() => apply("~~", "~~")}
      >
        S
      </button>
      <div className="w-px h-4 bg-border mx-0.5" />
      <button
        className="px-2 py-0.5 text-xs font-mono hover:bg-accent rounded transition-colors"
        title="Inline code"
        onClick={() => apply("`", "`")}
      >
        {"<>"}
      </button>
      <button
        className="px-2 py-0.5 text-sm hover:bg-accent rounded transition-colors"
        title="Link (Ctrl+K)"
        onClick={applyLink}
      >
        🔗
      </button>
    </div>
  );
};
