<template>
  <nav
    :class="[
      componentClass,
      hasAnyChildExpanded(0, null) && 'c-l0-exp',
      hasAnyChildExpanded(1, null) && 'c-l1-exp',
      filterHasClear && 'c-f-clr',
      isExpandedInternal && 'c-is-exp'
    ]"
    tabindex=0
  >
    <div
      v-if="showFilter"
      class="c-filter"
    >
      <button class="c-btn-exp" @click="onBtnExpClick"></button>
      <input
        type="text"
        :placeholder="filterPlaceholder"
        v-model="searchText"
        ref="filterInput"
      />
      <i
        class="c-btn-search"
        v-if="!filterHasClear"
        tabindex="-1"
      ></i>
      <i
        class="c-btn-clear"
        v-if="filterHasClear"
        tabindex="-1"
        @click="clearSearchText"
      >&#xE907;</i>
    </div>
    <ul class="c-l0">
      <li v-for="(row0, index0) in getChildren(0, null)" :key="index0" 
        :class="[
          'c-l0-item',
          {'c-can-exp':hasChildren(1, getChildValue(row0)) && hasValueSlot($scopedSlots, 'level1Item')},
          row0.isExpanded && 'c-exp',
          hasAnyChildExpanded(1, getChildValue(row0)) && 'c-l1-exp'
        ]"
        v-on:click.stop="(expandTrigger == 'click' && hasChildren(1, getChildValue(row0))) && expandNodeOnClick(row0)"
        v-on:mouseenter="(expandTrigger == 'hover' && hasChildren(1, getChildValue(row0))) && expandNodeOnMouseEnter(row0)"
        v-on:mouseleave="(expandTrigger == 'hover' && hasChildren(1, getChildValue(row0))) && collapseNodeOnMouseLeave(row0)"
      >
        <slot name="level0Item" v-bind:row="row0" v-bind:itemInfo="{hasChildren:hasChildren(1, getChildValue(row0))}"></slot>
        <ul v-if="columnsCount == 0 && hasChildren(1, getChildValue(row0)) && hasValueSlot($scopedSlots, 'level1Item')" class="c-l1">
          <li v-if="dataFieldIdent4SubMenuLabel" class="c-l1-item c-sub-menu-label">{{ getSubMenuLabel(row0) }}</li>
          <li v-for="(row1, index1) in getChildren(1, getChildValue(row0))" :key="index1"
            :class="[
              'c-l1-item',
              {'c-can-exp':hasChildren(2, getChildValue(row1)) && hasValueSlot($scopedSlots, 'level2Item')},
              row1.isExpanded && 'c-exp'
            ]"
            v-on:click.stop="(expandTrigger == 'click' && hasChildren(2, getChildValue(row1))) && expandNodeOnClick(row1)"
            v-on:mouseenter="(expandTrigger == 'hover' && hasChildren(2, getChildValue(row1))) && expandNodeOnMouseEnter(row1)"
            v-on:mouseleave="(expandTrigger == 'hover' && hasChildren(2, getChildValue(row1))) && collapseNodeOnMouseLeave(row1)"
          >
            <slot name="level1Item" v-bind:row="row1" v-bind:itemInfo="{hasChildren:hasChildren(2, getChildValue(row1))}"></slot>
            <ul class="c-l2" v-if="hasChildren(2, getChildValue(row1)) && hasValueSlot($scopedSlots, 'level2Item')">
              <li v-if="dataFieldIdent4SubMenuLabel" class="c-l2-item c-sub-menu-label">{{ getSubMenuLabel(row1) }}</li>
              <li v-for="(row2, index2) in getChildren(2, getChildValue(row1))" :key="index2" class="c-l2-item"
                v-on:click.stop="(expandTrigger == 'click')"
              >
                <slot name="level2Item" v-bind:row="row2"></slot>
              </li>
            </ul>
          </li>
        </ul>
        <div class="c-l1-cols" v-if="columnsCount > 0 && hasChildren(1, getChildValue(row0)) && hasValueSlot($scopedSlots, 'level1Item')">
          <ul v-for="(col1, indexcol1) in getColumns(1, getChildValue(row0))" :key="indexcol1" class="c-l1">
            <li v-for="(row1, index1) in getChildren4Colum(1, getChildValue(row0), indexcol1)" :key="index1"
              :class="[
                'c-l1-item',
                {'c-can-exp':hasChildren(2, getChildValue(row1)) && hasValueSlot($scopedSlots, 'level2Item')},
                row1.isExpanded && 'c-exp'
              ]"
              v-on:click.stop="(expandTrigger == 'click' && hasChildren(2, getChildValue(row1))) && expandNodeOnClick(row1)"
              v-on:mouseenter="(expandTrigger == 'hover' && hasChildren(2, getChildValue(row1))) && expandNodeOnMouseEnter(row1)"
              v-on:mouseleave="(expandTrigger == 'hover' && hasChildren(2, getChildValue(row1))) && collapseNodeOnMouseLeave(row1)"
            >
              <slot name="level1Item" v-bind:row="row1" v-bind:itemInfo="{hasChildren:hasChildren(2, getChildValue(row1))}"></slot>
              <ul class="c-l2" v-if="hasChildren(2, getChildValue(row1)) && hasValueSlot($scopedSlots, 'level2Item')">
                <li v-for="(row2, index2) in getChildren(2, getChildValue(row1))" :key="index2" class="c-l2-item"
                  v-on:click.stop="(expandTrigger == 'click')"
                >
                  <slot name="level2Item" v-bind:row="row2"></slot>
                </li>
              </ul>
            </li>
          </ul>
        </div>
      </li>
    </ul>
  </nav>
</template>
<script>

import base from './c-base'
import stringUtils from '../classes/stringUtils'
import { mapGetters } from 'vuex'

const props = {
  dataFieldIdent4Parent: {
    type: String,
    default:null
  },
  dataFieldIdent4Child: {
    type: String,
    default:null
  },
  dataFieldIdent4Level: {
    type: String,
    default:null
  },
  dataFieldIdent4IsExpanded: {
    type: String,
    default:null
  },
  dataFieldIdent4SubMenuLabel: {
    type: String,
    default: null
  },
  dataField4KeyWords: {
    type: String,
    default: 'keyWords'
  },
  columnsCount: {
    type: Number,
    default: 4
  },
  expandTrigger: {
    type: String,
    default: "hover" //hover, click
  },
  expandMode: {
    type: String,
    default: "one" //one, many
  },
  showFilter: {
    type: Boolean,
    default: false
  },
  filterPlaceholder: {
    type: String,
    default: 'Szukaj w menu'
  },
  filterShowClear: {
    type: Boolean,
    default: true
  },
  isExpanded: {
    type: Boolean,
    default: true
  }
}
export default {
  extends: base,
  data: function () {
    return {
      componentClass: 'c-menu',
      searchText: '',
      diacriticsMap: this.showFilter ? stringUtils.getDiacriticsMap('lower') : null,
      isExpandedInternal: true
    }
  },
  props,
  created: function() {
    this.isExpandedInternal = this.isExpanded
  },
  computed: {
    ...mapGetters('csAppWindowsUtils', [
      'getDataSetFieldsIdentsDataField'
    ]),
    filterHasClear: function() {
      return this.filterShowClear && this.searchText != '' && this.searchText != null
    }
  },
  methods: {
    getMenuSubClass: function (level) {
      return this.componentClass + '--item--' + level
    },
    getParentValue: function (item) {
      return item[this.dataFieldIdent4Parent]
    },
    getChildValue: function (item) {
      return item[this.dataFieldIdent4Child]
    },
    getLevelValue: function (item) {
      return item[this.dataFieldIdent4Level]
    },
    getSubMenuLabel: function(item) {
      return item[this.dataFieldIdent4SubMenuLabel]
    },
    // getChildrenV1: function (level, parentId) {
    //   return this.rows.filter(item => this.getLevelValue(item) === level && (this.getParentValue(item) === parentId || parentId === null))
    // },
    getChildren: function (level, parentId) {
      if(this.searchText != '' && this.searchText != null && this.getDataSetFieldsIdentsDataField(this.dataSet, this.dataField4KeyWords) != null) {
        if(level == 0) {
          let searchText = stringUtils.removeDiacritics(this.searchText.toLowerCase(), this.diacriticsMap)
          return this.rows.filter(row => stringUtils.removeDiacritics(row[this.dataField4KeyWords]?.toLowerCase(), this.diacriticsMap)?.includes(searchText))
        }
      } else {
        return this.rows.filter(item => this.getLevelValue(item) === level && (this.getParentValue(item) === parentId || parentId === null))
      }
    },
    hasChildren: function (level, parentId) {
      let children = this.getChildren(level, parentId)
      return children && children.length > 0 ? true : false
    },
    hasAnyChildExpanded: function(level, parentId) {
      let children = this.getChildren(level, parentId)
      if(children != null) {
        return children.some(row => this.getDataSetFieldValue(this.sourceKind, this.dataSet, this.dataFieldIdent4IsExpanded, row, null))
      } else {
        return false
      }
    },
    getColumns: function(level, parentId) {
      return this.getChildren(level, parentId).length > 0 ? this.columnsCount : 0
    },
    getChildren4Colum: function(level, parentId, columnNo) {
      var children = this.getChildren(level, parentId)
      var childrenCount4Column = Math.ceil(children.length / this.columnsCount)
      return children.slice((columnNo * childrenCount4Column), ((columnNo * childrenCount4Column) + (childrenCount4Column)))
    },
    hasValueSlot: function (scopedSlots, name) {
      return scopedSlots[name] ? true : false
    },
    expandNodeOnClick: function(row) {
      if(!stringUtils.isEmpty(this.dataFieldIdent4IsExpanded)) {
        let isExpanded = this.getDataSetFieldValue(this.sourceKind, this.dataSet, this.dataFieldIdent4IsExpanded, row, null)
        isExpanded = Number(!isExpanded)

        if(this.expandMode == "one" && isExpanded == 1) {
          this.getChildren(this.getDataSetFieldValue(this.sourceKind, this.dataSet, this.dataFieldIdent4Level, row, null), null).forEach((item) => {
            if((item != row) && (this.getDataSetFieldValue(this.sourceKind, this.dataSet, this.dataFieldIdent4IsExpanded, item, null) == 1)) {
              this.setDataSetFieldValue({
                sourceKind: this.sourceKind,
                appWindowIdent: this.appWindowIdent, 
                dataSet: this.dataSet,
                row: item,
                dataFieldIdent: this.dataFieldIdent4IsExpanded,
                dataFieldValue: 0 
              })
            }
          })
        }

        this.setDataSetFieldValue({
          sourceKind: this.sourceKind,
          appWindowIdent: this.appWindowIdent, 
          dataSet: this.dataSet,
          row: row,
          dataFieldIdent: this.dataFieldIdent4IsExpanded,
          dataFieldValue: isExpanded 
        })
      }
    },
    expandNodeOnMouseEnter: function(row) {
      if(!stringUtils.isEmpty(this.dataFieldIdent4IsExpanded)) {
        this.setDataSetFieldValue({
          sourceKind: this.sourceKind,
          appWindowIdent: this.appWindowIdent, 
          dataSet: this.dataSet,
          row: row,
          dataFieldIdent: this.dataFieldIdent4IsExpanded,
          dataFieldValue: 1 
        })
      }
    },
    collapseNodeOnMouseLeave: function(row) {
      if(!stringUtils.isEmpty(this.dataFieldIdent4IsExpanded)) {
        this.setDataSetFieldValue({
          sourceKind: this.sourceKind,
          appWindowIdent: this.appWindowIdent, 
          dataSet: this.dataSet,
          row: row,
          dataFieldIdent: this.dataFieldIdent4IsExpanded,
          dataFieldValue: 0 
        })
      }
    },
    clearSearchText: function() {
      this.searchText = ''
      this.$refs.filterInput.focus()
    },
    onBtnExpClick: function() {
      this.isExpandedInternal = !this.isExpandedInternal
    }
}
}</script>