

// imports
import clsx from 'clsx';
import { Combobox } from '@headlessui/react';
import { Transforms } from 'slate';
import React, { useRef, useEffect } from 'react';
import { useSelected, useFocused, ReactEditor } from 'slate-react';

// Component for rendering individual mentions
const Mention = ({ attributes, children, element }) => {
  // Check if the mention is selected or focused
  const selected = useSelected();
  const focused = useFocused();
  
  // Render the mention with appropriate styling
  return (
    <span
      {...attributes}
      contentEditable={false}
      data-cy={`mention-${(element.member?.user?.name || element.member?.user?.email || '').replace(' ', '-')}`}
      className={clsx(
        'inline-block rounded bg-primary-600/10 px-1 py-0.5 text-sm text-primary-600',
        selected && focused && 'ring-2 ring-primary-600'
      )}
    >
      @{element.member?.user?.name || element.member?.user?.email || ''}
      {children}
    </span>
  );
};

// Function to serialize mentions
export const serializeMention = ({ member }) => { 
  return `<mention:${member?.user?.id}>`
};

// Component for rendering the mention combobox
export const MentionCombobox = ({ items, onSelect, targetRange, editor, editorRef, selectedIndex }) => {
  // Reference to the combobox DOM element
  const ref = useRef(null);

  // Position the combobox based on the current selection
  useEffect(() => {
    if (targetRange && items.length > 0) {
      const el = ref.current;
      const domRange = ReactEditor.toDOMRange(editor, targetRange);
      const rect = domRange.getBoundingClientRect();
      const editorRect = editorRef.current.getBoundingClientRect();
      
      // Calculate the height of the combobox
      const comboboxHeight = el.offsetHeight;
      
      // Position the combobox above the text
      el.style.top = `${rect.top - editorRect.top - comboboxHeight}px`;
      el.style.left = `${rect.left - editorRect.left}px`;
    }
  }, [items.length, editor, targetRange, editorRef]);

  // Render the combobox
  return (
    <div ref={ref} className="absolute bottom-full z-10">
      <Combobox value={items[selectedIndex]} onChange={(id) => onSelect(items.find((i) => i.id === id))}>
        <div className="overflow-auto py-1 w-56 max-h-60 shadow-lg card">
          <Combobox.Options static>
            {items.map((item, index) => (
              <Combobox.Option
                key={item.id}
                value={item.id}
                className={clsx(
                  'relative cursor-default select-none py-2 px-4',
                  selectedIndex === index ? 'bg-blue-600 text-white' : ''
                )}
              >
                <span className={clsx('block truncate', selectedIndex === index && 'font-semibold')}>
                  @{item.user?.name || item.user?.email}
                </span>
              </Combobox.Option>
            ))}
          </Combobox.Options>
        </div>
      </Combobox>
    </div>
  );
};

// Function to insert a mention at the current selection
export const insertMention = (editor, member) => {
  const mention = {
    type: 'mention',
    member,
    children: [{ text: '' }],
  };
  Transforms.insertNodes(editor, mention);
  Transforms.move(editor);
};

// Custom plugin to handle mentions in the editor
export const withMentions = editor => {
  const { isInline, isVoid } = editor;

  // Override isInline to treat mentions as inline elements
  editor.isInline = element => {
    return element.type === 'mention' ? true : isInline(element);
  };

  // Override isVoid to treat mentions as void elements
  editor.isVoid = element => {
    return element.type === 'mention' ? true : isVoid(element);
  };

  return editor;
};

/**
 * export default mention
 */
export default Mention;