<template>
  <div class="editable-block">
    <!-- SVG ICONS CONTAINER -->
    <svg
      class="svg-icon-holder"
      width="24px"
      height="14px"
      viewBox="0 0 24 14"
      version="1.1"
      xmlns="http://www.w3.org/2000/svg"
      xmlns:xlink="http://www.w3.org/1999/xlink"
    >
      <defs
        stroke="none"
        stroke-width="1"
        fill="none"
        fill-rule="evenodd"
      >
        <g id="varIcon" fill="inherit">
          <path
            id="{x}"
            d="M3.63347002,7.08106937 L3.63347002,6.95804652 C4.60398359,6.86919669 5.05506736,6.33609769 5.05506736,5.33824571 L5.05506736,3.7184449 C5.05506736,2.64541229 5.40363209,2.31735137 6.51767231,2.31735137 L6.82522943,2.31735137 L6.82522943,0.813738797 L6.10759616,0.813738797 C4.02304237,0.813738797 3.14821324,1.56554508 3.14821324,3.38354937 L3.14821324,4.64795085 C3.14821324,5.71414885 2.86115993,6.06954819 2,6.06954819 L2,7.96273311 C2.86115993,7.96273311 3.14821324,8.31813244 3.14821324,9.37749584 L3.14821324,10.8674392 C3.14821324,12.7264511 4.02987697,13.4987612 6.10759616,13.4987612 L6.82522943,13.4987612 L6.82522943,12.0019832 L6.51767231,12.0019832 C5.41046669,12.0019832 5.05506736,11.6739223 5.05506736,10.6077243 L5.05506736,8.83072763 C5.05506736,7.78503344 4.56297597,7.16991921 3.63347002,7.08106937 Z M12.0205038,8.7282086 L13.4215973,11.1886655 L15.6360086,11.1886655 L13.2507323,7.37495728 L15.6155048,3.65009887 L13.4421011,3.65009887 L12.1093536,6.12422501 L11.9863308,6.12422501 L10.6535833,3.65009887 L8.37082602,3.65009887 L10.7492677,7.46380712 L8.38449523,11.1886655 L10.4963874,11.1886655 L11.897481,8.7282086 L12.0205038,8.7282086 Z M20.36653,7.08106937 C19.437024,7.16991921 18.9449326,7.78503344 18.9449326,8.83072763 L18.9449326,10.6077243 C18.9449326,11.6739223 18.5895333,12.0019832 17.4823277,12.0019832 L17.1747706,12.0019832 L17.1747706,13.4987612 L17.8924038,13.4987612 C19.970123,13.4987612 20.8517868,12.7264511 20.8517868,10.8674392 L20.8517868,9.37749584 C20.8517868,8.31813244 21.1388401,7.96273311 22,7.96273311 L22,6.06954819 C21.1388401,6.06954819 20.8517868,5.71414885 20.8517868,4.64795085 L20.8517868,3.38354937 C20.8517868,1.56554508 19.9769576,0.813738797 17.8924038,0.813738797 L17.1747706,0.813738797 L17.1747706,2.31735137 L17.4823277,2.31735137 C18.5963679,2.31735137 18.9449326,2.64541229 18.9449326,3.7184449 L18.9449326,5.33824571 C18.9449326,6.33609769 19.3960164,6.86919669 20.36653,6.95804652 L20.36653,7.08106937 Z"
          />
        </g>
      </defs>
    </svg>
    <!-- SVG ICONS CONTAINER END -->

    <or-icon-button
      v-if="mergeFields.length > 0"
      ref="addVariable"
      class="add-variable flat"
      type="secondary"
      tooltip="Add variable"
      @click="openDataOutPopover"
    >
      <div slot="default" class="svg-icon-position">
        <svg width="24px" height="14px">
          <use xlink:href="#varIcon" />
        </svg>
      </div>
    </or-icon-button>

    <editable-area
      ref="editable"
      :key="componentKey"
      :class="['editable-area', {'invalid': invalid }]"
      data-placeholder="Enter text here"
      :content="source"
      :tagList="tagList"
      @editable:modified="editableModified"
    />

    <or-popover
      v-if="mergeFields.length > 0"
      ref="dataOutPopoverInline"
      class="editable-data-outs"
      trigger="addVariable"
      open-on="click"
      :close-on-blur="true"
      @close="dataOutPopoverClosed"
    >
      <or-textbox
        ref="searchMergeField"
        v-model="searchMergeField"
        class="search-merge-field"
        placeholder="Search"
      />
      <div ref="dataOutsWrapper" class="list-wrapper">
        <ul class="list">
          <li v-for="dataOutTitled in filteredMergeFields" :key="dataOutTitled">
            <div class="list-title">
              {{ dataOutTitled.title }}
            </div>

            <div
              v-for="dataOut in dataOutTitled.variables"
              :key="`${dataOut.flowId}:s${dataOut.variableName}`"
              :class="[dataOut.subObject === true && 'sub-object', 'list-item']"
              @mousedown="addMFTag(dataOut.variableName)"
            >
              {{ dataOut.variableName }}
            </div>
          </li>
        </ul>
      </div>
    </or-popover>
  </div>
</template>

<script>
import _ from 'lodash';
import EditableArea from './_components/editable-area.vue';
import dataOuts from '../../utils/data_outs.js';

export default {
  name: 'EditableModule',

  components: {
    EditableArea
  },

  mixins: [dataOuts],

  props: {
    mergeFields: {
      type: Array,
      default: () => ({})
    },
    isActive: {
      type: Boolean,
      default: false
    },
    invalid: {
      type: Boolean,
      default: false
    }
  },

  data () {
    return {
      theSelection: null,
      componentKey: 0,
      searchMergeField: ''
    };
  },

  computed: {
    source () {
      return this.$liteStore.get('editable/editableInitContent');
    },

    tagList () {
      return this.$liteStore.get('tagList/getTagsList');
    },

    attributeListStore () {
      return this.$liteStore.get('tagDetails/attributeList');
    },

    filteredMergeFields () {
      return this.filterMergeFields(this.searchMergeField);
    }
  },

  watch: {
    attributeListStore (value) {
      if (this.isActive) {
        this.editableSetAttributes(value);
      }
    },

    tagList () {
      this.$liteStore.dispatch(
        'editable/validateEditorContent',
        this.$refs.editable.$el
      );
      this.tagList = this.$liteStore.get('tagList/getTagsList');
    },

    source () {
      this.$liteStore.dispatch(
        'editable/validateEditorContent',
        this.$refs.editable.$el
      );
      this.componentKey = Math.round(Math.random() * 1000);

      this.$nextTick(() => {
        this.$refs.editable.$el.focus();
      });
    }
  },

  beforeDestroy () {
    // this.$EventBus.$off('editable-update::unset-active-tag');
    this.$EventBus.$off('editable-update::clear');
    this.$EventBus.$off('editable-update::save');
    this.$EventBus.$off('editable-update::request');
    this.$EventBus.$off('editable-update::delete');
  },

  created () {
    // this.$EventBus.$on('editable-update::unset-active-tag', () => this.unsetActiveTag());
    this.$EventBus.$on('editable-update::clear', () => this.clearAll());
    this.$EventBus.$on('editable-update::clearInvalid', () =>
      this.clearInvalidTags()
    );
    this.$EventBus.$on('editable-update::save', (content) =>
      this.saveEditorContent(content)
    );
    this.$EventBus.$on('editable-update::request', () =>
      this.editableModified('$EventBus request')
    );
    this.$EventBus.$on('editable-update::delete', () =>
      this.editableDeleteActiveTag()
    );
  },

  methods: {
    addMFTag (variableName) {
      this.$refs.editable.addMFTagDomNode(variableName);
      this.$EventBus.$emit('editable-update::request');
      this.$refs.dataOutPopoverInline.close();
      this.searchMergeField = '';
    },

    openDataOutPopover () {
      this.$refs.editable.setFocus();
      this.dataOutPopoverOpened = true;
      this.$nextTick(() => {
        const maxWidth = Math.floor(window.innerHeight / 2 - 40);
        this.$refs.dataOutsWrapper.style.maxHeight = `${maxWidth}px`;
        this.$refs.dataOutPopoverInline.reposition();
        this.$refs.dataOutPopoverInline.open();

        const inputs =
          this.$refs.searchMergeField.$el.getElementsByTagName('input');
        if (!_.isEmpty(inputs)) inputs[0].focus();
      });
    },

    dataOutPopoverClosed () {
      this.dataOutPopoverOpened = false;
    },

    saveEditorContent (content) {
      if (this.isActive) {
        this.$liteStore.dispatch(
          'editable/saveEditableAreaContent',
          content || this.$refs.editable.$el
        );
      }
    },

    editableModified (e) {
      this.$liteStore.get('selection/getSelection').formatSelection();
      this.$liteStore.dispatch(
        'editable/saveEditableAreaTmpContent',
        this.$refs.editable.$el
      );
      this.$liteStore.dispatch('tagList/setAllowedTags');
      this.$liteStore.dispatch('tagDetails/setTagDetails');

      this.$emit('editable:modified');
    },

    deleteTags (selector) {
      const invalidTags = this.$refs.editable.$el.querySelectorAll(selector);

      if (invalidTags.length > 0) {
        invalidTags.forEach((item) => {
          const parentTag = item.parentNode;
          item.replaceWith(...item.childNodes);
          parentTag.normalize();
        });
      }

      this.$liteStore.dispatch(
        'editable/saveEditableAreaTmpContent',
        this.$refs.editable.$el
      );
      this.$liteStore.dispatch('tagList/setAllowedTags');
      this.$liteStore.dispatch('tagDetails/setTagDetails');
    },

    editableDeleteActiveTag () {
      this.deleteTags('[data-active-tag]');
    },

    editableSetAttributes (selectedAttrs) {
      const attrList = this.$liteStore.get('tagList/getTagsList');
      const activeTag = this.$liteStore.get('editable/activeTag');
      const activeTagElement =
        this.$refs.editable.$el.querySelector('[data-active-tag]');

      if (activeTag === undefined) {
        return;
      }

      const tagConfig = attrList[activeTag.type];

      const attrsUpdated = {};
      const conditional = [];

      if (tagConfig !== undefined) {
        _.forIn(tagConfig.attr, (value, key) => {
          const el = selectedAttrs[key] || value;
          const val = el.type === 'select' ? el.selected : el.value;

          if (el.showif) {
            conditional.push({
              source: key,
              targetName: el.showif.name,
              targetValue: el.showif.value
            });
          }

          if (val !== '' || val !== undefined) {
            attrsUpdated[key] = {
              id: key,
              name: 'data-attr-' + key,
              value: val
            };
          }
        });
      }

      if (conditional.length >= 1) {
        conditional.forEach((item) => {
          const condition =
            attrsUpdated[item.targetName].selected === item.targetValue;

          if (!condition) {
            delete attrsUpdated[item.source];
          }
        });
      }

      let lastAttrValue = '';

      _.forIn(attrsUpdated, (item, key) => {
        if (activeTagElement) {
          activeTagElement.setAttribute(item.name, item.value);
        }
        lastAttrValue = item.value;
      });

      const dataLabel =
        lastAttrValue !== ''
          ? activeTag.type + ': ' + lastAttrValue
          : activeTag.type;

      if (activeTagElement) {
        activeTagElement.setAttribute('data-label', dataLabel);
      }

      this.$liteStore.dispatch(
        'editable/saveEditableAreaTmpContent',
        this.$refs.editable.$el
      );
    },

    clearAll () {
      this.$refs.editable.$el.innerHTML = '';
      this.editableModified();
    },

    clearInvalidTags () {
      this.deleteTags('.text-wrapper--error');
    },

    filterMergeFields (search) {
      const loweredSearch = _.chain(search).trim().toLower();

      if (_.isEmpty(loweredSearch)) return this.dataOuts;

      return _.map(this.dataOuts, ({ variables, ...rest }) => ({
        ...rest,
        variables: _.filter(variables, ({ variableName }) =>
          _.includes(_.toLower(variableName), loweredSearch)
        )
      }));
    }

    // unsetActiveTag() {
    //   console.log('this.$refs.editable.$el', this.$refs.editable.$el)
    // }
  }
};
</script>

<style lang="scss" scoped>
.editable-block {
  position: relative;
  color: rgb(33, 39, 49);

  .editable-area.invalid {
    border-color: var(--or-c-error) !important;
  }

  .editable-area:empty:before {
    content: attr(data-placeholder);
    color: lightgray;
  }
}

.add-variable {
  position: absolute;
  top: 0;
  right: 0;
}

.editable-data-outs {
  padding: 0;
}
</style>

<style lang="scss">
@at-root .list {
  list-style: none;
  padding: 0;

  &-wrapper {
    overflow: auto;
    min-width: 268px;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
      "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
      "Helvetica Neue", sans-serif;
    font-size: 14px;
  }

  &-title {
    margin-top: 5px;
    padding-left: 10px;
    padding-bottom: 2px;
    border-bottom: 1px solid grey;
    font-weight: bold;
  }

  &-item {
    padding: 2px 10px;
    cursor: pointer;

    &.sub-object {
      padding-left: 20px;
      color: #a1a5aa;
    }

    &:hover,
    &.active {
      background-color: #eee;
    }
  }
}

@at-root .search-merge-field {
  margin: 0;
  padding: 10px;
}
</style>
