text: import Vue from 'vue';
  import annotationMixin from './mixin';
  import HTTP from './http';
  import simpleShortcut from './filter';
  
  Vue.use(require('vue-shortkey'), {
    prevent: ['input', 'textarea'],
  });
  
  Vue.filter('simpleShortcut', simpleShortcut);
  
  Vue.component('annotator', {
    template: '<div @click="setSelectedRange">'
          + '         <p>This is a paragraph.</p>'
            + '       <span class="text-sequence"'
            + '            v-for="r in chunks"'
            + '            v-if="id2label[r.label]"'
            + '            v-bind:class="{tag: id2label[r.label].text_color}"'
            + '            v-bind:style="{ color: id2label[r.label].text_color, backgroundColor: id2label[r.label].background_color }"'
            + '       >{{ [...text].slice(r.start_offset, r.end_offset).join(\'\') }}<button class="delete is-small"'
            + '                            v-if="id2label[r.label].text_color"'
            + '                            @click="removeLabel(r)"></button></span>'
            + '  </div>',
    props: {
      labels: Array, // [{id: Integer, color: String, text: String}]
      text: String,
      entityPositions: Array, // [{'startOffset': 10, 'endOffset': 15, 'label_id': 1}]
    },
    data() {
      return {
        startOffset: 0,
        endOffset: 0,
      };
    },
  
    methods: {
      setSelectedRange() {
        let start;
        let end;
        if (window.getSelection) {
          const range = window.getSelection().getRangeAt(0);
          const preSelectionRange = range.cloneRange();
          preSelectionRange.selectNodeContents(this.$el);
          preSelectionRange.setEnd(range.startContainer, range.startOffset);
          start = [...preSelectionRange.toString()].length;
          end = start + [...range.toString()].length;
        } else if (document.selection && document.selection.type !== 'Control') {
          const selectedTextRange = document.selection.createRange();
          const preSelectionTextRange = document.body.createTextRange();
          preSelectionTextRange.moveToElementText(this.$el);
          preSelectionTextRange.setEndPoint('EndToStart', selectedTextRange);
          start = [...preSelectionTextRange.text].length;
          end = start + [...selectedTextRange.text].length;
        }
        this.startOffset = start;
        this.endOffset = end;
        console.log(start, end); // eslint-disable-line no-console
      },
  
      validRange() {
        if (this.startOffset === this.endOffset) {
          return false;
        }
        if (this.startOffset > this.text.length || this.endOffset > this.text.length) {
          return false;
        }
        if (this.startOffset < 0 || this.endOffset < 0) {
          return false;
        }
        for (let i = 0; i < this.entityPositions.length; i++) {
          const e = this.entityPositions[i];
          if ((e.start_offset <= this.startOffset) && (this.startOffset < e.end_offset)) {
            return false;
          }
          if ((e.start_offset < this.endOffset) && (this.endOffset < e.end_offset)) {
            return false;
          }
          if ((this.startOffset < e.start_offset) && (e.start_offset < this.endOffset)) {
            return false;
          }
          if ((this.startOffset < e.end_offset) && (e.end_offset < this.endOffset)) {
            return false;
          }
        }
        return true;
      },
  
      resetRange() {
        this.startOffset = 0;
        this.endOffset = 0;
      },
  
      addLabel(labelId) {
        if (this.validRange()) {
          const label = {
            start_offset: this.startOffset,
            end_offset: this.endOffset,
            label: labelId,
          };
          this.$emit('add-label', label);
        }
      },
  
      removeLabel(index) {
        this.$emit('remove-label', index);
      },
  
      makeLabel(startOffset, endOffset) {
        const label = {
          id: 0,
          label: -1,
          start_offset: startOffset,
          end_offset: endOffset,
        };
        return label;
      },
    },
  
    watch: {
      entityPositions() {
        this.resetRange();
      },
    },
  
    computed: {
      sortedEntityPositions() {
        this.entityPositions = this.entityPositions.sort((a, b) => a.start_offset - b.start_offset);
        return this.entityPositions;
      },
  
      chunks() {
        const res = [];
        let left = 0;
        for (let i = 0; i < this.sortedEntityPositions.length; i++) {
          const e = this.sortedEntityPositions[i];
          const l = this.makeLabel(left, e.start_offset);
          res.push(l);
          res.push(e);
          left = e.end_offset;
        }
        const l = this.makeLabel(left, this.text.length);
        res.push(l);
  
        return res;
      },
  
      id2label() {
        const id2label = {};
        // default value;
        id2label[-1] = {
          text_color: '',
          background_color: '',
        };
        for (let i = 0; i < this.labels.length; i++) {
          const label = this.labels[i];
          id2label[label.id] = label;
        }
        return id2label;
      },
    },
  });
  
  const vm = new Vue({ // eslint-disable-line no-unused-vars
    el: '#mail-app',
    delimiters: ['[[', ']]'],
    mixins: [annotationMixin],
    methods: {
      annotate(labelId) {
        this.$refs.annotator.addLabel(labelId);
      },
  
      addLabel(annotation) {
        const docId = this.docs[this.pageNumber].id;
        HTTP.post(`docs/${docId}/annotations`, annotation).then((response) => {
          this.annotations[this.pageNumber].push(response.data);
        });
      },
  
      async submit() {
        const state = this.getState();
        this.url = `docs?q=${this.searchQuery}&seq_annotations__isnull=${state}&offset=${this.offset}`;
        await this.search();
        this.pageNumber = 0;
      },
    },
  });
  