<template>
  <div ref="container" class="editor" :class="{ readonly }" />
</template>
<style lang="scss">
@font-face {
  font-family: "Virgil";
  src: url("https://unpkg.com/@excalidraw/excalidraw@0.16.1/dist/excalidraw-assets/Virgil.woff2");
}
@font-face {
  font-family: "Cascadia";
  src: url("https://unpkg.com/@excalidraw/excalidraw@0.16.1/dist/excalidraw-assets/Cascadia.woff2");
}
.editor {
  &.readonly {
    .cdx-input {
      border: 0 none;
      -webkit-box-shadow: none;
      box-shadow: none;
      padding: 0;
    }

    .image-tool__caption {
      font-style: italic;
      text-align: center;
    }
    .cdx-quote {
      border-left: 3px solid #222;
      padding: 0.5rem 1rem;
      margin-bottom: .5rem;
    }
    .cdx-quote__text {
      border-radius: 0;
      min-height: auto;
      margin-bottom: 0;
    }
    .cdx-quote__caption {
      font-style: italic;

      &:not(:empty) {
        margin-top: 10px;
      }

      &:not(:empty)::before {
        content: '— ';
        padding-right: 20px;
      }
      &:after {
        display: none !important;
      }
    }
  }
}
</style>
<script>
import { Vue, Model, Component, Watch, Prop } from 'vue-property-decorator';
import EditorJS from '@editorjs/editorjs';
import Header from '@editorjs/header';
import Embed from '@editorjs/embed';
import Quote from '@editorjs/quote';
import Marker from '@editorjs/marker';
import LinkTool from '@editorjs/link';
import Delimiter from '@editorjs/delimiter';
import InlineCode from '@editorjs/inline-code';
import Image from '@editorjs/image';
import Table from '@editorjs/table';
import AttachesTool from '@editorjs/attaches';
import NestedList from '@editorjs/nested-list';
import editorjsCodecup from './tools/highlightcode/codecup';
import Drawing from './tools/drawing/drawing';
import Bpmn from './tools/bpmn/bpmn';
import cloneDeep from 'lodash/cloneDeep';

export default @Component({
  components: {
  }
})
class itfEditor extends Vue {
  @Model('input') value;
  @Prop(Boolean) readonly;
  @Prop(String) imageEndpoint;
  @Prop(String) fetchEndpoint;
  @Prop(String) bearerToken;
  @Prop({ type: String, default: function() { return this.$t('workflows.clickToEdit'); } }) startTypingText;
  @Prop({ default: () => ({}) }) tools;

  editor = null;

  isIgnoreReload = false;

  mounted() {
    this.onValueChanged(this.value);
  }

  beforeDestroy() {
    if (this.editor && this.editor.destroy) {
      this.editor.destroy();
    }
  }

  @Watch('value')
  onValueChanged(val, oldVal) {
    if (this.editor && (this.isIgnoreReload || JSON.stringify(val && val.blocks) === JSON.stringify(oldVal && oldVal.blocks))) {
      return;
    }
    setTimeout(() => {
      this.initEditor();
    }, 200);
  }

  @Watch('readonly')
  onReadonlyChange(val, oldVal) {
    this.editor.readOnly.toggle(this.readonly);
  }

  initEditor() {
    if (!this.$refs.container) {
      return;
    }
    if (this.editor && this.editor.destroy) {
      this.editor.destroy();
    }
    this.$refs.container.innerHTML = '';
    const node = document.createElement('div');
    this.$refs.container.appendChild(node);

    this.editor = new EditorJS({
      tools: {
        header: Header,
        embed: Embed,
        quote: Quote,
        marker: Marker,
        code: editorjsCodecup,
        delimiter: Delimiter,
        drawing: {
          inlineToolbar: true,
          class: Drawing
        },
        bpmn: {
          inlineToolbar: true,
          class: Bpmn
        },
        // warning: Warning,
        table: {
          inlineToolbar: true,
          class: Table
        },
        inlineCode: {
          class: InlineCode,
          shortcut: 'CMD+SHIFT+M',
        },
        list: {
          class: NestedList,
          inlineToolbar: true,
          config: {
            defaultStyle: 'unordered'
          },
        },
        linkTool: {
          class: LinkTool,
          config: {
            endpoint: this.fetchEndpoint, // Your backend endpoint for url data fetching,
          }
        },
        attaches: {
          class: AttachesTool,
          config: {
            endpoint: this.imageEndpoint
          }
        },
        image: {
          class: Image,
          inlineToolbar: true,
          config: {
            endpoints: {
              byFile: this.imageEndpoint, // Your backend file uploader endpoint
              byUrl: this.fetchEndpoint, // Your endpoint that provides uploading by Url
            },
            additionalRequestHeaders: {
              Authorization: `Bearer ${this.bearerToken}`
            }
            /* actions: [
              {
                toggle: true,
                icon: '<svg width="256px" height="256px" viewBox="-32 -32 320 320" xmlns="http://www.w3.org/2000/svg"><g opacity="0.2"><rect x="72" y="56" width="112" height="56" rx="8"/></g><g opacity="0.2"><rect x="72" y="144" width="152" height="56" rx="8"/></g><path fill="currentColor" d="M216,136H80a16.01833,16.01833,0,0,0-16,16v40a16.01833,16.01833,0,0,0,16,16H216a16.01833,16.01833,0,0,0,16-16V152A16.01833,16.01833,0,0,0,216,136Zm0,56H80V152H216l.01025,39.99951ZM47.99414,39.99512v176a8,8,0,0,1-16,0v-176a8,8,0,0,1,16,0ZM80,120h96a16.01833,16.01833,0,0,0,16-16V64a16.01833,16.01833,0,0,0-16-16H80A16.01833,16.01833,0,0,0,64,64v40A16.01833,16.01833,0,0,0,80,120Zm0-56h96l.01025,39.99951L176,104H80Z"/></svg>\n',
                name: 'left',
                title: 'Left',
                action: (name) => {
                  console.info(name)
                }
              },
              {
                toggle: true,
                icon: '<svg width="256px" height="256px" viewBox="-32 -32 320 320" xmlns="http://www.w3.org/2000/svg"><g opacity="0.2"><rect x="64" y="56" width="128" height="56" rx="8"/></g><g opacity="0.2"><rect x="40" y="144" width="176" height="56" rx="8"/></g><path fill="currentColor" d="M208,136H136V120h48a16.01833,16.01833,0,0,0,16-16V64a16.01833,16.01833,0,0,0-16-16H136V31.99512a8,8,0,1,0-16,0V48H72A16.01833,16.01833,0,0,0,56,64v40a16.01833,16.01833,0,0,0,16,16h48v16H48a16.01833,16.01833,0,0,0-16,16v40a16.01833,16.01833,0,0,0,16,16h72v15.99512a8,8,0,0,0,16,0V208h72a16.01833,16.01833,0,0,0,16-16V152A16.01833,16.01833,0,0,0,208,136ZM72,64H184l.01025,39.99951L184,104H128.09668c-.03253-.00037-.064-.00488-.09668-.00488s-.06415.00451-.09668.00488H72ZM208,192H128.09668c-.03253-.00037-.064-.00488-.09668-.00488s-.06415.00451-.09668.00488H48V152H208l.01025,39.99951Z"/></svg>',
                name: 'centered',
                title: 'Centered'
              },
              {
                toggle: true,
                icon: '<svg width="256px" height="256px" viewBox="-32 -32 320 320" xmlns="http://www.w3.org/2000/svg"><g opacity="0.2"><rect x="72" y="56" width="112" height="56" rx="8" transform="translate(256 168) rotate(180)"/></g><g opacity="0.2"><rect x="32" y="144" width="152" height="56" rx="8"/></g><path fill="currentColor" d="M224.00586,39.99512v176a8,8,0,0,1-16,0v-176a8,8,0,0,1,16,0ZM192,64v40a16.01833,16.01833,0,0,1-16,16H80a16.01833,16.01833,0,0,1-16-16V64A16.01833,16.01833,0,0,1,80,48h96A16.01833,16.01833,0,0,1,192,64Zm-16,0H80v40h96Zm16,88v40a16.01833,16.01833,0,0,1-16,16H40a16.01833,16.01833,0,0,1-16-16V152a16.01833,16.01833,0,0,1,16-16H176A16.01833,16.01833,0,0,1,192,152Zm-16,0H40v40H176Z"/></svg>',
                name: 'right',
                title: 'Right'
              }
            ] */
          }
        },
        ...this.tools
      },
      readOnly: this.readonly,
      holder: node,
      data: cloneDeep(this.value || {}),
      // autofocus: true,
      minHeight: this.readonly ? 10 : 100,
      placeholder: this.startTypingText,

      onReady: () => {
        if (!this.readonly) {
          return;
        }
        const links = document.querySelectorAll('.codex-editor a');
        for (const link of links) {
          link.setAttribute('target', '_blank');
        }
      },
      onChange: async (api, event) => {
        if (!this.editor.save || this.readonly) {
          return;
        }
        this.isIgnoreReload = true;
        this.$emit('input', await this.editor.save());
        setTimeout(() => { this.isIgnoreReload = false; }, 200);
      }
    });
  }
}
</script>
