import Vue from 'vue'
import './SntCart.scss'
import { mapActions, mapGetters } from 'vuex'
import { VDataTable, VProgressCircular, VDivider, VImg } from 'vuetify/lib'
import { GET_SALEPAGE_CALC_PRICE } from '../../resources/graphql'

export default Vue.extend({
  name: 'SntCart',
  components: { VDataTable, VProgressCircular, VDivider, VImg },
  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
          }))
      }
    })
  },
  props: {
    noHeader: {
      type: Boolean,
      default: false
    },
    noAction: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      products: [],
      headers: [
        {
          text: '',
          align: 'start',
          sortable: false,
          value: 'src',
          width: '150px'
        },
        {
          text: 'ชื่อ',
          align: 'start',
          sortable: false,
          value: 'name',
          width: '350px'
        },
        {
          text: 'ราคา',
          align: 'start',
          sortable: false,
          value: 'price'
        },
        {
          text: 'จำนวน',
          align: 'start',
          sortable: false,
          value: 'buy'
        },
        {
          text: 'ราคารวม',
          align: 'right',
          sortable: false,
          value: 'sum'
        },
        {
          text: '',
          align: 'start',
          sortable: false,
          value: 'delete'
        }
      ]
    }
  },
  computed: {
    ...mapGetters({
      subdomain: 'salePage/subdomain',
      customer: 'salePage/customer',
      cart: 'cart/cart',
      selected: 'cart/selected'
    }),
    isDemo  () {
      return !this.subdomain
    },
    customerId () {
      return this.customer?.id
    },
    isAuth () {
      return !!this.customerId
    },
    loading () {
      return this.$apollo.queries.products.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
        )
      ) || []
    },
    totalPrice () {
      return this.selectedPurchase.reduce((total, purchase) => total + ((purchase.price - purchase.discount) * purchase.quantity), 0)
    },
    selectedAll () {
      return this.cart.length === this.selectedPurchase.length
    },
    slotProps () {
      return {
        loading: this.loading,
        items: this.cartProducts,
        selectedPurchase: this.selectedPurchase,
        remove: this.remove,
        selectQuantity: this.selectQuantity,
        selectedAll: this.selectedAll,
        totalPrice: this.totalPrice
      }
    }
  },
  methods: {
    ...mapActions({
      updatePurchases: 'cart/updatePurchases',
      updateSetPurchases: 'cart/updateSetPurchases',
      deletePurchases: 'cart/deletePurchases',
      deleteSetPurchases: 'cart/deleteSetPurchases',
      setSelectedPurchase: 'cart/setSelected'
    }),
    selectPurchaseAll (value) {
      if (!value) {
        this.setSelectedPurchase([])
      } else {
        this.setSelectedPurchase(this.cart)
      }
    },
    selectePurchase (items) {
      this.setSelectedPurchase(items)
    },
    selectQuantity (item, value) {
      if (item.__typename === 'Purchase') {
        this.updatePurchases({
          id: item.id,
          quantity: value ? Number(value) : 1
        })
      } else {
        this.updateSetPurchases({
          id: item.id,
          quantity: value ? Number(value) : 1
        })
      }
    },
    remove (item) {
      const selectedPurchase = this.$_.cloneDeep(this.selectedPurchase)
      const index = selectedPurchase.findIndex((e) => e.id === item.id)
      if (index !== -1) {
        selectedPurchase.splice(index, 1)
        this.selectePurchase(selectedPurchase)
      }
      if (item.__typename === 'Purchase') {
        this.deletePurchases(item)
      } else {
        this.deleteSetPurchases(item)
      }
    }
  },
  template: `
    <div class="snt-cart">
      <slot v-bind="slotProps">
        <snt-container class="snt-cart__container">
          <div class="snt-cart__title">
            <slot name="header">
              <div class="snt-cart-title">
                ตะกร้าสินค้า
              </div>
            </slot>
          </div>
          <div
            v-if="!!cartProducts.length"
            class="snt-cart__items">
            <slot
              v-bind="slotProps"
              name="items">
              <v-data-table
                :value="selectedPurchase"
                :headers="headers"
                :items="cartProducts"
                :mobile-breakpoint="0"
                class="snt-cart-items__table"
                show-select
                hide-default-header
                hide-default-footer
                @input="selectePurchase($event)">
                <template #header="{ props }">
                  <thead>
                    <tr>
                      <td
                        v-for="(header, i) in props.headers"
                        :key="'header-'+i"
                        :align="header.align"
                        class="snt-cart-items__td">
                        <div v-if="i === 0">
                          <snt-checkbox
                            :value="selectedAll"
                            :ripple="false"
                            @input="selectPurchaseAll($event)" />
                        </div>
                        <div v-else>
                          {{ header.text }}
                        </div>
                      </td>
                    </tr>
                  </thead>
                </template>
                <template v-slot:item.src="{ item }">
                  <v-img
                    :src="item.pictureUrl"
                    max-width="100"
                    height="100" />
                </template>
                <template v-slot:item.name="{ item }">
                  <div class="snt-cart-items__name">
                    {{ item.name }}
                  </div>
                </template>
                <template v-slot:item.price="{ item }">
                  <span
                    :class="{ 'snt-cart-items__discount': item.discount }"
                    class="snt-cart-items__price">
                    {{ item.price | toLocaleString }} บาท
                  </span>
                  <span
                    v-if="item.discount"
                    class="snt-cart-items__price">
                    {{ (item.price - item.discount) | toLocaleString }} บาท
                  </span>
                </template>
                <template v-slot:item.buy="{ item }">
                  <div class="snt-cart-items__quantity">
                    <snt-number-field
                      :value="item.quantity"
                      :min="1"
                      :max="item.available"
                      controls
                      center
                      @input="selectQuantity(item, $event)" />
                  </div>
                </template>
                <template v-slot:item.sum="{ item }">
                  <span class="snt-cart-items__sum">
                    {{ (item.price - item.discount) * item.quantity | toLocaleString }} บาท
                  </span>
                </template>
                <template v-slot:item.delete="{ item }">
                  <snt-button
                    :ripple="false"
                    plain
                    text
                    @click="remove(item)">
                    ลบ
                  </snt-button>
                </template>
              </v-data-table>
            </slot>
            <slot
              name="action"
              :selectedPurchase="selectedPurchase"
              :totalPrice="totalPrice">
              <v-divider class="snt-cart__divider" />
              <div class="snt-cart-action">
                <div class="snt-cart-action__net-price">
                  <div class="snt-cart-action__net-price-title">
                    ราคารวมสินค้าทั้งหมด
                  </div>
                  <div class="snt-cart-action__net-price-text">
                    <v-progress-circular
                      v-if="loading"
                      :size="14"
                      :width="1"
                      color="secondary"
                      indeterminate
                    />
                    <div v-else>
                      {{ totalPrice | toLocaleString }} บาท
                    </div>
                  </div>
                </div>
                <snt-button
                  :to="{ name: 'SalePageCheckout' }"
                  :disabled="!selectedPurchase.length"
                  class="snt-cart-action__submit"
                  color="primary"
                  depressed
                  large>
                  สั่งสินค้า
                </snt-button>
              </div>
            </slot>
          </div>
          <div
            v-else
            class="snt-cart__no-data">
            <slot name="no-data">
              <div class="snt-cart-no-data">
                <div class="snt-cart-no-data">
                  <snt-icon
                    icon="mdi-cart-variant"
                    size="64" />
                  <div class="snt-cart-no-data__title">
                    ยังไม่มีสินค้าในตะกร้า
                  </div>
                  <snt-button
                    :to="{ name: 'SalePageProducts' }"
                    class="snt-cart__submit"
                    color="primary"
                    depressed
                    large>
                    ไปซื้อสินค้า
                  </snt-button>
                </div>
              </div>
            </slot>
          </div>
        </snt-container>
      </slot>
    </div>
  `
})
