import React, { useMemo, useCallback } from 'react';
import { createEditor, Descendant, Editor } from 'slate';
import {
  Slate,
  Editable,
  withReact as withReactPlugin,
  useSlate,
  RenderElementProps,
  RenderLeafProps,
} from 'slate-react';
import { withHistory } from 'slate-history';
import { CustomEditor, CustomTextKey } from './custom-types';
import {
  BlockButton,
  Button,
  Icon,
  Leaf,
  SlateRenderElement,
  Toolbar,
  withHtml,
} from './slate-editor-components';

export interface RichTextEditorProps {
  value: Descendant[];
  onChange: (value: Descendant[]) => void;
  placeholder?: string;
  readOnly?: boolean;
  className?: string;
}

interface MarkButtonProps {
  format: CustomTextKey;
  icon: string;
}

const isMarkActive = (editor: CustomEditor, format: CustomTextKey) => {
  const marks = Editor.marks(editor);
  return marks ? marks[format] === true : false;
};

const toggleMark = (editor: CustomEditor, format: CustomTextKey) => {
  const isActive = isMarkActive(editor, format);

  if (isActive) {
    Editor.removeMark(editor, format);
  } else {
    Editor.addMark(editor, format, true);
  }
};

const MarkButton = ({ format, icon }: MarkButtonProps) => {
  const editor = useSlate();
  return (
    <Button
      active={isMarkActive(editor, format)}
      onPointerDown={(event: any) => event.preventDefault()}
      onClick={() => toggleMark(editor, format)}
    >
      <Icon>{icon}</Icon>
    </Button>
  );
};

const RichTextEditor: React.FC<RichTextEditorProps> = ({
  value,
  onChange,
  placeholder = 'Type something...',
  readOnly = false,
  className = '',
}) => {
  const editor = useMemo(() => withHtml(withHistory(withReactPlugin(createEditor()))), []);

  const renderElement = useCallback(
    (props: RenderElementProps) => <SlateRenderElement {...props} />,
    []
  );

  //   const renderElement = useCallback((props: any) => {
  //   switch (props.element.type) {
  //     case "block-quote":
  //       return <blockquote {...props.attributes}>{props.children}</blockquote>;
  //     case "bulleted-list":
  //       return <ul {...props.attributes}>{props.children}</ul>;
  //     case "list-item":
  //       return <li {...props.attributes}>{props.children}</li>;
  //     case "numbered-list":
  //       return <ol {...props.attributes}>{props.children}</ol>;
  //     default:
  //       return <p {...props.attributes}>{props.children}</p>;
  //   }
  // }, []);

  const renderLeaf = useCallback((props: RenderLeafProps) => <Leaf {...props} />, []);

  return (
    <div className={`bg-gray-800 rounded-lg border border-gray-700 ${className}`}>
      <Slate editor={editor} initialValue={value} onChange={onChange}>
        <Toolbar>
          <MarkButton format="bold" icon="format_bold" />
          <MarkButton format="italic" icon="format_italic" />
          <MarkButton format="underline" icon="format_underlined" />
          <MarkButton format="code" icon="code" />
          <BlockButton format="heading-one" icon="looks_one" />
          <BlockButton format="heading-two" icon="looks_two" />
          <BlockButton format="block-quote" icon="format_quote" />
          <BlockButton format="numbered-list" icon="format_list_numbered" />
          <BlockButton format="bulleted-list" icon="format_list_bulleted" />
          <BlockButton format="left" icon="format_align_left" />
          <BlockButton format="center" icon="format_align_center" />
          <BlockButton format="right" icon="format_align_right" />
          <BlockButton format="justify" icon="format_align_justify" />
        </Toolbar>
        <Editable
          renderElement={renderElement}
          renderLeaf={renderLeaf}
          placeholder={placeholder}
          readOnly={readOnly}
          className="min-h-[200px] p-4 text-gray-100 focus:outline-none"
          spellCheck
        />
      </Slate>
    </div>
  );
};

export default RichTextEditor;
