<template>
  <div class="b-properties-list">
    <sortable
      require-sortable-attribute
      v-model="list"
      axis="y"
      :read-only="!editable"
      auto-scroll="window"
    >
      <template v-for="(field, n) of listToHide">
        <property-item
          v-if="field.isVisible || isShowAll"
          :key="n"
          ref="properties"
          :field="field"
          :editable="editable"
          :lock-fields="lockFields"
          :value="value[field.Id]"
          @input="$emit('input', { ...value, [field.Id]: $event })"
          @delete="onDelete(field)"
          @duplicate="onDuplicate(field)"
          @update:field="onChange($event, n)"
        />
      </template>
    </sortable>

    <div v-if="editable && !lockFields" class="text-start">
      <div v-if="isShowAll || !hiddenItemsCount">
        <itf-dropdown ref="newItemDd" class="flex-grow-1 mw-100" shadow :button-options="{ small: true }">
          <template #button>
            <span class="text-muted d-flex align-items-center">
              <itf-icon name="plus" />
              Add property
            </span>
          </template>
          <div><h6 class="dropdown-header">{{ $t('components.customize.type') }}</h6></div>
          <div v-for="type of types" :keys="type.Type">
            <a class="dropdown-item d-flex align-items-center" @click.prevent="createNewField(type)">
              <itf-icon :name="type.Icon" :size="16" class="me-1" />
              {{ type.Name }}
            </a>
          </div>
        </itf-dropdown>
      </div>

      <itf-button v-if="hiddenItemsCount" small class="text-muted" @click="toggleShowAll">
        <itf-icon :name="isShowAll ? 'chevron_up' : 'chevron_down'" />
        {{isShowAll ? $tc('components.customize.hideMoreProperties', hiddenItemsCount, { n: hiddenItemsCount }) : $tc('components.customize.showMoreProperties', hiddenItemsCount, { n: hiddenItemsCount })}}
      </itf-button>
    </div>
  </div>
</template>
<style lang="scss">
.itf-dropdown__menu {
  div {
    position: relative;
  }
  .dropdown-submenu {
    display: none;
    position: absolute;
    left: 100%;
    top: -7px;
  }
  .dropdown-submenu-left {
    right: 100%;
    left: auto;
  }
  & div:hover > .dropdown-submenu {
    display: block;
  }
}
.b-properties-list {
  display: flex;
  flex-direction: column;
  padding: 5px 3px 5px 15px;
}
</style>
<script>
import { Vue, Component, Model, Prop, PropSync } from 'vue-property-decorator';
import itfIcon from '../icon/Icon';
import itfButton from '../button/Button';
import itfDropdown from '../dropdown/Dropdown.vue';
import itfLabel from '../form/Label.vue';
import itfTextField from '../text-field/TextField.vue';
import Sortable from '../sortable/Sortable.vue';
import PropertyItem from './PropertyItem';
import { INLINE_TYPES } from './constants';

export default @Component({
  name: 'itfPropertiesList',
  components: {
    itfIcon,
    itfDropdown,
    itfTextField,
    itfLabel,
    itfButton,
    Sortable,
    PropertyItem
  }
})
class itfPropertiesList extends Vue {
  @Model('input') value;
  @PropSync('fields') list;
  @Prop({ type: Boolean, default: false }) loading;
  @Prop({ type: Boolean, default: false }) editable;
  @Prop({ type: Boolean, default: false }) lockFields;

  isShowAll = false;

  toggleShowAll() {
    this.isShowAll = !this.isShowAll;
  }

  get types() {
    return INLINE_TYPES;
  }

  get hiddenItemsCount() {
    return this.listToHide.filter((item) => !item.isVisible).length;
  }

  get listToHide() {
    return this.list.map((item) => {
      return {
        ...item,
        isVisible: this.isVisible(item)
      }
    });
  }

  isVisible(field) {
    if (field.Visible === 'show') {
      return true;
    }
    if (field.Visible === 'hide') {
      return false;
    }
    return !!this.value[field.Id];
  }

  onChange(item, index) {
    const list = [...this.list];
    list[index] = item;
    this.$emit('update:fields', list);
  }

  onDelete(item) {
    const list = [...this.list].filter((i) => i.Id !== item.Id);
    this.$emit('update:fields', list);
  }

  onDuplicate(item) {
    const list = [...this.list];
    const newItem = { ...item };
    newItem.Id = `new-${Math.random().toString(36).substr(2, 9)}`;
    const index = newItem.Name.match(/\((\d+)\)$/);
    // додає вкінці номер (1), (2) і т.д.
    newItem.Name = newItem.Name.replace(/\s\(\d+\)$/, '');
    newItem.Name = `${newItem.Name}${index ? ` (${parseInt(index[1], 10) + 1})` : ' (1)'}`;
    list.push(newItem);
    this.$emit('update:fields', list);

    this.$nextTick(() => {
      for (const prop of this.$refs.properties) {
        prop.hideEditMenu();
      }
      setTimeout(() => {
        if (this.$refs.properties && this.$refs.properties[list.length - 1]) {
          this.$refs.properties[list.length - 1].showEditMenu();
        }
      }, 10);
    });
  }

  createNewField(type) {
    const list = [...this.list];
    list.push({
      Id: `new-${Math.random().toString(36).substr(2, 9)}`,
      Name: type.Name,
      Type: type.Type,
      Icon: type.Icon,
      Visible: 'show'
    });
    this.$emit('update:fields', list);
    if (this.$refs.newItemDd) {
      this.$refs.newItemDd.hide();
    }

    this.$nextTick(() => {
      setTimeout(() => {
        if (this.$refs.properties && this.$refs.properties[list.length - 1]) {
          try {
            this.$refs.properties[list.length - 1].showEditMenu();
          } catch (e) {
            // ignore
          }
        }
      }, 10);
    });
  }
}
</script>
