import { useState, useCallback, useEffect, useRef } from 'react';
import { type Editor } from '@tiptap/react';
import {
  Heading1, Heading2, Heading3, List, ListOrdered, CheckSquare,
  Code, Quote, Minus,
} from 'lucide-react';

interface SlashMenuProps { editor: Editor }

interface SlashItem {
  title: string;
  description: string;
  icon: React.ReactNode;
  action: () => void;
}

const items: SlashItem[] = [
  { title: 'Heading 1', description: 'Large heading', icon: <Heading1 className="size-4" />, action: () => {} },
  { title: 'Heading 2', description: 'Medium heading', icon: <Heading2 className="size-4" />, action: () => {} },
  { title: 'Heading 3', description: 'Small heading', icon: <Heading3 className="size-4" />, action: () => {} },
  { title: 'Bullet List', description: 'Unordered list', icon: <List className="size-4" />, action: () => {} },
  { title: 'Numbered List', description: 'Ordered list', icon: <ListOrdered className="size-4" />, action: () => {} },
  { title: 'Task List', description: 'Checklist', icon: <CheckSquare className="size-4" />, action: () => {} },
  { title: 'Code Block', description: 'Code with syntax highlighting', icon: <Code className="size-4" />, action: () => {} },
  { title: 'Blockquote', description: 'Quote or citation', icon: <Quote className="size-4" />, action: () => {} },
  { title: 'Divider', description: 'Horizontal rule', icon: <Minus className="size-4" />, action: () => {} },
];

export function SlashMenu({ editor }: SlashMenuProps) {
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState('');
  const [selectedIndex, setSelectedIndex] = useState(0);
  const menuRef = useRef<HTMLDivElement>(null);

  const filteredItems = query
    ? items.filter((item) => item.title.toLowerCase().includes(query.toLowerCase()))
    : items;

  const executeAction = useCallback((item: SlashItem) => {
    const { chain } = editor;
    const index = items.indexOf(item);
    const actions = [
      () => chain().focus().toggleHeading({ level: 1 }).run(),
      () => chain().focus().toggleHeading({ level: 2 }).run(),
      () => chain().focus().toggleHeading({ level: 3 }).run(),
      () => chain().focus().toggleBulletList().run(),
      () => chain().focus().toggleOrderedList().run(),
      () => chain().focus().toggleTaskList().run(),
      () => chain().focus().toggleCodeBlock().run(),
      () => chain().focus().toggleBlockquote().run(),
      () => chain().focus().setHorizontalRule().run(),
    ];
    actions[index]?.();
    setOpen(false);
    setQuery('');
  }, [editor]);

  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (!open) return;
      if (e.key === 'ArrowDown') { e.preventDefault(); setSelectedIndex((i) => (i + 1) % filteredItems.length); }
      if (e.key === 'ArrowUp') { e.preventDefault(); setSelectedIndex((i) => (i - 1 + filteredItems.length) % filteredItems.length); }
      if (e.key === 'Enter') { e.preventDefault(); executeAction(filteredItems[selectedIndex]!); }
      if (e.key === 'Escape') { setOpen(false); setQuery(''); }
    };
    document.addEventListener('keydown', handleKeyDown);
    return () => document.removeEventListener('keydown', handleKeyDown);
  }, [open, filteredItems, selectedIndex, executeAction]);

  useEffect(() => {
    setSelectedIndex(0);
  }, [query]);

  editor.on('selectionUpdate', () => {
    const { state } = editor;
    const { $from } = state.selection;
    const textBefore = $from.parent.textBetween(0, $from.parentOffset);
    const slashMatch = textBefore.match(/\/(\w*)$/);

    if (slashMatch) {
      setOpen(true);
      setQuery(slashMatch[1] ?? '');
    } else if (open) {
      setOpen(false);
      setQuery('');
    }
  });

  if (!open) return null;

  return (
    <div
      ref={menuRef}
      className="absolute z-50 w-72 bg-popover border rounded-lg shadow-lg overflow-hidden"
      style={{ top: '100%', left: 0 }}
    >
      <div className="p-1">
        {filteredItems.map((item, i) => (
          <button
            key={item.title}
            type="button"
            className={`flex items-center gap-3 w-full px-3 py-2 rounded text-left text-sm transition-colors ${
              i === selectedIndex ? 'bg-accent text-accent-foreground' : 'text-foreground'
            }`}
            onMouseDown={(e) => { e.preventDefault(); executeAction(item); }}
            onMouseEnter={() => setSelectedIndex(i)}
          >
            <span className="flex items-center justify-center size-8 rounded bg-muted text-muted-foreground">
              {item.icon}
            </span>
            <div>
              <div className="font-medium">{item.title}</div>
              <div className="text-xs text-muted-foreground">{item.description}</div>
            </div>
          </button>
        ))}
      </div>
    </div>
  );
}
