import { BLOCK_SELECTORS } from '../config/constants';

export default function(editor) {
  let customStyles = [];

  editor.ui.registry.addMenuButton("tdstyles", {
    text: "Styles",
    tooltip: "Custom Styles",
    onSetup: (api) => {
      const updateButtonText = () => {
        const selection = editor.selection;
        const selectedNode = selection.getNode();
        const parents = editor.dom.getParents(selectedNode);
        
        // First check for block styles using formatter
        const activeBlockStyle = customStyles.find(style => 
          editor.formatter.match('block-style-' + style.name)
        );
        if (activeBlockStyle) {
          api.setText(activeBlockStyle.title);
          return;
        }
        
        // Then check for block styles using classes
        const blockElm = parents.find(parent => editor.dom.is(parent));
        if (blockElm) {
          const activeBlockStyleByClass = customStyles.find(style => 
            style.classes.some(className => editor.dom.hasClass(blockElm, className))
          );
          if (activeBlockStyleByClass) {
            api.setText(activeBlockStyleByClass.title);
            return;
          }
        }
        
        // Then check for inline styles
        const activeInlineStyle = customStyles.find(style => 
          editor.formatter.match('inline-style-' + style.name)
        );
        if (activeInlineStyle) {
          api.setText(activeInlineStyle.title);
          return;
        }
        
        // If no active style, show default text
        api.setText('Custom Styles');
      };

      // Update on selection change
      editor.on('NodeChange', updateButtonText);
      
      // Initial update
      updateButtonText();

      // Cleanup
      return () => {
        editor.off('NodeChange', updateButtonText);
      };
    },
    fetch: (callback) => {
      const items = customStyles.map(style => {
        const selection = editor.selection;
        const selectedNode = selection.getNode();
        const parents = editor.dom.getParents(selectedNode);
        
        let indicator = '';
        
        // First check if block element has the style classes
        const blockElm = parents.find(parent => editor.dom.is(parent));
        if (blockElm) {
          const hasBlockClass = style.classes.some(className => 
            editor.dom.hasClass(blockElm, className)
          );
          if (hasBlockClass) {
            indicator = '● ';  // Show active for block
          }
        }
        
        // If block is not active, check for inline
        if (!indicator) {
          const isInlineActive = editor.formatter.match('inline-style-' + style.name);
          if (isInlineActive) {
            indicator = '◉ ';  // Show active for inline
          }
        }
        
        return {
          type: 'menuitem',
          text: indicator + style.title,
          onAction: () => {
            editor.execCommand('applyCustomStyle', style);
          },
        };
      });
      callback(items);
    }
  });

  // Custom command to apply appropriate format based on selection
  editor.addCommand('applyCustomStyle', function (style) {
    const selection = editor.selection;
    const selectedNode = selection.getNode();
    let selectedContent = selection.getContent({ format: 'text' });

    // If no selection, get the word at cursor position
    if (!selectedContent.trim()) {
      const cursorPosition = selection.getRng();
      const textNode = cursorPosition.startContainer;
      
      if (textNode.nodeType === 3) { // Text node
        const text = textNode.textContent;
        const offset = cursorPosition.startOffset;
        
        // Find word boundaries
        const wordStart = text.lastIndexOf(' ', offset - 1) + 1;
        const wordEnd = text.indexOf(' ', offset);
        const word = text.substring(
          wordStart,
          wordEnd === -1 ? text.length : wordEnd
        ).trim();
        
        if (word) {
          // Create a new range for the word
          const range = editor.dom.createRng();
          range.setStart(textNode, wordStart);
          range.setEnd(textNode, wordEnd === -1 ? text.length : wordEnd);
          selection.setRng(range);
          selectedContent = word;
        }
      }
    }

    // Get all parent elements and find the first one that matches our selector
    const parents = editor.dom.getParents(selectedNode);
    const blockElm = parents.find(parent => editor.dom.is(parent, BLOCK_SELECTORS));

    if (!blockElm) return;

    const blockText = blockElm.textContent;
    const isBlockSelection = selectedContent.trim() === blockText.trim();
    const formatName = isBlockSelection ? 'block-style-' + style.name : 'inline-style-' + style.name;

    // Check if the style is already applied
    if (editor.formatter.match(formatName)) {
      // If it's active, just remove it
      editor.formatter.remove(formatName);
      if (!isBlockSelection) {
        // Get all spans in the selection
        const spans = editor.dom.select('span', selection.getNode());
        spans.forEach(span => {
          // If the span has no classes, remove it
          if (!span.className) {
            editor.dom.remove(span, true);
          }
        });
      }
    } else {
      // If it's not active, first remove any existing custom styles
      customStyles.forEach(s => {
        if (isBlockSelection) {
          editor.formatter.remove('block-style-' + s.name);
        } else {
          editor.formatter.remove('inline-style-' + s.name);
        }
      });
      // Then apply the new style
      if (isBlockSelection) {
        editor.formatter.apply(formatName);
      } else {
        // Check if the block already has this class
        const hasBlockClass = style.classes.some(className => 
          editor.dom.hasClass(blockElm, className)
        );
        if (!hasBlockClass) {
          editor.formatter.apply(formatName);
        }
      }
    }
  });

  // Register the custom styles
  editor.on('init', () => {
    customStyles.forEach(style => {
      // Register each style with its specific selector and class
      editor.formatter.register('block-style-' + style.name, {
        selector: style.selector,
        classes: style.classes,
        exact: style.exact,
        deep: style.deep,
        split: style.split,
        remove: style.remove,
        group: 'custom-styles' // This ensures only one style can be active at a time
      });
      editor.formatter.register('inline-style-' + style.name, {
        inline: 'span',
        classes: style.classes,
        group: 'custom-styles' // This ensures only one style can be active at a time
      });
    });
  });

  return {
    initStyles: (style_formats) => {
      customStyles = style_formats;
    }
  };
} 