<template>
  <div
    class="vh-50 d-flex justify-content-center align-items-center"
    v-if="getErrors('genealogy_sponsor_downline_listing_loading') || getErrors('enrolmentRankLoading')"
  >
    <div class="p-5 lifted bg-white text-center">
      <h2>{{ $t('Common.UnexpectedErrorHeader.Title') }}</h2>
      <p>{{ $t('Common.UnexpectedErrorHeader.Msg') }}</p>
    </div>
  </div>
  <div v-else class="genealogy">
    <b-container fluid class="border bg-white pt-3 auth-load">
      <b-row>
        <b-col class="my-1 col-12 col-xs-6 col-sm-7 col-lg-8 col-xl-9">
          <div class="d-inline-block mr-1">
            {{ $t('Common.ActiveUntil') }}
          </div>
          <div class="d-inline-block">
            <b-form-select
              v-model="selectedActiveExpiring"
              :options="activeExpiringOptions"
              @input="populateActiveExpiringMember"
              :disabled="tableDataSource === null"
            />
          </div>
        </b-col>
        <b-col class="my-1 col-12 col-xs-6 col-sm-5 col-lg-4 col-xl-3">
          <b-input-group class="w-100" v-if="selectedActiveExpiring === null">
            <b-form-input
              v-model="searchMember"
              :placeholder="$t('Genealogy.SponsorDownlineListing.SearchDownline')"
              :disabled="tableDataSource === null"
            />
            <b-input-group-append>
              <div class="d-flex p-0 justify-content-between align-items-center">
                <b-btn variant="primary" @click="searchSponsorDownlineMember" :disabled="tableDataSource === null">
                  <icon name="search" />
                </b-btn>
              </div>
            </b-input-group-append>
          </b-input-group>
          <b-btn class="float-right" variant="primary" @click="resetActiveExpiring" v-else>
            {{ $t('Genealogy.SponsorDownlineListing.ActiveExpiring.Back') }}
          </b-btn>
        </b-col>
      </b-row>
      <b-row>
        <b-col class="pt-1">
          <div class="d-flex flex-wrap justify-content-start align-items-center px-3 py-2 mt-2 bg-light">
            <div class="d-flex" v-for="(model, index) in drillDownDataSource" :key="index">
              <div class="d-inline-block px-2" v-if="index !== 0">
                /
              </div>
              <b-link class="d-inline-block" @click="drillTo(index)" :title="model.ibo_name">
                {{ model.ibo_id }}
              </b-link>
            </div>
            &nbsp;
          </div>
        </b-col>
      </b-row>
      <b-row>
        <b-col class="col-12 pt-3 overflow-x-auto">
          <div class="d-flex justify-content-center align-items-center py-5" v-if="tableDataSource === null">
            <icon class="icon-size-4" name="spinner" pulse />
          </div>
          <table class="table" v-else>
            <thead>
              <tr>
                <th scope="col" class="border-left border-right border-top text-left">
                  &nbsp;
                </th>
                <th scope="col" class="border-left border-right border-top text-left align-middle">
                  {{ $t('Common.IboId') }}
                </th>
                <th scope="col" class="border-left border-right border-top text-left align-middle">
                  {{ $t('Common.IboName') }}
                </th>
                <th scope="col" class="border-left border-right border-top text-left align-middle">
                  {{ $t('Common.Terminology.PersonalSalesPV') }}
                </th>
                <th scope="col" class="border-left border-right border-top text-left align-middle">
                  {{ $t('Genealogy.SponsorDownlineListing.TableHeader.HasActiveDownline') }}
                </th>
                <th scope="col" class="border-left border-right border-top text-left align-middle">
                  {{ $t('Genealogy.SponsorDownlineListing.TableHeader.TotalActiveLeftDownlines') }}
                </th>
                <th scope="col" class="border-left border-right border-top text-left align-middle">
                  {{ $t('Genealogy.SponsorDownlineListing.TableHeader.TotalActiveRightDownlines') }}
                </th>
                <th scope="col" class="border-left border-right border-top text-left align-middle">
                  {{ $t('Genealogy.SponsorDownlineListing.TableHeader.PlacementPosition') }}
                </th>
                <th scope="col" class="border-left border-right border-top text-left align-middle">
                  {{ $t('Genealogy.SponsorDownlineListing.TableHeader.GcvPowerLeg') }}
                </th>
                <th scope="col" class="border-left border-right border-top text-left align-middle">
                  {{ $t('Genealogy.SponsorDownlineListing.TableHeader.GcvPayLeg') }}
                </th>
                <th scope="col" class="border-left border-right border-top text-left align-middle">
                  {{ $t('Genealogy.SponsorDownlineListing.TableHeader.NumberOfDirectDownline') }}
                </th>
                <th scope="col" class="border-left border-right border-top text-left align-middle">
                  {{ $t('Genealogy.SponsorDownlineListing.TableHeader.NumberOfTotalDownline') }}
                </th>
                <th scope="col" class="border-left border-right border-top text-left align-middle">
                  {{ $t('Common.Terminology.PaidAsRank') }}
                </th>
                <th scope="col" class="border-left border-right border-top text-left align-middle">
                  {{ $t('Common.Terminology.EnrollmentRank') }}
                </th>
                <th scope="col" class="border-left border-right border-top text-left align-middle">
                  {{ $t('Common.HighestRank') }}
                </th>
                <th scope="col" class="border-left border-right border-top text-left align-middle">
                  {{ $t('Common.ActiveUntil') }}
                </th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(model, index) in tableDataSource" :key="index">
                <td class="border-left border-right border-bottom align-middle">
                  <div
                    class="genealogy-tree-icon-status-user-container"
                    v-if="model.depth === null || model.depth <= 0"
                  >
                    <icon class="genealogy-tree-icon-status-user" name="user-circle" />
                  </div>
                  <div class="genealogy-tree-icon-status-active" v-else-if="isStatusActive(model)">
                    {{ model.depth }}
                  </div>
                  <div class="genealogy-tree-icon-status-inactive" v-else-if="isStatusInactive(model)">
                    {{ model.depth }}
                  </div>
                  <div class="genealogy-tree-icon-status-other" v-else-if="!isStatusInactive(model)">
                    {{ model.depth }}
                  </div>
                </td>
                <td class="border-left border-right border-bottom align-middle">
                  <b-link @click="drillDown(model)" v-if="selectedActiveExpiring === null">
                    {{ model.ibo_id }}
                  </b-link>
                  <div :class="getTreeItemMemberClass(model, 'c-auto')" v-else>
                    {{ model.ibo_id }}
                  </div>
                </td>
                <td class="border-left border-right border-bottom align-middle">
                  <div
                    :class="getTreeItemMemberClass(model, '')"
                    @click="drillDown(model)"
                    v-if="selectedActiveExpiring === null"
                  >
                    {{ model.ibo_name }}
                  </div>
                  <div :class="getTreeItemMemberClass(model, 'c-auto')" v-else>
                    {{ model.ibo_name }}
                  </div>
                </td>
                <td
                  class="border-left border-right border-bottom align-middle"
                  :style="
                    `color: ${(model.personal_sales_cv_label_hex_color_code === undefined && 'unset') ||
                      '#' + model.personal_sales_cv_label_hex_color_code}`
                  "
                >
                  {{ typeof model.personal_sales_cv !== 'undefined' ? model.personal_sales_cv : 0.0 }}
                </td>
                <td class="border-left border-right border-bottom align-middle">
                  {{ hasActiveDownline(model) }}
                </td>
                <td class="border-left border-right border-bottom align-middle">
                  {{ typeof model.total_active_left_downlines !== 'undefined' ? model.total_active_left_downlines : 0 }}
                </td>
                <td class="border-left border-right border-bottom align-middle">
                  {{
                    typeof model.total_active_right_downlines !== 'undefined' ? model.total_active_right_downlines : 0
                  }}
                </td>
                <td class="border-left border-right border-bottom align-middle">
                  {{ getTreeItemMemberPlacementPosition(model) }}
                </td>
                <td class="border-left border-right border-bottom align-middle">
                  <span>
                    {{ getPosition(model.power_leg_position) }}
                    {{ model.power_leg_acc_gcv || 0 }}
                  </span>
                </td>
                <td class="border-left border-right border-bottom align-middle">
                  <span>
                    {{ getPosition(model.pay_leg_position) }}
                    {{ model.pay_leg_acc_gcv || 0 }}
                  </span>
                </td>
                <td class="border-left border-right border-bottom align-middle">
                  {{ typeof model.total_direct_downlines !== 'undefined' ? model.total_direct_downlines : 0 }}
                </td>
                <td class="border-left border-right border-bottom align-middle">
                  {{ typeof model.total_downlines !== 'undefined' ? model.total_downlines : 0 }}
                </td>
                <td class="border-left border-right border-bottom align-middle">
                  {{ fallbackToBA(model.effective_rank_code, model.enrollment_rank) }}
                </td>
                <td class="border-left border-right border-bottom align-middle">
                  {{ model.enrollment_rank }}
                </td>
                <td class="border-left border-right border-bottom align-middle">
                  {{ model.highest_rank_code }}
                </td>
                <td class="border-left border-right border-bottom align-middle no-wrap">
                  {{ typeof model.active_until_cw !== 'undefined' ? model.active_until_cw : '-' }}
                </td>
              </tr>
            </tbody>
          </table>
        </b-col>
      </b-row>
    </b-container>
    <b-modal
      ok-only
      hide-header
      centered
      size="sm"
      class="eshop-model"
      ref="member_search_notice"
      @ok="closeMemberSearchNotice"
    >
      <div v-if="searchDataSource.length === 0">
        {{ $t('Report.Notice.MemberSearchEmptyNotice') }}
      </div>
      <div v-else>
        {{ $t('Report.Notice.MemberSearchNotice') }}
      </div>
    </b-modal>
  </div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
import _ from 'lodash'
export default {
  name: 'SponsorDownlineListing',
  data() {
    return {
      activeExpiringOptions: [
        { value: null, text: '', disabled: true },
        { value: 0, text: this.$t('Genealogy.SponsorDownlineListing.ActiveExpiring.0') },
        { value: 1, text: this.$t('Genealogy.SponsorDownlineListing.ActiveExpiring.1') },
        { value: 2, text: this.$t('Genealogy.SponsorDownlineListing.ActiveExpiring.2') },
        { value: 3, text: this.$t('Genealogy.SponsorDownlineListing.ActiveExpiring.3') },
        { value: 4, text: this.$t('Genealogy.SponsorDownlineListing.ActiveExpiring.4') },
        { value: 5, text: this.$t('Genealogy.SponsorDownlineListing.ActiveExpiring.5') },
      ],
      currentUserId: null,
      selectedActiveExpiring: null,
      searchMember: '',
      sponsorDownlineListingData: null,
      tableDataSource: [],
      drillDownDataSource: [],
      searchDataSource: [],
      backupTableDataSource: null,
      backupDrillDownDataSource: null,
    }
  },
  mounted() {
    this.loadEnrollmentRanks()
    this.populateSponsorDownlineListing()
  },
  methods: {
    ...mapActions(['loadSponserDownlineListingData', 'loadEnrollmentRanks']),
    getTreeItemMemberClass: function(modelObject, appendCss) {
      let className = ''
      if (modelObject.depth === null || modelObject.depth <= 0) {
        className = 'genealogy-tree-item-member-user'
      } else if (this.isStatusActive(modelObject)) {
        className = 'genealogy-tree-item-member-active'
      } else if (this.isStatusInactive(modelObject)) {
        className = 'genealogy-tree-item-member-inactive'
      } else if (!this.isStatusInactive(modelObject)) {
        className = 'genealogy-tree-item-member-other'
      }
      return className + ' ' + appendCss
    },
    populateSponsorDownlineListing() {
      this.tableDataSource = []
      this.drillDownDataSource = []
      this.searchDataSource = []
      this.loadSponserDownlineListingData({}).then(() => {
        this.sponsorDownlineListingData = this.getSponsorDownlineListing
        if (!_.isEmpty(this.sponsorDownlineListingData)) {
          this.tableDataSource = this.sponsorDownlineListingData.downlines
          if (typeof this.sponsorDownlineListingData.member_data.details !== 'undefined') {
            this.currentUserId = this.sponsorDownlineListingData.member_data.details.user_id
          }
        }
      })
    },
    drillDown(model) {
      this.drillDownDataSource.push(model)
      this.tableDataSource = model.children
    },
    drillTo(index) {
      if (index > 0) {
        this.tableDataSource = this.drillDownDataSource[index - 1].children
        this.drillDownDataSource.splice(index, this.drillDownDataSource.length - index)
      } else {
        this.tableDataSource = this.sponsorDownlineListingData.downlines
        this.drillDownDataSource = []
      }
    },
    searchSponsorDownlineMember() {
      this.searchDataSource = []
      this.sponsorDownlineListingData.downlines.forEach((item, index) => {
        this.searchSponsorDownlineMemberRecursive(null, item, index, [])
      })
      if (this.searchDataSource.length === 1) {
        if (this.searchDataSource[0].tableDataSource === null) {
          this.tableDataSource = this.sponsorDownlineListingData.downlines
          this.drillDownDataSource = []
        } else {
          let dataSource = JSON.parse(JSON.stringify(this.searchDataSource[0].tableDataSource))
          for (let index = dataSource.children.length - 1; index >= 0; index--) {
            if (
              dataSource.children[index].ibo_id.toString().indexOf(this.searchMember) < 0 &&
              dataSource.children[index].ibo_name.toLowerCase().indexOf(this.searchMember.toLowerCase()) < 0
            ) {
              dataSource.children.splice(index, 1)
            }
          }
          this.drillDownDataSource = []
          let indexArray = this.searchDataSource[0].levelDataSource
          this.drillDownDataSource.push(this.sponsorDownlineListingData.downlines[indexArray[0]])
          let modelObject = this.drillDownDataSource[0]
          for (let index = 1; index < indexArray.length; index++) {
            this.drillDownDataSource.push(modelObject.children[indexArray[index]])
            modelObject = modelObject.children[indexArray[index]]
          }
          this.tableDataSource = dataSource.children
        }
      } else {
        this.$refs.member_search_notice.show()
      }
    },
    searchSponsorDownlineMemberRecursive(parentModel, model, modelIndex, level) {
      if (
        (parentModel !== null && model.ibo_id.toString().indexOf(this.searchMember) >= 0) ||
        model.ibo_name.toLowerCase().indexOf(this.searchMember.toLowerCase()) >= 0
      ) {
        this.searchDataSource.push({
          tableDataSource: parentModel,
          levelDataSource: level,
        })
      }
      if (typeof model.children !== 'undefined' && model.children !== null && model.children.length > 0) {
        let levelDataSource = JSON.parse(JSON.stringify(level))
        levelDataSource.push(modelIndex)
        model.children.forEach((item, index) => {
          this.searchSponsorDownlineMemberRecursive(model, item, index, levelDataSource)
        })
      }
    },
    closeMemberSearchNotice() {
      this.$refs.member_search_notice.hide()
    },
    populateActiveExpiringMember() {
      if (this.selectedActiveExpiring === null) {
        this.resetActiveExpiring()
      } else {
        this.searchDataSource = []
        this.sponsorDownlineListingData.downlines.forEach((item, index) => {
          this.populateActiveExpiringMemberRecursive(item)
        })
        if (this.backupTableDataSource === null && this.backupDrillDownDataSource === null) {
          this.backupTableDataSource = this.tableDataSource
          this.backupDrillDownDataSource = this.drillDownDataSource
        }
        this.tableDataSource = this.searchDataSource
        this.drillDownDataSource = []
        if (this.searchDataSource.length < 1) {
          this.$refs.member_search_notice.show()
        }
      }
    },
    populateActiveExpiringMemberRecursive(model) {
      if (model.active_expiring === this.selectedActiveExpiring) {
        this.searchDataSource.push(model)
      }
      if (typeof model.children !== 'undefined' && model.children !== null && model.children.length > 0) {
        model.children.forEach((item, index) => {
          this.populateActiveExpiringMemberRecursive(item)
        })
      }
    },
    resetActiveExpiring() {
      if (this.backupTableDataSource !== null && this.backupDrillDownDataSource !== null) {
        this.tableDataSource = this.backupTableDataSource
        this.drillDownDataSource = this.backupDrillDownDataSource
      }
      this.backupTableDataSource = null
      this.backupDrillDownDataSource = null
      this.selectedActiveExpiring = null
    },
    getTreeItemMemberPlacementPosition(modelObject) {
      if (typeof modelObject.sponsor_position !== 'undefined' && modelObject.sponsor_position !== null) {
        if (modelObject.sponsor_position === 1) {
          return this.$t('Genealogy.SponsorDownlineListing.PlacementPosition.Left')
        } else if (modelObject.sponsor_position === 2) {
          return this.$t('Genealogy.SponsorDownlineListing.PlacementPosition.Right')
        }
      }
      return ''
    },
    hasActiveDownline(modelObject) {
      let left =
        modelObject.total_active_left_downlines === undefined || modelObject.total_active_left_downlines === null
          ? 0
          : modelObject.total_active_left_downlines
      let right =
        modelObject.total_active_right_downlines === undefined || modelObject.total_active_right_downlines === null
          ? 0
          : modelObject.total_active_right_downlines
      return left + right > 0 ? this.$t('Common.Yes') : this.$t('Common.No')
    },
    isStatusActive(modelObject) {
      if (modelObject.is_active_brand_ambassador !== null) {
        return (
          modelObject.is_active_brand_ambassador === 1 &&
          modelObject.sales_activity_status !== null &&
          modelObject.sales_activity_status.toUpperCase() === 'ACTIVE'
        )
      }
      return false
    },
    isStatusInactive(modelObject) {
      if (modelObject.is_active_brand_ambassador === null || modelObject.is_active_brand_ambassador === 0) {
        return (
          modelObject.sales_activity_status !== null && modelObject.sales_activity_status.toUpperCase() === 'ACTIVE'
        )
      }
      return false
    },
    fallbackToBA(effectiveRankCode, enrolmentRankCode) {
      if (effectiveRankCode !== null) {
        return effectiveRankCode
      } else {
        let rank = this.getMemberEnrollmentRankList.find(rnk => rnk.rank_code === enrolmentRankCode)
        if (rank !== undefined && rank.enrollment_type_id === 1) {
          return this.$t('Genealogy.SponsorDownlineListing.EffectiveRank.BA')
        } else {
          return enrolmentRankCode
        }
      }
    },
    getRefreshText() {
      return this.$t('Common.RefreshPage.Text', {
        link: '<a href="#" onclick="window.location.reload(true);">' + this.$t('Common.Here') + '</a>',
      })
    },
    getPosition(pos) {
      return (pos === 1 && '(L)') || (pos === 2 && '(R)') || ''
    },
  },
  computed: {
    ...mapGetters(['getErrors', 'getSponsorDownlineListing', 'getMemberEnrollmentRankList']),
  },
}
</script>
