import { $generateHtmlFromNodes } from '@lexical/html';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import { useEffect } from 'react';

/**
 * Removes inline styles and unnecessary span elements from HTML.
 */
function cleanHtml(htmlString: string): string {
  const parser = new DOMParser();
  const doc = parser.parseFromString(htmlString, 'text/html');

  // Remove all style attributes.
  const elementsWithStyle = doc.querySelectorAll('[style]');
  elementsWithStyle.forEach((element) => {
    element.removeAttribute('style');
  });

  // Remove all spans by replacing them with their content.
  const spans = Array.from(doc.querySelectorAll('span'));
  spans.forEach((span) => {
    const parent = span.parentNode;
    if (parent) {
      while (span.firstChild) {
        parent.insertBefore(span.firstChild, span);
      }
      parent.removeChild(span);
    }
  });

  return doc.body.innerHTML;
}

function CleanHtmlOnChangePlugin({ onChange }: { onChange?: (html: string) => void }) {
  const [editor] = useLexicalComposerContext();

  useEffect(() => {
    return editor.registerUpdateListener(({ editorState }) => {
      editorState.read(() => {
        const htmlString = $generateHtmlFromNodes(editor, null);
        const cleanedHtml = cleanHtml(htmlString);

        if (onChange) {
          onChange(cleanedHtml);
        }
      });
    });
  }, [editor, onChange]);

  return null;
}

export default CleanHtmlOnChangePlugin;
