import { useEditor } from "@/modules/editor";
import { Alignment } from "@ckeditor/ckeditor5-alignment";
import { Bold, Italic } from "@ckeditor/ckeditor5-basic-styles";
import { InlineEditor } from "@ckeditor/ckeditor5-editor-inline";
import { Essentials } from "@ckeditor/ckeditor5-essentials";
import { FontColor, FontFamily, FontSize } from "@ckeditor/ckeditor5-font";
import { Link } from "@ckeditor/ckeditor5-link";
import { Paragraph } from "@ckeditor/ckeditor5-paragraph";
import { css } from "@linaria/core";
import { defineComponent, onUnmounted, watch, watchEffect } from "vue";
import { string } from "vue-types";
import { useCompData } from ".";
import { View } from "../View";

export const Component = defineComponent({
  props: {
    compId: string().def(""),
  },
  setup(props) {
    const comp = useCompData(props.compId);
    const { store, actions } = useEditor();
    const config = {
      language: "zh-cn",
      plugins: [
        Essentials,
        Bold,
        Italic,
        Link,
        Paragraph,
        FontColor,
        FontSize,
        FontFamily,
        Alignment,
      ],
      fontSize: {
        options: [12, 14, 16, 18, 20, 24, 28, 32, 38, 42, 46, 52, 60],
      },
      toolbar: {
        items: [
          // "undo",
          // "redo",
          // "|",
          "fontColor",
          "fontsize",
          "bold",
          "italic",
          "|",
          "alignment",
          // "|",
          // "link",
        ],
      },
    };

    let editorInstance: InlineEditor;

    watch(
      () => comp.value,
      () => {
        if (!store.textEditingState) {
          editorInstance?.setData(comp.value);
        }
      }
    );

    let blurCanceler: any = null;
    watchEffect(() => {
      blurCanceler?.();
      if (store.currCompId === props.compId) {
        blurCanceler = blurHandle();
      }
    });

    onUnmounted(() => {
      blurCanceler?.();
    });

    function blurHandle() {
      function blur(e: MouseEvent) {
        const target = e.target as HTMLElement;
        if (
          editorInstance.ui.view.toolbar.element?.contains(target) ||
          comp.$el.contains(target)
        ) {
          return;
        }
        store.setTextEditingState(false);
        actions.submitUpdate();
      }
      document.addEventListener("mousedown", blur, {
        capture: true,
      });
      return () => {
        document.removeEventListener("mousedown", blur, { capture: true });
      };
    }

    return () => (
      <View
        class={[textStyle, store.currCompId === props.compId && "drag-disable"]}
        compId={props.compId}
      >
        <ckeditor
          class={textStyle}
          editor={InlineEditor}
          onFocus={() => {
            store.setTextEditingState(true);
          }}
          onInput={(value: any) => {
            if (editorInstance && comp.value !== value) {
              actions.updateCompData(comp, "value", value);
            }
          }}
          onReady={(editor: InlineEditor) => {
            editorInstance = editor;
            editor.setData(comp.value);
            if (store.isPreview) {
              editor.enableReadOnlyMode("editor");
            }
          }}
          config={config}
        />
      </View>
    );
  },
});

const textStyle = css`
  font-size: 12px;
  color: #666;
  p {
    margin: 0;
  }
  .ck.ck-editor__editable_inline {
    cursor: text;
    overflow: hidden;
    pointer-events: none;

    > :last-child,
    > :first-child {
      margin-top: 0;
      margin-bottom: 0;
    }
  }

  &.drag-disable {
    .ck.ck-editor__editable_inline {
      pointer-events: auto;
    }
  }
`;
