<template>
  <div>
    <h6 class="text-light font-weight-normal">
      {{ updatedAsAt }}
    </h6>
    <div class="genealogy">
      <b-container class="genealogy-main-container" fluid>
        <b-row :no-gutters="true">
          <b-col cols="12" sm="12" md="12" lg="12" xl="9">
            <div class="genealogy-main-wrapper">
              <div class="genealogy-base-container">
                <b-container fluid>
                  <b-row class="pt-3">
                    <b-col class="pr-0 my-1 col-12 col-xs-12 col-sm-12 col-lg-5 col-xl-6">
                      <div class="d-inline-block pl-3 pt-2" v-if="viewIboId === ''">
                        {{ $t('Genealogy.SponsorNetworkTree.SubTitle') }}
                      </div>
                      <div class="d-inline-block pl-3 pt-2" v-if="viewIboId !== ''">
                        <div
                          class="genealogy-back-icon-container"
                          v-if="searchedUserId === null"
                          @click="removeViewIbo()"
                        >
                          <icon class="genealogy-back-icon-content" name="angle-left" />
                        </div>
                        {{ $t('Common.View') }}: {{ viewIboId }} ({{ viewIboName }})
                      </div>
                    </b-col>
                    <b-col class="px-0 my-1 col-12 col-xs-12 col-sm-5 col-lg-3 col-xl-3">
                      <div class="d-flex align-items-center">
                        <div class="d-flex">
                          {{ $t('Genealogy.SponsorNetworkTree.Search.Display') }}
                        </div>
                        <div class="d-flex mx-2">
                          <b-form-select
                            v-model="selectedDepth"
                            :options="depthOptions"
                            @input="populateSponsorNetworkTree"
                            :disabled="treeDataSource === null || viewIboId !== '' || searchedUserId !== null"
                          />
                        </div>
                      </div>
                    </b-col>
                    <b-col class="pl-0 my-1 col-12 col-xs-12 col-sm-7 col-lg-4 col-xl-3">
                      <b-input-group>
                        <eshop-autocomplete
                          :items="getMemberList"
                          v-model="selectedDownline"
                          :get-label="item => (item ? item.name : '')"
                          :wait="200"
                          variant="primary"
                          template-name="member"
                          :min-len="3"
                          class="flex-grow-1"
                          :placeholder="$t('Genealogy.SponsorNetworkTree.Search.SearchDownline')"
                          id="myInput"
                          @updateItems="searchMemberListExcludeSelf"
                          @item-selected="searchDownline"
                        />
                        <b-input-group-append>
                          <b-btn
                            v-if="$helpers.isEmpty(selectedDownline) === false"
                            variant="link"
                            @click="clearSearchInput"
                            class="border-light border-left-0 rounded-0"
                          >
                            <icon name="clear-icon" />
                          </b-btn>
                          <b-btn
                            v-else
                            disabled
                            class="bg-transparent text-success border-left-0 border-light rounded-0"
                          >
                          </b-btn>
                        </b-input-group-append>
                      </b-input-group>
                    </b-col>
                  </b-row>
                </b-container>
                <hr />
                <div class="genealogy-tree-base-container">
                  <div
                    class="vh-50 d-flex justify-content-center align-items-center"
                    v-if="treeDataSource === null || isLoading('verifyMemberTreeLoading')"
                  >
                    <icon class="icon-size-4" name="spinner" pulse />
                  </div>
                  <div
                    v-else-if="selectedDownline !== '' && downlineNotFound"
                    class="vh-50 d-flex justify-content-center align-items-center"
                  >
                    <h3>{{ $t('Genealogy.SponsorNetworkTree.Search.DownlineNotFound') }}</h3>
                  </div>
                  <div class="genealogy-tree-base-wrapper" v-else>
                    <sponsor-network-tree-item
                      v-for="(downlines, index) in treeDataSource.downlines"
                      :key="index"
                      :model="downlines"
                      :view-ibo-id="viewIboId"
                      :select-view-ibo="selectViewIbo"
                    />
                  </div>
                </div>
              </div>
            </div>
          </b-col>
          <b-col cols="12" sm="12" md="12" lg="12" xl="3">
            <div class="genealogy-legend-wrapper">
              <div class="genealogy-legend-detail-container">
                <div
                  class="d-flex justify-content-center align-items-center vh-25"
                  v-if="treeDataSource === null || isLoading('verifyMemberTreeLoading')"
                >
                  <icon class="icon-size-4" name="spinner" pulse />
                </div>
                <div v-else-if="selectedDownline !== '' && downlineNotFound" class="vh-25" />
                <b-container fluid v-else>
                  <b-row>
                    <b-col>
                      <div class="genealogy-legend-label">
                        {{ $t('Common.IboId') }}
                      </div>
                    </b-col>
                    <b-col>
                      <div class="genealogy-legend-value">
                        {{ memberDetails.ibo_id }}
                      </div>
                    </b-col>
                  </b-row>
                  <b-row>
                    <b-col>
                      <div class="genealogy-legend-label">
                        {{ $t('Common.IboName') }}
                      </div>
                    </b-col>
                    <b-col>
                      <div class="genealogy-legend-value">
                        {{ memberDetails.ibo_name }}
                      </div>
                    </b-col>
                  </b-row>
                  <b-row>
                    <b-col>
                      <div class="genealogy-legend-label">
                        {{ $t('Common.JoinDate') }}
                      </div>
                    </b-col>
                    <b-col>
                      <div class="genealogy-legend-value">
                        {{ memberDetails.joined_date }}
                      </div>
                    </b-col>
                  </b-row>
                  <b-row>
                    <b-col>
                      <div class="genealogy-legend-label">
                        {{ $t('Common.ExpiryDate') }}
                      </div>
                    </b-col>
                    <b-col>
                      <div class="genealogy-legend-value">
                        {{ memberDetails.expiry_date }}
                      </div>
                      <div class="genealogy-legend-expiry-holder">
                        <icon name="check" class="genealogy-legend-expiry-icon" />
                      </div>
                    </b-col>
                  </b-row>
                  <b-row>
                    <b-col>
                      <div class="genealogy-legend-label">
                        {{ $t('Genealogy.SponsorNetworkTree.DetailLegend.Country') }}
                      </div>
                    </b-col>
                    <b-col>
                      <div class="genealogy-legend-value">
                        {{ $helpers.getValue(memberDetails, 'translated_country.content', memberDetails.country) }}
                      </div>
                    </b-col>
                  </b-row>
                  <b-row>
                    <b-col>
                      <div class="genealogy-legend-label">
                        {{ $t('Genealogy.SponsorNetworkTree.DetailLegend.EnrolmentType') }}
                      </div>
                    </b-col>
                    <b-col>
                      <div class="genealogy-legend-value">
                        {{ memberDetails.enrollment_rank }}
                      </div>
                    </b-col>
                  </b-row>
                  <b-row>
                    <b-col>
                      <div class="genealogy-legend-label">
                        {{ $t('Common.HighestRank') }}
                      </div>
                    </b-col>
                    <b-col>
                      <div class="genealogy-legend-value">
                        {{
                          $helpers.getValue(
                            memberDetails,
                            'translated_highest_rank.content',
                            memberDetails.highest_rank
                          )
                        }}
                      </div>
                    </b-col>
                  </b-row>
                  <b-row>
                    <b-col>
                      <div class="genealogy-legend-label">
                        {{ $t('Common.Terminology.PaidAsRank') }}
                      </div>
                    </b-col>
                    <b-col>
                      <div class="genealogy-legend-value">
                        {{
                          $helpers.getValue(
                            memberDetails,
                            'translated_effective_rank.content',
                            memberDetails.effective_rank
                          )
                        }}
                      </div>
                    </b-col>
                  </b-row>
                  <b-row>
                    <b-col>
                      <div class="genealogy-legend-label">
                        {{ $t('Common.Terminology.CumulativePersonalSalesCV') }}
                      </div>
                    </b-col>
                    <b-col>
                      <div class="genealogy-legend-value">
                        {{ memberDetails.personal_sales_cv }}
                      </div>
                    </b-col>
                  </b-row>
                </b-container>
              </div>
            </div>
            <div class="genealogy-legend-wrapper">
              <div class="genealogy-legend-status-container">
                <div>
                  <table>
                    <tbody>
                      <tr v-for="(item, inx) in legendColorItems" :key="inx">
                        <td><div :class="item.icon" /></td>
                        <td>
                          <div :class="item.item">
                            {{ item.text }}
                          </div>
                        </td>
                      </tr>
                    </tbody>
                  </table>
                  <hr class="genealogy-legend-horizontal-rule" />
                  <div class="genealogy-legend-label-status">
                    {{ $t('Genealogy.SponsorNetworkTree.StatusLegend.SalesActivityStatus') }}
                  </div>
                  <table>
                    <tbody>
                      <tr v-for="(item, inx) in legendStatusItems" :key="inx">
                        <td><div :class="item.icon" /></td>
                        <td>
                          <div :class="item.item">
                            {{ item.text }}
                          </div>
                        </td>
                      </tr>
                    </tbody>
                  </table>
                  <hr class="genealogy-legend-horizontal-rule" />
                  <table>
                    <tbody>
                      <tr v-for="(item, inx) in legendOtherItems" :key="inx">
                        <td><div :class="item.icon" /></td>
                        <td>
                          <div :class="item.item">
                            {{ item.text }}
                          </div>
                        </td>
                      </tr>
                    </tbody>
                  </table>
                </div>
              </div>
            </div>
          </b-col>
        </b-row>
      </b-container>
    </div>
  </div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
import SponsorNetworkTreeItem from './SponsorNetworkTreeItem'
import EshopAutocomplete from '@/app/_global/components/elements/EshopAutocomplete'
import moment from 'moment'

export default {
  name: 'Genealogy',
  $_veeValidate: {
    validator: 'new',
  },
  components: {
    SponsorNetworkTreeItem,
    EshopAutocomplete,
  },
  data() {
    return {
      updatedAsAt: '',
      selectedDepth: 4,
      selectedDownline: '',
      viewIboId: '',
      viewIboName: '',
      depthOptions: [
        { value: 1, text: this.$t('Genealogy.SponsorNetworkTree.Search.Level1') },
        { value: 2, text: this.$t('Genealogy.SponsorNetworkTree.Search.Level2') },
        { value: 3, text: this.$t('Genealogy.SponsorNetworkTree.Search.Level3') },
        { value: 4, text: this.$t('Genealogy.SponsorNetworkTree.Search.Level4') },
        { value: 5, text: this.$t('Genealogy.SponsorNetworkTree.Search.Level5') },
        { value: 6, text: this.$t('Genealogy.SponsorNetworkTree.Search.Level6') },
        { value: 7, text: this.$t('Genealogy.SponsorNetworkTree.Search.Level7') },
        { value: 8, text: this.$t('Genealogy.SponsorNetworkTree.Search.Level8') },
        { value: 9, text: this.$t('Genealogy.SponsorNetworkTree.Search.Level9') },
        { value: 10, text: this.$t('Genealogy.SponsorNetworkTree.Search.Level10') },
        { value: 99, text: this.$t('Genealogy.SponsorNetworkTree.Search.AllLevels') },
      ],
      legendColorItems: [
        {
          icon: 'genealogy-legend-icon-direct-downline',
          item: 'genealogy-legend-item-direct-downline',
          text: this.$t('Genealogy.SponsorNetworkTree.ColorLegend.NumberOfDirectDownline'),
        },
        {
          icon: 'genealogy-legend-icon-total-downline',
          item: 'genealogy-legend-item-total-downline',
          text: this.$t('Genealogy.SponsorNetworkTree.ColorLegend.NumberOfTotalDownline'),
        },
        {
          icon: 'genealogy-legend-icon-highest-rank',
          item: 'genealogy-legend-item-highest-rank',
          text: this.$t('Common.Terminology.PaidAsRank'),
        },
        {
          icon: 'genealogy-legend-icon-expiry-date',
          item: 'genealogy-legend-item-expiry-date',
          text: this.$t('Common.ExpiryDate'),
        },
        {
          icon: 'genealogy-legend-icon-left-downline',
          item: 'genealogy-legend-item-left-downline',
          text: this.$t('Genealogy.SponsorNetworkTree.ColorLegend.TotalActiveLeftDownlines'),
        },
        {
          icon: 'genealogy-legend-icon-right-downline',
          item: 'genealogy-legend-item-right-downline',
          text: this.$t('Genealogy.SponsorNetworkTree.ColorLegend.TotalActiveRightDownlines'),
        },
      ],
      legendStatusItems: [
        {
          icon: 'genealogy-legend-icon-active-status',
          item: 'genealogy-legend-item-active-status',
          text: this.$t('Common.Active'),
        },
        {
          icon: 'genealogy-legend-icon-inactive-status',
          item: 'genealogy-legend-item-inactive-status',
          text: this.$t('Common.Inactive'),
        },
      ],
      legendOtherItems: [
        {
          icon: 'genealogy-legend-icon-other-status',
          item: 'genealogy-legend-item-other-status',
          text: this.$t('Genealogy.SponsorNetworkTree.StatusLegend.Others'),
        },
      ],
      sponsorNetworkTreeData: null,
      treeDataSource: null,
      treeActiveItem: [],
      filterInAction: false,
      filterCurrentKey: '',
      filterActiveItem: [],
      viewDataSource: null,
      treeMaxDepth: 0,
      minContentWidth: 0,
      searchedUserId: null,
      searchedUserName: '',
      downlineNotFound: false,
      memberDetails: null,
    }
  },
  mounted() {
    this.searchMemberListExcludeSelf('')
    this.loadEnrollmentRanks()
    this.loadMemberDashboard().then(() => {
      let updatedTimeStemp = this.$helpers.getValue(this.getMemberDashboard, 'updated_at')
      if (updatedTimeStemp) {
        this.updatedAsAt = this.$t('Genealogy.SponsorNetworkTree.Audit', {
          time: moment(updatedTimeStemp).format('DD/MM/YYYY hh:mm A'),
        })
      } else {
        this.updatedAsAt = this.$t('Genealogy.SponsorNetworkTree.Audit', { time: '-' })
      }
    })
    this.populateSponsorNetworkTree()
    window.addEventListener('resize', this.resizeEventHandler)
  },
  beforeDestroy: function() {
    window.removeEventListener('resize', this.resizeEventHandler)
  },
  methods: {
    ...mapActions([
      'loadSponserDownlineListingData',
      'searchMemberSponsor',
      'loadMemberDetails',
      'loadMemberDashboard',
      'loadEnrollmentRanks',
      'searchMemberListExcludeSelf',
    ]),
    populateSponsorNetworkTree() {
      let query = {
        depth: this.searchedUserId === null ? this.selectedDepth : 99,
        user_id: this.getGenealogyUserId,
      }
      this.treeDataSource = null
      this.loadSponserDownlineListingData(query).then(() => {
        this.sponsorNetworkTreeData = this.getSponsorDownlineListing
        this.memberDetails =
          this.getSponsorDownlineListing.member_data !== undefined
            ? this.getSponsorDownlineListing.member_data.details
            : []
        this.treeDataSource = this.sponsorNetworkTreeData
        if (this.searchedUserName !== '') {
          this.filterTree()
        } else {
          this.updateContentWidth(0)
        }
      })
    },
    selectViewIbo(iboId, iboName) {
      if (this.viewIboId === '') {
        this.viewDataSource = JSON.parse(JSON.stringify(this.treeDataSource))
      }
      this.viewIboId = '' + iboId
      this.viewIboName = iboName
      let resultData = null
      if (iboId === this.sponsorNetworkTreeData.downlines[0].ibo_id) {
        resultData = JSON.parse(JSON.stringify(this.sponsorNetworkTreeData))
      } else {
        this.filterActiveItem = []
        this.recursiveSearch(this.sponsorNetworkTreeData.downlines[0], this.viewIboId, this.viewIboName, true, true)
        if (this.filterActiveItem.length === 0) {
          this.filterActiveItem.push(this.sponsorNetworkTreeData.downlines[0].ibo_id)
        }
        resultData = JSON.parse(JSON.stringify(this.sponsorNetworkTreeData))
        resultData.downlines[0] = this.recursiveRemove(resultData.downlines[0])
      }
      this.treeDataSource = resultData
      this.updateContentWidth(0)
    },
    removeViewIbo() {
      this.viewIboId = ''
      this.viewIboName = ''
      this.treeDataSource = JSON.parse(JSON.stringify(this.viewDataSource))
      this.viewDataSource = null
      this.updateContentWidth(0)
    },
    filterTree() {
      if (!this.filterInAction) {
        this.treeDataSource = null
        this.filterInAction = true
        this.filterCurrentKey = this.searchedUserName
        let resultData = null
        if (this.filterCurrentKey !== '') {
          this.filterActiveItem = []
          this.recursiveSearch(
            this.sponsorNetworkTreeData.downlines[0],
            this.filterCurrentKey,
            this.filterCurrentKey,
            false,
            true
          )
          if (this.filterActiveItem.length === 0) {
            this.filterActiveItem.push(this.sponsorNetworkTreeData.downlines[0].ibo_id)
          }
          resultData = JSON.parse(JSON.stringify(this.sponsorNetworkTreeData))
          resultData.downlines[0] = this.recursiveRemove(resultData.downlines[0])
        } else {
          resultData = this.sponsorNetworkTreeData
        }
        this.filterInAction = false
        if (this.filterCurrentKey !== this.searchedUserName) {
          this.filterTree() // input changed during filtering, so filter again
        } else {
          this.treeDataSource = resultData
          this.updateContentWidth(0)
        }
      }
    },
    recursiveRemove(dataSource) {
      if (
        typeof dataSource.children !== 'undefined' &&
        dataSource.children !== null &&
        dataSource.children.length > 0
      ) {
        for (let index = dataSource.children.length - 1; index >= 0; index--) {
          if (this.filterActiveItem.indexOf(dataSource.children[index].ibo_id) < 0) {
            dataSource.children.splice(index, 1)
          } else {
            dataSource.children[index] = this.recursiveRemove(dataSource.children[index])
          }
        }
      }
      return dataSource
    },
    recursiveSearch(dataSource, searchID, searchName, exactMatch, searching) {
      let returnValue = false
      if (
        typeof dataSource.children !== 'undefined' &&
        dataSource.children !== null &&
        dataSource.children.length > 0
      ) {
        if (searching) {
          dataSource.children.forEach((item, index) => {
            let isMatch = false
            let iboId = '' + item.ibo_id
            if (exactMatch) {
              if (
                iboId.toUpperCase() === searchID.toUpperCase() &&
                item.ibo_name.toUpperCase() === searchName.toUpperCase()
              ) {
                isMatch = true
              }
            } else {
              if (
                iboId.toUpperCase().indexOf(searchID.toUpperCase()) >= 0 ||
                item.ibo_name.toUpperCase().indexOf(searchName.toUpperCase()) >= 0
              ) {
                isMatch = true
              }
            }
            if (isMatch) {
              returnValue = true
              if (this.filterActiveItem.indexOf(item.ibo_id) < 0) {
                this.filterActiveItem.push(item.ibo_id)
              }
              this.recursiveSearch(item, searchID, searchName, exactMatch, false)
            } else {
              let searchResult = this.recursiveSearch(item, searchID, searchName, exactMatch, true)
              if (searchResult === true) {
                returnValue = true
              }
            }
          })
          if (returnValue === true) {
            if (this.filterActiveItem.indexOf(dataSource.ibo_id) < 0) {
              this.filterActiveItem.push(dataSource.ibo_id)
            }
          }
        } else {
          dataSource.children.forEach((item, index) => {
            if (this.filterActiveItem.indexOf(item.ibo_id) < 0) {
              this.filterActiveItem.push(item.ibo_id)
            }
            this.recursiveSearch(item, searchID, searchName, exactMatch, false)
          })
        }
      }
      return returnValue
    },
    calculateTreeMaxDepth(dataSource, currentDepth) {
      if (currentDepth > this.treeMaxDepth) {
        this.treeMaxDepth = currentDepth
      }
      if (
        typeof dataSource.children !== 'undefined' &&
        dataSource.children !== null &&
        dataSource.children.length > 0
      ) {
        dataSource.children.forEach((item, index) => {
          this.calculateTreeMaxDepth(item, currentDepth + 1)
        })
      }
    },
    updateContentWidth(iteration) {
      let masterContainer = document.getElementsByClassName('genealogy-tree-base-container')
      let masterWrapper = document.getElementsByClassName('genealogy-tree-base-wrapper')
      if (masterContainer.length > 0 && masterWrapper.length > 0) {
        let inx = 0
        let minLeftWidth = 0
        let minRightWidth = 0
        let objs = document.getElementsByClassName('genealogy-tree-item-left')
        for (inx = 0; inx < objs.length; inx++) {
          if (objs[inx].clientWidth > minLeftWidth) {
            minLeftWidth = objs[inx].clientWidth
          }
        }
        objs = document.getElementsByClassName('genealogy-tree-item-right')
        for (inx = 0; inx < objs.length; inx++) {
          if (objs[inx].clientWidth > minRightWidth) {
            minRightWidth = objs[inx].clientWidth
          }
        }
        this.treeMaxDepth = 0
        this.calculateTreeMaxDepth(this.treeDataSource.downlines[0], 1)
        let newWidth = minLeftWidth + minRightWidth + this.treeMaxDepth * 25
        let maxWidth = masterContainer[0].clientWidth
        this.minContentWidth = newWidth
        if (maxWidth > newWidth) {
          newWidth = maxWidth
        }
        masterWrapper[0].style.width = newWidth + 'px'
      } else {
        if (iteration < 50) {
          setTimeout(() => {
            this.updateContentWidth(iteration + 1)
          }, 500)
        }
      }
    },
    refreshContentWidth() {
      if (this.minContentWidth > 0) {
        let masterContainer = document.getElementsByClassName('genealogy-tree-base-container')
        let masterWrapper = document.getElementsByClassName('genealogy-tree-base-wrapper')
        if (masterContainer.length > 0 && masterWrapper.length > 0) {
          let maxWidth = masterContainer[0].clientWidth
          if (maxWidth > this.minContentWidth) {
            masterWrapper[0].style.width = maxWidth + 'px'
          } else if (masterWrapper[0].clientWidth !== this.minContentWidth) {
            masterWrapper[0].style.width = this.minContentWidth + 'px'
          }
        }
      }
    },
    resizeEventHandler(event) {
      this.refreshContentWidth()
      setTimeout(() => {
        this.refreshContentWidth()
      }, 500)
    },
    clearSearchInput() {
      this.viewIboId = ''
      this.viewIboName = ''
      this.downlineNotFound = false
      this.selectedDownline = ''
      this.searchedUserId = null
      this.searchedUserName = ''
      this.populateSponsorNetworkTree()
    },
    searchDownline(val) {
      this.searchedUserId = val.user_id
      this.searchedUserName = val.name
      this.selectedDownline = val.user.old_member_id
      this.populateSponsorNetworkTree()
      this.selectViewIbo(this.selectedDownline, this.searchedUserName)
    },
    iboError(errorObj) {
      if (errorObj.items.length > 0) {
        let temp = errorObj.items.find(function(obj) {
          return obj.field === 'searchIBOID'
        })
        if (typeof temp !== 'undefined' && temp.hasOwnProperty('rule')) {
          return this.$t('Genealogy.SponsorNetworkTree.Search.PleaseInsertIBOID')
        }
      }
      return ''
    },
  },
  computed: {
    ...mapGetters([
      'isLoading',
      'getGenealogyUserId',
      'getSponsorDownlineListing',
      'getMemberDashboard',
      'getMemberList',
      'getDashboardUpdatedAt',
    ]),
  },
  watch: {
    selectedDownline() {
      if (this.downlineNotFound) {
        this.downlineNotFound = false
      }
    },
  },
}
</script>
