import { ComponentArgs } from "@streamlit/component-v2-lib";
import {
  FC,
  ReactElement,
  useEffect,
  useRef,
  useCallback,
} from "react";
import Editor from '@toast-ui/editor';
import '@toast-ui/editor/dist/toastui-editor.css';
import '@toast-ui/editor/dist/theme/toastui-editor-dark.css';

export type MyComponentStateShape = {
  markdown: string;
};

export type MyComponentDataShape = {
  initialValue: string;
  height: string;
  initialEditType: 'markdown' | 'wysiwyg';
  previewStyle: 'tab' | 'vertical';
  theme: 'light' | 'dark';
  usageStatistics: boolean;
};

export type MyComponentProps = Pick<
  ComponentArgs<MyComponentStateShape, MyComponentDataShape>,
  "setStateValue"
> &
  MyComponentDataShape;

/**
 * Toast UI Editor component for Streamlit
 */
const MyComponent: FC<MyComponentProps> = ({
  initialValue,
  height,
  initialEditType,
  previewStyle,
  theme,
  usageStatistics,
  setStateValue,
}): ReactElement => {
  const editorRef = useRef<HTMLDivElement>(null);
  const editorInstance = useRef<Editor | null>(null);

  const createSaveButton = useCallback((currentTheme: 'light' | 'dark') => {
    const button = document.createElement('button');
    button.className = 'toastui-editor-toolbar-icons save';
    button.style.backgroundImage = 'none';
    button.style.margin = '0';
    button.style.display = 'flex';
    button.style.alignItems = 'center';
    button.style.justifyContent = 'center';
    
    // Set color based on theme
    button.style.color = currentTheme === 'dark' ? '#d5d5d5' : '#333';
    
    button.innerHTML = `
      <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 16" width="20" height="20">
        <path d="M14 3a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zM2 2a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2z"/>
        <path fill-rule="evenodd" d="M9.146 8.146a.5.5 0 0 1 .708 0L11.5 9.793l1.646-1.647a.5.5 0 0 1 .708.708l-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 0 1 0-.708"/>
        <path fill-rule="evenodd" d="M11.5 5a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-1 0v-4a.5.5 0 0 1 .5-.5"/>
        <path d="M3.56 11V7.01h.056l1.428 3.239h.774l1.42-3.24h.056V11h1.073V5.001h-1.2l-1.71 3.894h-.039l-1.71-3.894H2.5V11z"/>
      </svg>
    `;
    
    return button;
  }, []);

  // Initialize editor
  useEffect(() => {
    if (editorRef.current) {
      if (editorInstance.current) {
        editorInstance.current.destroy();
      }

      editorInstance.current = new Editor({
        el: editorRef.current,
        initialValue: initialValue || '',
        height: height || '500px',
        initialEditType: initialEditType || 'markdown',
        previewStyle: previewStyle || 'vertical',
        theme: theme || 'light',
        usageStatistics: usageStatistics !== undefined ? usageStatistics : true,
      });

      const saveButtonEl = createSaveButton(theme || 'light');
      
      // Define the save function
      saveButtonEl.onclick = () => {
        if (editorInstance.current) {
          const markdown = editorInstance.current.getMarkdown();
          setStateValue("markdown", markdown);
        }
      };

      // Insert the toolbar item using the method
      // We insert it at the end (new group) or specific position. 
      // Let's verify the default groups. Usually index 4 is after basic formatting.
      // Or we can just use push if we knew the API better, but insertToolbarItem is requested.
      // Let's place it at the end.
      // NOTE: TUI Editor Default toolbar groups:
      // 0: Heading, Bold, Italic, Strike
      // 1: HR, Quote
      // 2: UL, OL, Task
      // 3: Table, Image, Link
      // 4: Code, CodeBlock
      // So we want to insert at group index 5 (new group) or append to 4. 
      // Let's try appending to the end by using a high index or just creating a new group.
      
      editorInstance.current.insertToolbarItem(
        { groupIndex: 4, itemIndex: 2 }, // Append to the code/codeblock group
        {
          name: 'save',
          el: saveButtonEl,
          command: 'save',
          tooltip: 'Save Markdown'
        }
      );
    }

    return () => {
      if (editorInstance.current) {
        editorInstance.current.destroy();
        editorInstance.current = null;
      }
    };
  }, [height, initialEditType, previewStyle, theme, usageStatistics, createSaveButton, setStateValue]);

  return (
    <div style={{ marginBottom: '1rem' }}>
      <div ref={editorRef} />
    </div>
  );
};

export default MyComponent;