import Vue from 'vue'
import './SntPromoCodes.scss'
import { VSpacer, VDialog, VChip, VProgressCircular } from 'vuetify/lib'
import { mapActions, mapGetters } from 'vuex'
import {
  GET_SALEPAGE_ALLPROMOCODES,
  GET_SALEPAGE_CALC_PRICE,
  GET_SALEPAGE_PROMOCODES
} from '../../resources/graphql'

export default Vue.extend({
  name: 'SntPromoCodes',
  components: { VSpacer, VDialog, VChip, VProgressCircular },
  apollo: {
    products: () => ({
      fetchPolicy: 'network-only',
      query: GET_SALEPAGE_CALC_PRICE,
      skip () {
        return this.isDemo || !this.isAuth
      },
      debounce: 800,
      variables () {
        return {
          domain: this.subdomain,
          customerId: this.customerId,
          purchases: this.cart
            .filter(({ __typename }) => __typename === 'Purchase')
            .map(({ id: subproductId, quantity, price }) => ({
              subproductId,
              quantity,
              price
            }))
        }
      },
      update ({ salePage }) {
        return salePage.calculatePrice
          .map(({ subproductId: id, name, price, quantity, discount }) => ({
            id,
            quantity,
            name,
            price,
            discount
          }))
      }
    }),
    promoCodeList: () => ({
      fetchPolicy: 'network-only',
      query () {
        return this.isAuth ? GET_SALEPAGE_ALLPROMOCODES : GET_SALEPAGE_PROMOCODES
      },
      skip () {
        return this.isDemo
      },
      variables () {
        const variables = {
          domain: this.subdomain,
          customerId: this.customerId,
          page: this.page,
          perPage: this.perPage
        }
        if (this.claimable) {
          variables.search = this.search
        }
        return variables
      },
      update ({ salePage }) {
        if (this.isAuth && this.claimable) {
          return salePage.findCustomer.activeClaimedPromoCodes
        }
        return salePage.promoCodeList
      }
    })
  },
  data () {
    return {
      dialog: false,
      claimable: false,
      search: '',
      products: [],
      promoCodeList: {
        nodes: [],
        nodesCount: 0,
        pagesCount: 0
      },
      page: 1,
      perPage: 12,
      filter: '',
      items: [
        {
          text: 'ทั้งหมด',
          value: ''
        },
        {
          text: 'ลดเป็นเปอร์เซ็นต์',
          value: 'percent'
        },
        {
          text: 'ลดเป็นบาท',
          value: 'baht'
        }
      ]
    }
  },
  computed: {
    ...mapGetters({
      subdomain: 'salePage/subdomain',
      customer: 'salePage/customer',
      checkout: 'salePage/checkout',
      cart: 'cart/cart',
      selected: 'cart/selected'
    }),
    isDemo  () {
      return !this.subdomain
    },
    customerId () {
      return this.customer?.id
    },
    isAuth () {
      return !!this.customerId
    },
    selectedCode () {
      return this.checkout.promocode
    },
    loading () {
      return this.$apollo.queries.promoCodeList.loading
    },
    cartProducts () {
      return this.cart.map((cartItem) => {
        let price = cartItem.price
        let discount = 0
        if (cartItem.__typename === 'Purchase') {
          const product = this.products.find((productItem) => productItem.id === cartItem.id)
          if (product) {
            price = product.price
            discount = product.discount
          }
        }
        return {
          ...cartItem,
          price,
          discount
        }
      })
    },
    selectedPurchase () {
      return this.cartProducts.filter(
        (cartItem) => this.selected.some(
          (selected) => cartItem.id === selected.id
          && cartItem.__type === selected.__type
        )
      ) || []
    },
    sumPurchaseQuantity () {
      return this.selectedPurchase.reduce((sum, item) => sum + item.quantity, 0)
    },
    sumPurchasePrice () {
      return this.selectedPurchase.reduce((sum, item) => sum + ((item.price - item.discount) * item.quantity), 0)
    },
    filteredPromoCodes () {
      const filteredPromoCodes = this.promoCodeList.nodes.filter((item) => item.claimable === this.claimable)
      if (this.claimable && this.filter) {
        return filteredPromoCodes.filter((item) => item.discountType === this.filter)
      }
      return filteredPromoCodes
    }
  },
  created () {
    this.debounceSetSearch = this.$_.debounce(this.setSearch, 500)
  },
  methods: {
    ...mapActions({
      setCheckout: 'salePage/setCheckout'
    }),
    setSearch (search) {
      this.search = search
    },
    setDialog (val) {
      this.dialog = val
    },
    isSelectedCode (promoCode) {
      return this.selectedCode.code === promoCode.code
    },
    setPromocodeType (val) {
      this.claimable = val
    },
    update (value) {
      this.setCheckout({
        promocode: value
      })
      this.$emit('update', value)
      this.setDialog(false)
    },
    setPage (page) {
      this.page = page
    },
    canUsePromoCodes (redeemType, redeemValue) {
      if (redeemType === 'count_value') {
        return redeemValue <= this.sumPurchasePrice
      }
      return redeemValue <= this.sumPurchaseQuantity
    },
    formatDiscountType (discountType) {
      if (discountType === 'baht') {
        return 'บาท'
      }
      return '%'
    },
    formatRedeemType (redeemType) {
      if (redeemType === 'count_value') {
        return 'บาท'
      }
      return 'ชิ้น'
    }
  },
  template: `
    <div class="snt-promocodes">
      <snt-container class="snt-promocodes__container">
        <v-dialog
          v-model="dialog"
          max-width="500">
          <template #activator="{ on, attrs }">
            <div class="d-flex align-center">
              <div class="snt-promocodes__title">
                <div class="snt-promocodes-title">
                  คูปองส่วนลด
                </div>
                <div
                  v-if="selectedCode.code"
                  class="snt-promocodes-content">
                  <div>{{ selectedCode.code }}</div>
                  <div>
                    ( ลดราคา {{ selectedCode.discountValue }}  {{ formatDiscountType(selectedCode.discountType) }} )
                  </div>
                </div>
              </div>
              <v-spacer />
              <snt-button
                v-bind="attrs"
                color="primary"
                depressed
                v-on="on">
                เลือก
              </snt-button>
            </div>
          </template>
          <div class="snt-promocodes-dialog">
            <snt-container class="snt-promocodes-dialog__container">
              <div class="snt-promocodes-dialog__title">
                <span> โค้ดส่วนลด </span>
                <v-spacer />
                <snt-icon
                  icon="mdi-close"
                  @click="setDialog(false)" />
              </div>
              <div class="snt-promocodes-dialog__text">
                <div class="snt-promocodes__chips">
                  <v-chip
                    class="snt-promocodes__chip"
                    :color="!claimable ? 'primary': '#C4C4C4'"
                    dark
                    depressed
                    @click="setPromocodeType(false)">
                    ใช้ได้ทันที
                  </v-chip>
                  <v-chip
                    v-if="isAuth"
                    class="snt-promocodes__chip"
                    :color="claimable ? 'primary': '#C4C4C4'"
                    dark
                    depressed
                    @click="setPromocodeType(true)">
                    ที่เก็บไว้
                  </v-chip>
                </div>
                <div
                  v-if="claimable"
                  class="snt-promocode-filters">
                  <snt-text-field
                    :value="search"
                    placeholder="ค้นหา"
                    prepend-inner-icon="mdi-magnify"
                    dense
                    outlined
                    hide-details
                    @input="debounceSetSearch($event)" />
                  <snt-select
                    v-model="filter"
                    :items="items"
                    item-text="text"
                    item-value="value"
                    dense
                    outlined
                    hide-details />
                </div>
                <div class="snt-promocodes__content">
                  <div
                    v-if="loading"
                    class="text-center">
                    <v-progress-circular
                      :size="14"
                      :width="1"
                      color="secondary"
                      indeterminate
                    />
                  </div>
                  <template v-else>
                    <div
                      v-if="filteredPromoCodes.length"
                      class="snt-promocodes__list">
                      <div
                        v-for="(promoCode, i) in filteredPromoCodes"
                        :key="'promocode-'+i"
                        class="snt-promocodes__list-card mb-4">
                        <div class="snt-promocodes__list-card-title">
                          <v-chip
                            class="snt-promocodes__list-card-text-discount"
                            color="error"
                            small
                            label>
                            ลดราคา {{ promoCode.discountValue }}
                            {{ formatDiscountType(promoCode.discountType) }}
                          </v-chip>
                          <v-chip
                            class="snt-promocodes__list-card-text-code"
                            color="warning"
                            small
                            label>
                            {{ promoCode.code }}
                          </v-chip>
                        </div>
                        <div class="snt-promocodes__list-card-text">
                          <div class="d-flex justify-space-between">
                            <div>
                              <div>
                                ใช้ {{ promoCode.pointUsed }} แต้ม
                                ซื้อขั้นต่ำอย่างน้อย {{ promoCode.minRedeemValue }} {{ formatRedeemType(promoCode.minRedeemType) }}
                              </div>
                              <div class="snt-promocodes__list-card-text-description">
                                ใช้ได้ถึงวันที่ {{ promoCode.endDate | formatTime }}
                              </div>
                            </div>
                            <div>
                              <div class="d-flex w-100">
                                <v-spacer />
                                <snt-button
                                  :disabled="isSelectedCode(promoCode) ||
                                    !canUsePromoCodes(promoCode.minRedeemType, promoCode.minRedeemValue)"
                                  class="snt-promocodes__list-card-text-use"
                                  color="primary"
                                  depressed
                                  @click="update(promoCode)">
                                  <snt-icon
                                    v-if="selectedCode.code === promoCode.code"
                                    icon="mdi-check"
                                    left />
                                  {{ canUsePromoCodes(promoCode.minRedeemType, promoCode.minRedeemValue) ? 'ใช้' : 'ใช้ไม่ได้' }}
                                </snt-button>
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                    <div
                      v-else
                      class="snt-promocodes__not-found">
                      <snt-icon
                        icon="mdi-sale"
                        size="32" />
                      <div class="snt-promocodes-not-found">
                        ไม่มีส่วนลด
                      </div>
                    </div>
                  </template>
                  <div class="snt-promocodes__footer">
                    <snt-button
                      v-if="!!selectedCode.code"
                      :ripple="false"
                      color="primary"
                      outlined
                      @click="update({
                        code: ''
                      })">
                      ไม่ใช้ส่วนลด
                    </snt-button>
                    <v-spacer />
                    <snt-pagination
                      v-if="promoCodeList.pagesCount > 1"
                      :value="page"
                      :length="promoCodeList.pagesCount"
                      :total-visible="7"
                      class="snt-promocodes__pagination"
                      @input="setPage($event)">
                    </snt-pagination>
                  </div>
                </div>
              </div>
            </snt-container>
          </div>
        </v-dialog>
      </snt-container>
    </div>
  `
})
