<template>
  <div class="sp-prod">
    <Row>
      <Col
        :span="24"
        class="sp-prod__toolbar"
      >
        <span class="sp-prod__loader">{{ productLoaderText }}</span>
        <Page
          v-model="pagging.current"
          :total="pagging.total"
          :page-size="pagging.limit"
          :model-value="pagging.current"
          show-sizer
          show-total
          :page-size-opts="pagging.size"
          @on-change="onPaggingChange"
          @on-page-size-change="onPaggingSize"
        />
      </Col>
      <Col :span="24">
        <Table
          ref="TableProductList"
          :loading="queryProduct.loading"
          :columns="tableProduct.columns"
          :data="tableProductRow"
          highlight-row
          size="small"
          height="800"
          border
          @on-sort-change="onSortTable"
          @on-selection="onSelectProduct"
          @on-selection-change="onSelectProduct"
        >
          <template
            slot="name"
            slot-scope="{ row }"
          >
            <a
              :href="row.sellerUrl"
              target="_blank"
              class="sp-prod__name"
              :class="{ 'is-unlisted': row.unlisted }"
            >
              {{ row.name | maxString(90) }}
            </a>
          </template>
          <template
            slot="image"
            slot-scope="{ row }"
          >
            <a
              :href="row.productUrl"
              target="_blank"
              class="sp-prod__thumb"
            >
              <img v-lazy="row.image + '_tn'">
            </a>
          </template>
          <template slot="action">
            Action
          </template>
        </Table>
        <div class="sp-prod__actions">
          <Button
            size="small"
            type="warning"
            ghost
            @click="reFetchProduct"
          >
            {{ $t('FETCH_PRODUCT_LIST') }}
          </Button>
        </div>
      </Col>
    </Row>
  </div>
</template>

<script>
import PromiseMap from 'p-map';
import lodash from 'lodash';
import arrayDedupe from 'array-dedupe';
import { shopeeSellerFetchProductList, getShopeeSellerProductId } from '@/api/shopee/seller/product';
import { tableProduct, renderTableProduct } from './mixin/Table';
import {
  CacheShopeeSellerProductList,
  CacheShopeeSellerProductId,
  CacheShopeeSellerProductTime,
} from '@/plugins/store/cache';

const clearProductCache = async () => Promise.all([
  CacheShopeeSellerProductList.destroy(),
  CacheShopeeSellerProductId.destroy(),
  CacheShopeeSellerProductTime.destroy(),
]);

export default {
  name: 'ShopeeSellerProductList',
  data() {
    return {
      listSelected: [],
      /** @type {ShopeeSellerProductId[]} */
      listProduct: [],
      queryProduct: {
        loading: false,
        total: 0,
        page: 0,
        limit: 40,
        cursor: '',
        fetchId: 0,
      },
      tableProduct: {
        columns: tableProduct.columns,
        rows: [],
      },
      pagging: {
        total: 0,
        current: 0,
        limit: 100,
        size: [10, 20, 50, 100, 500, 1000, 5000, 10000],
      },
    };
  },
  methods: {
    onSortTable({ key, order }) {
      this.tableProduct.rows = lodash.orderBy(this.tableProduct.rows, key, order);
      return false;
    },
    onSelectProduct(listSelected) {
      this.listSelected = listSelected;

      const listProduct = listSelected.map((metaProduct) => {
        const productData = this.listProduct.find(
          (product) => product.id === metaProduct.productId,
        );

        return {
          ...productData,
          meta: metaProduct,
        };
      });
      this.$emit('on-select', listProduct);
    },
    onPaggingChange(page) {
      this.pagging.current = page;
    },
    onPaggingSize(limit) {
      this.pagging.limit = limit;
    },
    async reFetchProduct() {
      await clearProductCache();

      this.fetchListProduct();
    },
    async fetchListProduct() {
      this.queryProduct.fetchId = 0;
      this.queryProduct.page = 1;
      this.queryProduct.cursor = '';
      this.queryProduct.loading = true;

      for (let i = 0; i < 100; i++) {
        const fetchData = await shopeeSellerFetchProductList(
          this.queryProduct.page,
          this.queryProduct.limit,
          this.queryProduct.cursor,
        );

        if (!fetchData.listProduct.length) {
          break;
        }

        this.listProduct.push(...fetchData.listProduct);

        this.queryProduct.total = fetchData.total;
        this.queryProduct.cursor = fetchData.cursor;
        this.queryProduct.page += this.queryProduct.limit;

        if (this.queryProduct.page > fetchData.total) {
          break;
        }
      }

      this.listProduct = arrayDedupe(this.listProduct, ['id']);

      this.listProduct = await PromiseMap(
        this.listProduct,
        async (product) => {
          const productId = product.id;

          let isCache = true;
          const productTimeUpdate = product.modify_time;

          const CacheTimeUpdate = new CacheShopeeSellerProductTime(productId);
          const getTimeUpdateCache = await CacheTimeUpdate.get();

          if (getTimeUpdateCache && getTimeUpdateCache !== productTimeUpdate) {
            isCache = false;
          }

          const detail = await getShopeeSellerProductId(productId, isCache);

          this.queryProduct.fetchId++;

          await CacheTimeUpdate.set(productTimeUpdate);

          const productData = {
            ...product,
            ...detail,
            shop_id: this.getShopeeShopId,
          };

          return productData;
        },
        {
          concurrency: 4,
        },
      );

      this.tableProduct.rows = this.listProduct.map(renderTableProduct);

      this.pagging.total = this.listProduct.length;
      this.queryProduct.loading = false;
    },
  },
  async created() {
    this.fetchListProduct();
  },
  computed: {
    tableProductRow() {
      const { limit, current } = this.pagging;

      const start = current ? (current - 1) * limit : 0;
      const end = current ? current * limit : limit;

      return this.tableProduct.rows.slice(start, end);
    },
    productLoaderText() {
      if (!this.queryProduct.loading) {
        return '';
      }

      return this.$t('LOADING_PROCESS_TEXT', {
        current: this.queryProduct.fetchId,
        total: this.queryProduct.total,
      });
    },
  },
};
</script>

<style lang="scss" scoped>
@import '@/vue/styles/tokens.scss';

.sp-prod {
  &__toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
  }

  &__loader {
    font-size: 12px;
    color: $c-text-muted;

    @include ellipsis;
  }

  &__name {
    font-size: 13px;
    line-height: 1.4;
    color: $c-link;
    transition: color $motion-fast;

    &:hover {
      color: $c-link-hover;
    }

    &.is-unlisted {
      color: $c-text-muted;

      &:hover {
        color: $c-text;
      }
    }
  }

  &__thumb {
    display: inline-block;
    overflow: hidden;
    border-radius: $radius-sm;
    background: $c-surface-alt;
    transition: box-shadow $motion-fast;

    &:hover {
      box-shadow: $shadow-card;
    }

    img {
      display: block;
      width: 50px;
      height: auto;
    }
  }

  &__actions {
    display: flex;
    justify-content: flex-end;
    margin-top: 8px;
  }
}
</style>
