<template>
  <div class="snt-shipping">
    <slot v-bind="slotProps">
      <v-container class="snt-shipping__container">
        <div class="snt-shipping__title">
          <span>
            วิธีการจัดส่ง
          </span>
        </div>
        <div class="snt-shipping__text">
          <div class="snt-shipping-text">
            <v-select
              :value="shipping"
              :items="shippingList"
              :loading="loading"
              class="snt-shipping__input"
              item-text="name"
              placeholder="เลือกวิธีจัดส่ง"
              return-object
              outlined
              dense
              hide-details
              @change="selectShipping($event)" />
            <span class="snt-shipping__price">
              {{ shippingFee | toLocaleString }} บาท
            </span>
          </div>
        </div>
      </v-container>
    </slot>
  </div>
</template>

<script>
import {
  GET_SALEPAGE_SHIPPING,
  GET_SHIPPING_CALCULATORS
} from '@/resources/graphql'
import { mapActions, mapGetters } from 'vuex'

export default {
  name: 'SntShipping',
  props: {
    autoSelectFirst: {
      type: Boolean,
      default: false
    }
  },
  apollo: {
    shippingList: () => ({
      fetchPolicy: 'network-only',
      query () {
        return this.isDemo ? GET_SHIPPING_CALCULATORS : GET_SALEPAGE_SHIPPING
      },
      variables () {
        return this.isDemo
          ? {
              page: 1,
              perPage: 50
            }
          : {
              domain: this.subdomain,
              input: {
                purchases: this.purchases
              }
            }
      },
      update (data) {
        const items = this.isDemo
          ? this.$_.map(data.shippingCalculators.nodes, ({ shippingType: name, cost, type }) => ({ name, cost, type }))
          : this.$_.map(data.salePage.shippingList, ({ name, cost, type }) => ({ name, cost, type }))

        const shippings = []
        const suffixCod = 'COD'
        items.forEach((item) => {
          const words = item.name.split(' ')
          const isCod = this.$_.includes(words, suffixCod)
          const filteredWords = this.$_.filter(words, (str) => str !== suffixCod)
          let name = filteredWords.join(' ')
          if (!name && isCod) {
            name = suffixCod
          }
          const value = {
            name,
            cost: item.cost,
            codCost: item.cost,
            type: item.type,
            isCod
          }
          const shipping = shippings.find((ship) => ship.name === value.name)
          if (!shipping) {
            shippings.push(value)
          } else {
            shipping.codCost = isCod ? item.cost : shipping.codCost
            shipping.isCod = isCod || shipping.isCod
          }
        })
        return shippings
      },
      result ({ data }) {
        if (!this.isDemo) {
          let shipping = null
          if (!this.shipping.name) {
            shipping = this.shippingList.find((ship) => ship.name === data.salePage.stock.shop.defaultShippingType)
          } else {
            shipping = this.shippingList.find((ship) => ship.name === this.shipping.name)
          }
          if (shipping) {
            this.selectShipping(shipping)
          }
        }
      }
    })
  },
  data () {
    return {
      shippingList: []
    }
  },
  computed: {
    ...mapGetters({
      subdomain: 'salePage/subdomain',
      checkout: 'salePage/checkout',
      selectedPurchase: 'cart/selected'
    }),
    isDemo () {
      return !this.subdomain
    },
    loading () {
      return this.$apollo.queries.shippingList.loading
    },
    shipping () {
      return this.checkout.shipping
    },
    paymentMethod () {
      return this.checkout.paymentMethod
    },
    shippingFee () {
      return this.paymentMethod === 1 ? this.shipping?.codCost : this.shipping?.cost
    },
    purchases () {
      const purchases = []
      // todo: ต้องเซตสินค้าด้วยไหม
      this.selectedPurchase.forEach((item) => {
        if (item.__typename === 'Purchase') {
          purchases.push({
            subproductId: item.id,
            quantity: item.quantity,
            price: item.price
          })
        }
      })
      return purchases
    },
    slotProps () {
      return {
        items: this.shippingList,
        value: this.shipping,
        loading: this.loading,
        selectShipping: this.selectShipping,
        isShippingSelected: this.isShippingSelected
      }
    }
  },
  methods: {
    ...mapActions({
      setCheckout: 'salePage/setCheckout'
    }),
    isShippingSelected (shipping) {
      return this.shipping.name === shipping.name
    },
    selectShipping (shipping) {
      this.setCheckout({
        shipping,
        paymentMethod: this.$_.isEqual(this.shipping, shipping) ? this.paymentMethod : null
      })
      this.$emit('input', shipping)
    }
  }
}
</script>

<style scoped>
  .snt-shipping {
    background-color: #FFFFFF;
  }
  .snt-shipping__title {
    font-weight: 500;
    margin-bottom: 16px;
  }
  .snt-shipping-text {
    display: flex;
    align-items: center;
  }
  .snt-shipping__input {
    max-width: 300px;
  }
  .snt-shipping__price {
    margin: 0 16px;
    white-space: nowrap;
  }
</style>
