import Vue from 'vue'
import './SntAllProducts.scss'
import { mapActions, mapGetters } from 'vuex'
import { VChip, VProgressCircular } from 'vuetify/lib'
import {
  GET_PRODUCTS,
  GET_PRODUCTSETS,
  GET_PRODUCT_BRANDS,
  GET_PRODUCT_CATEGORIES,
  GET_SALEPAGE_PRODUCTS,
  GET_SALEPAGE_SETPRODUCTS,
  GET_SALEPAGE_PRODUCT_CATEGORIES,
  GET_SALEPAGE_PRODUCT_BRANDS
} from '../../resources/graphql'

export default Vue.extend({
  name: 'SntAllProducts',
  components: { VChip, VProgressCircular },
  apollo: {
    productCategories: {
      query () {
        if (this.isDemo) {
          return GET_PRODUCT_CATEGORIES
        }
        return GET_SALEPAGE_PRODUCT_CATEGORIES
      },
      variables () {
        if (this.isDemo) {
          return {}
        }
        return {
          domain: this.subdomain
        }
      },
      update (data) {
        if (this.isDemo) {
          return data.productCategories
        }
        return data.salePage.productCategoryList.nodes
      }
    },
    productBrands: {
      query () {
        if (this.isDemo) {
          return GET_PRODUCT_BRANDS
        }
        return GET_SALEPAGE_PRODUCT_BRANDS
      },
      variables () {
        if (this.isDemo) {
          return {}
        }
        return {
          domain: this.subdomain
        }
      },
      update (data) {
        if (this.isDemo) {
          return data.productBrands
        }
        return data.salePage.productBrandList.nodes
      }
    },
    products: () => ({
      fetchPolicy: 'network-only',
      query () {
        if (this.isDemo) {
          return this.isCollection ? GET_PRODUCTSETS : GET_PRODUCTS
        }
        return this.isCollection ? GET_SALEPAGE_SETPRODUCTS : GET_SALEPAGE_PRODUCTS
      },
      variables () {
        const filters = {}
        if (this.isDemo) {
          filters.stockId = this.stockId
          const categoryIdList = this.filters.categoryId
          const brandIdList = this.filters.brandId
          const matchs = []
          if (this.$_.isArray(categoryIdList)) {
            categoryIdList.forEach((cid) => {
              if (this.$_.isArray(brandIdList)) {
                brandIdList.forEach((bid) => {
                  matchs.push({
                    stockId: this.stockId,
                    categoryId: cid,
                    brandId: bid
                  })
                })
              } else {
                matchs.push({
                  stockId: this.stockId,
                  categoryId: cid
                })
              }
            })
          } else if (this.$_.isArray(brandIdList)) {
            brandIdList.forEach((bid) => {
              matchs.push({
                stockId: this.stockId,
                brandId: bid
              })
            })
          }
          if (this.$_.isArray(matchs) && matchs.length) {
            filters.OR = []
            const match = matchs.pop()
            filters.categoryId = match.categoryId
            filters.brandId = match.brandId
            matchs.forEach((value) => {
              filters.OR.push({
                stockId: this.stockId,
                categoryId: value.categoryId,
                brandId: value.brandId
              })
            })
          }
        } else {
          filters.domain = this.subdomain
        }
        return this.$_.defaults(filters, this.filters)
      },
      update (data) {
        if (this.isDemo) {
          return this.isCollection ? data.productSets : data.products
        }
        return this.isCollection ? data.salePage.productSetList : data.salePage.productList
      },
      result () {
        if (this.paging) {
          this.paging = false
          this.$shipnity.goTo(this.$refs.allproducts, { duration: 300, offset: 0 })
        }
      }
    })
  },
  props: {
    perPage: {
      type: [String, Number],
      default: 12
    },
    cols: {
      type: [Boolean, String, Number],
      default: undefined
    },
    lg: {
      type: [Boolean, String, Number],
      default: undefined
    },
    md: {
      type: [Boolean, String, Number],
      default: undefined
    },
    sm: {
      type: [Boolean, String, Number],
      default: undefined
    },
    xl: {
      type: [Boolean, String, Number],
      default: undefined
    }
  },
  data () {
    return {
      page: 1,
      paging: false,
      productCategories: [],
      productBrands: [],
      products: {
        nodes: [],
        nodesCount: 0,
        pagesCount: 0
      },
      sortItems: [
        {
          text: 'มาใหม่',
          value: 'id_DESC'
        },
        {
          text: 'สินค้าขายดี',
          value: 'sold_DESC'
        },
        {
          text: 'ราคาจาก น้อยไปมาก',
          value: 'price_ASC'
        },
        {
          text: 'ราคาจาก มากไปน้อย',
          value: 'price_DESC'
        }
      ]
    }
  },
  computed: {
    ...mapGetters({
      stockId: 'salePage/stockId',
      subdomain: 'salePage/subdomain'
    }),
    isDemo () {
      return !this.subdomain
    },
    isCollection () {
      return ['SalePageCollection', 'SalePageCategoryCollection'].includes(this.$route.name)
    },
    orderBy () {
      return this.$route.query?.orderBy || 'id_DESC'
    },
    search () {
      return this.$route.query?.search || ''
    },
    categoryId () {
      return this.$route.params?.categoryId || null
    },
    category () {
      return this.productCategories.find((item) => item.id === this.categoryId)
    },
    categoryName () {
      return this.category ? this.category.name : null
    },
    categories () {
      const categoryQuery = this.$route.query?.categoryId || null
      const categories = categoryQuery
        ? [this.categoryId, ...this.$_.split(categoryQuery, ',')]
        : [this.categoryId]
      return categories.filter((item) => !!item)
    },
    brands () {
      const brandQuery = this.$route.query?.brandId || null
      return brandQuery ? this.$_.split(brandQuery, ',') : []
    },
    filters () {
      const filters = {
        page: Number(this.page),
        perPage: Number(this.perPage),
        orderBy: this.orderBy
      }
      if (this.search) {
        filters.search = this.search
      }
      if (this.categoryId) {
        filters.categoryId = this.$_.uniq([this.categoryId, ...this.categories])
      }
      if (this.brands.length) {
        filters.brandId = [...this.brands]
      }
      return filters
    },
    loading () {
      return this.$apollo.queries.products.loading
    },
    allProducts () {
      return this.products.nodes.map((item) => ({
        ...item,
        routerLink: {
          name: this.isCollection ? 'SalePageCollectionDetail' : 'SalePageProductDetail',
          params: {
            productId: item.id
          }
        },
        isCollection: this.isCollection
      }))
    },
    slotProps () {
      return {
        isCollection: this.isCollection,
        loading: this.loading,
        items: this.allProducts,
        sortItems: this.sortItems,
        filters: this.filters,
        pagesCount: this.products.pagesCount,
        itemsCount: this.products.nodesCount,
        page: this.page,
        category: this.category,
        selectPage: this.setPage,
        selectOrderBy: this.changeOrderBy,
        selectCategories: this.changeCategories,
        selectBrands: this.changeBrands,
        selectProductType: this.changeProductType,
        addMainToCart: this.addMainToCart,
        props: {
          perPage: this.perPage
        }
      }
    }
  },
  watch: {
    isCollection () {
      this.setPage(1)
    }
  },
  methods: {
    ...mapActions({
      addToCart: 'cart/addToCart'
    }),
    getMain (item) {
      let subproducts = item?.subproducts || []
      subproducts = subproducts.filter()
      subproducts = subproducts.map((sub) => ({
        ...sub,
        selected: sub.id === this.selectedPurchase.id
      }))
      return subproducts
    },
    addMainToCart (item) {
      let name = item.name
      const subproducts = item?.subproducts || []
      const subproduct = this.$_.head(subproducts)
      if (!this.isCollection) {
        if (subproduct.name !== 'main') {
          name += ` (${subproduct.name})`
        }
      }
      this.addToCart({
        id: subproduct.id,
        price: subproduct.price,
        available: subproduct.available,
        name,
        pictureUrl: item.pictureUrl,
        isCollection: this.isCollection,
        quantity: 1
      })
      this.$shipnity.notification.success('เพิ่มสินค้าลงตะกร้า')
    },
    changeOrderBy (value) {
      this.$router.push({
        query: {
          ...this.$route.query,
          orderBy: value,
          search: this.search
        }
      })
    },
    changeCategories (categories) {
      if (categories.length) {
        const categoryId = categories.shift()
        const categoryQuery = this.$_.join(categories, ',')
        const category = this.productCategories.find((item) => item.id === categoryId)
        const routeName = this.isCollection ? 'SalePageCategoryCollection' : 'SalePageCategoryProducts'
        this.$router.push({
          name: routeName,
          params: {
            categoryId: category.id,
            categoryName: category.name
          },
          query: {
            ...this.$route.query,
            categoryId: categoryQuery
          }
        })
      } else if (this.categoryId) {
        this.$router.push({
          name: this.isCollection ? 'SalePageCollection' : 'SalePageProducts',
          query: {
            ...this.$route.query,
            categoryId: ''
          }
        })
      }
      this.setPage(1)
    },
    changeBrands (brands) {
      const brandQuery = this.$_.join(brands, ',')
      this.$router.push({
        query: {
          ...this.$route.query,
          brandId: brandQuery
        }
      })
      this.setPage(1)
    },
    setPage (page) {
      this.paging = true
      this.page = page
    }
  },
  template: `
    <div
      ref="allproducts"
      class="snt-all-products">
      <slot v-bind="slotProps">
        <snt-container class="snt-all-products__container">
          <div class="snt-all-products__title">
            <slot
              v-bind="slotProps"
              name="header">
              รายการสินค้า
            </slot>
          </div>
          <div class="snt-all-products__filter">
            <slot
              v-bind="slotProps"
              name="filter">
              <div class="snt-all-products__header">
                <v-chip
                  :to="{
                    name: categoryId ? 'SalePageCategoryProducts' : 'SalePageProducts',
                    query: $route.query
                  }"
                  :color="isCollection ? '#C4C4C4': 'primary'"
                  :dark="isCollection"
                  class="snt-all-products__chip">
                  สินค้า
                </v-chip>
                <v-chip
                  :to="{
                    name: categoryId ? 'SalePageCategoryCollection' : 'SalePageCollection',
                    query: $route.query
                  }"
                  :color="!isCollection ? '#C4C4C4': 'primary'"
                  :dark="!isCollection"
                  class="snt-all-products__chip">
                  สินค้าเซ็ต
                </v-chip>
              </div>
              <div class="d-flex">
                <snt-spacer />
                <div class="snt-all-products__orderby">
                  <snt-select
                    :value="orderBy"
                    :items="sortItems"
                    :menu-props="{
                      'origin': 'center center',
                      'transition':'slide-y-transition',
                      'nudge-top': '-2px',
                      'offset-y': true,
                      'attach': true
                    }"
                    placeholder="ราคา"
                    item-text="text"
                    item-value="value"
                    background-color="#ffffff"
                    class="snt-all-products__input"
                    attach
                    dense
                    outlined
                    hide-details
                    @change="changeOrderBy($event)">
                  </snt-select>
                </div>
              </div>
              <div class="d-flex justify-space-between flex-wrap mb-4">
                <div class="snt-all-products__search">
                  <snt-text-field
                    :value="search"
                    type="search"
                    placeholder="ค้นหา"
                    prepend-inner-icon="mdi-magnify"
                    class="snt-all-products__input"
                    autocomplete="off"
                    background-color="#ffffff"
                    dense
                    outlined
                    hide-details
                    @keydown.enter="$router.push({
                      query: {
                        ...$route.query,
                        search: $event.target.value
                      }
                    })">
                  </snt-text-field>
                </div>
                <div class="snt-all-products__catagories">
                  <snt-select
                    :value="categories"
                    :items="productCategories"
                    :menu-props="{
                      'origin': 'center center',
                      'transition':'slide-y-transition',
                      'nudge-top': '-2px',
                      'offset-y': true,
                      'attach': true
                    }"
                    placeholder="ประเภท"
                    item-text="name"
                    item-value="id"
                    background-color="#ffffff"
                    class="snt-all-products__input"
                    attach
                    dense
                    outlined
                    hide-details
                    chips
                    multiple
                    clearable
                    @change="changeCategories($event)">
                    <template #selection="{ item, index }">
                      <v-chip v-if="index < 1">
                        <span>{{ item.name || '-' }}</span>
                      </v-chip>
                      <span
                        v-if="index === 1"
                        class="grey--text text-caption">
                        (+{{ categories.length - 1 }} others)
                      </span>
                    </template>
                  </snt-select>
                </div>
                <div class="snt-all-products__brands">
                  <snt-select
                    :value="brands"
                    :items="productBrands"
                    :menu-props="{
                      'origin': 'center center',
                      'transition':'slide-y-transition',
                      'nudge-top': '-2px',
                      'offset-y': true,
                      'attach': true
                    }"
                    placeholder="ยี่ห้อ"
                    item-text="name"
                    item-value="id"
                    background-color="#ffffff"
                    class="snt-all-products__input"
                    attach
                    dense
                    outlined
                    hide-details
                    chips
                    multiple
                    clearable
                    @change="changeBrands($event)">
                    <template #selection="{ item, index }">
                      <v-chip v-if="index < 1">
                        <span>{{ item.name || '-' }}</span>
                      </v-chip>
                      <span
                        v-if="index === 1"
                        class="grey--text text-caption">
                        (+{{ brands.length - 1 }} others)
                      </span>
                    </template>
                  </snt-select>
                </div>
              </div>
            </slot>
          </div>
          <template v-if="loading">
            <slot name="loader">
              <div class="text-center">
                <v-progress-circular
                  :size="14"
                  :width="1"
                  color="secondary"
                  indeterminate
                />
              </div>
            </slot>
          </template>
          <template v-else>
            <snt-row>
              <snt-col
                v-for="(product, i) in allProducts"
                :key="'product-'+i"
                :cols="cols"
                :lg="lg"
                :md="md"
                :sm="sm"
                :xl="xl">
                <snt-product
                  :id="product.id"
                  :picture-url="product.pictureUrl || 'https://via.placeholder.com/400x400/ddd/fff?text=No Image'"
                  :name="product.name"
                  :sub-products="product.subproducts"
                  :description="product.description"
                  :price="product.price"
                  :stock="product.available"
                  :is-collection="isCollection"
                  :show-sku="!isCollection"
                  show-description
                  show-price
                  show-stock
                  show-cart>
                  <slot
                    :item="product"
                    :index="i"
                    name="item" />
                </snt-product>
              </snt-col>
            </snt-row>
            <div
              v-if="!products.nodesCount"
              class="snt-all-products__not-found">
              <slot
                v-bind="slotProps"
                name="no-data">
                <snt-icon
                icon="mdi-bag-personal-outline"
                size="64" />
                <div class="snt-all-products-not-found">
                  ไม่มีสินค้า
                </div>
              </slot>
            </div>
            <slot
              v-bind="slotProps"
              name="pagination">
              <template v-if="products.pagesCount > 1">
                <snt-pagination
                  :value="page"
                  :length="products.pagesCount"
                  :total-visible="7"
                  class="snt-all-products__pagination"
                  @input="setPage($event)" />
              </template>
            </slot>
          </template>
        </snt-container>
      </slot>
    </div>
  `
})
