<template>
  <div>
    <div>
      <Card dis-hover>
        <Row>
          <Col
            v-for="stats in headerStats"
            :key="stats.key"
            :span="4"
            class="text-center"
          >
            <h2>{{ stats.text }}</h2>
            <h3>{{ stats.value | addCommas }}</h3>
          </Col>
        </Row>
      </Card>
    </div>
    <div class="mt-20 mb-20">
      <span>
        <Button
          size="small"
          type="primary"
          class="mr-5"
          @click="openPopup = true"
        >
          {{ $t('SPY_SHOP_OPEN_TOP_SELL') }}
        </Button>

        <Button
          size="small"
          type="success"
          ghost
          class="mr-5"
          @click="exportExcelProduct"
        >
          {{ $t('EXPORT_EXCEL_BTN') }}
        </Button>

        <Button
          size="small"
          type="primary"
          ghost
          class="mr-5"
          @click="copyUrlProduct"
        >
          <span class="mr-5">{{ $t('COPY_URL') }}</span>
          <span>[{{ listSelected.length }}]</span>
        </Button>

        <span
          v-if="query.loading"
          class="text-danger"
        >
          <span class="mr-5">{{ $t('LOADING_TEXT') }}</span>
          <span>[{{ query.page * query.limit }} / {{ query.total }}]</span>
        </span>
      </span>
      <span style="float: right">
        <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"
        />
      </span>
    </div>

    <div>
      <Table
        ref="TableProductList"
        :loading="query.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
            v-if="row.videoUrl"
            :href="row.videoUrl"
            target="_blank"
            class="text-danger"
          >
            [{{ $t('VIDEO') }}]
          </a>
          <a
            :href="row.productUrl"
            target="_blank"
          >
            {{ row.name | maxString(90) }}
          </a>
        </template>
        <template
          slot="image"
          slot-scope="{ row }"
        >
          <a
            :href="row.productUrl"
            target="_blank"
          >
            <img
              v-lazy="row.image + '_tn'"
              style="width: 50px"
            >
          </a>
        </template>
        <template
          slot="action"
          slot-scope="{ row }"
        >
          <router-link
            v-if="shopeeSpyEnabled"
            :to="row.spyUrl"
            target="_blank"
          >
            {{ $t('SPY_BTN') }}
          </router-link>
        </template>
      </Table>
    </div>
    <div>
      <Modal
        v-model="openPopup"
        :title="$t('SPY_SHOP_TOP_SELL')"
        width="1000"
        scrollable
      >
        <div
          v-if="openPopup"
          class="model-container-box mb-5"
        >
          <Row>
            <Col
              :span="24"
              class="mb-10"
            />
            <Col
              :span="24"
              class="mt-10"
            >
              <Collapse>
                <Panel
                  v-for="group in groupByData"
                  :key="group.key"
                  :name="group.key"
                >
                  <span>{{ group.label }}</span>
                  <template #content>
                    <div class="text-right mb-5">
                      <Button
                        type="success"
                        size="small"
                        ghost
                        @click="exportExcelReport(group)"
                      >
                        {{ $t('EXPORT_EXCEL_BTN') }}
                      </Button>
                    </div>
                    <Table
                      :columns="tableTopSellColum"
                      :data="group.data"
                      highlight-row
                      size="small"
                      border
                    />
                  </template>
                </Panel>
              </Collapse>
            </Col>
          </Row>
        </div>
      </Modal>
    </div>
  </div>
</template>

<script>
import queryString from 'query-string';
import lodash from 'lodash';
import arrayDedupe from 'array-dedupe';
import { addCommas, calcPercentage } from '@/lib/utils/str';
import { exportSheet } from '@/lib/utils/excel';
import { shopeeSearchProductCategoryId } from '@/api/shopee/client/search/index';
import { renderTableProduct, tableProductSpy } from '../mixin/Table';
import { fetchListProductCategoryId } from '@/api/worker/shopee';
import { getShopeeCategoryId as getCategoryId, getCategoryMatchName } from '@/api/shopee/client/category/index';

export default {
  name: 'ShopeeSearchCategory',
  props: {
    categoryId: String,
    categoryName: String,
  },
  data() {
    /** @type {ShopeeSearchItemShop[]} */
    const listProduct = [];

    return {
      openPopup: false,
      listSelected: [],
      listProduct,
      query: {
        total: 500,
        limit: 50,
        page: 0,
        loading: false,
      },
      pagging: {
        total: 0,
        current: 0,
        limit: 100,
        size: [10, 20, 50, 100, 500, 1000, 5000, 10000],
      },
      exportExcel: {
        file: `Cateogry [${this.categoryName}].xls`,
        sheet: 'ShopeeProduct',
        column: [],
        data: [],
      },
      tableProduct: {
        columns: tableProductSpy.columns,
        rows: [],
      },
      groupByData: {
        time: {
          key: 'time',
          label: this.$t('SPY_SHOP_TOP_SELL_TIME'),
          data: [],
        },
        price: {
          key: 'price',
          label: this.$t('SPY_SHOP_TOP_SELL_PRICE'),
          data: [],
        },
        brand: {
          key: 'brand',
          label: this.$t('SPY_SHOP_TOP_SELL_BRAND'),
          data: [],
        },
        category: {
          key: 'category',
          label: this.$t('SPY_SHOP_TOP_SELL_CATEGORY'),
          data: [],
        },
      },
    };
  },
  methods: {
    onSortTable({ key, order }) {
      this.tableProduct.rows = lodash.orderBy(this.tableProduct.rows, key, order);
      return false;
    },
    onSelectProduct(list) {
      this.listSelected = list;
    },
    onPaggingChange(page) {
      this.pagging.current = page;
    },
    onPaggingSize(limit) {
      this.pagging.limit = limit;
    },
    copyUrlProduct() {
      const textCopy = this.listSelected.map((product) => product.productUrl).join('\r\n');

      this.$copyText(textCopy).then(() => {
        this.$Message.info(this.$t('COPIED_VALUE'));
      });
    },
    groupByProduct() {
      this.groupByData.category.data = lodash(this.tableProduct.rows)
        .groupBy('categoryTree')
        .map((items, categoryTree) => ({
          key: categoryTree,
          text: categoryTree,
          totalSold: lodash.sumBy(items, 'sold'),
          totalSale: lodash.sumBy(items, 'sale'),
          totalProduct: items.length,
        }))
        .orderBy('totalSold', 'desc')
        .value();

      this.groupByData.brand.data = lodash(this.tableProduct.rows)
        .groupBy('brand')
        .map((items, brand) => ({
          key: brand,
          text: brand,
          totalSold: lodash.sumBy(items, 'sold'),
          totalSale: lodash.sumBy(items, 'sale'),
          totalProduct: items.length,
        }))
        .orderBy('totalSold', 'desc')
        .value();

      this.groupByData.time.data = lodash(this.tableProduct.rows)
        .groupBy('year')
        .map((items, year) => ({
          key: year,
          text: year,
          totalSold: lodash.sumBy(items, 'sold'),
          totalSale: lodash.sumBy(items, 'sale'),
          totalProduct: items.length,
        }))
        .orderBy('year', 'desc')
        .value();

      const priceRanges = [
        { label: 'dưới 10k', min: 0, max: 9999 },
        { label: '10k - 100k', min: 10000, max: 99999 },
        { label: '100k - 200k', min: 100000, max: 199999 },
        { label: '200k - 300k', min: 200000, max: 299999 },
        { label: '300k - 500k', min: 300000, max: 499999 },
        { label: '500k - 1tr', min: 500000, max: 999999 },
        { label: 'trên 1tr', min: 1000000, max: Infinity },
      ];

      this.groupByData.price.data = lodash
        .map(priceRanges, (range) => {
          const items = lodash.filter(
            this.tableProduct.rows,
            (product) => product.price >= range.min && product.price <= range.max,
          );

          return {
            key: range.label,
            text: range.label,
            totalSold: lodash.sumBy(items, 'sold'),
            totalSale: lodash.sumBy(items, 'sale'),
            totalProduct: items.length,
          };
        })
        .filter((item) => item.totalProduct);
    },
    exportExcelReport({ label, data, key: sheetName }) {
      const rows = data;
      const fileName = `${label}-${this.exportExcel.file}`;
      exportSheet(rows, sheetName, fileName);
    },
    exportExcelProduct() {
      const rows = this.tableProduct.rows;

      exportSheet(rows, this.exportExcel.sheet, this.exportExcel.file);
    },
    async fetchShopProduct() {
      this.tableProduct.rows = [];
      this.query.page = 0;
      this.query.loading = true;

      const categoryId = this.categoryId;

      if (false) {
        const categoryData = getCategoryId(categoryId);

        const listCategoryIdFetch = [];

        getCategoryMatchName(categoryData.display_name).forEach((catMatch) => {
          listCategoryIdFetch.push(
            ...[
              ...catMatch.path.map((child) => child.category_id.toString()),
              catMatch.category_id.toString(),
            ],
          );
        });

        const limitFetch = 100;
        const pageFetch = 100;
        const listProductFetch = [];

        for (let page = 0; page < pageFetch; page++) {
          try {
            const listProduct = (await fetchListProductCategoryId([...new Set(listCategoryIdFetch)], page, limitFetch));

            if (!listProduct.length) {
              break;
            }

            listProductFetch.push(...listProduct);
          } catch (error) {

          }
        }

        this.tableProduct.rows.push(
          ...listProductFetch.map((product, index) => {
            const productIndex = this.tableProduct.rows.length + index + 1;
            const spyUrl = queryString.stringifyUrl({
              url: '/shopee/spy/product',
              query: {
                productId: product.productId,
                shopId: product.shopId,
              },
            });

            return {
              index: productIndex,
              spyUrl,
              ...product,
            };
          }),
        );
      }

      if (true) {
        const listProductFetch = [];

        const limit = this.query.limit;

        for (let page = 0; page * limit < this.query.total; page++) {
          this.query.page = page;

          try {
            const { listProduct, totalProduct } = await shopeeSearchProductCategoryId(
              categoryId,
              limit,
              page,
            );

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

            if (false && totalProduct) {
              this.query.total = totalProduct;
            } else {
              this.query.total = 500;
            }

            listProductFetch.push(...listProduct);
          } catch (error) {

          }
        }

        this.tableProduct.rows.push(
          ...listProductFetch.map(renderTableProduct),
        );
      }

      this.tableProduct.rows = arrayDedupe(this.tableProduct.rows, ['productId']);

      this.pagging.total = this.tableProduct.rows.length;

      this.query.loading = false;

      this.groupByProduct();
    },
  },
  created() {
    this.fetchShopProduct();
  },
  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);
    },
    totalProduct() {
      return this.tableProduct.rows.length;
    },
    totalSold() {
      return lodash.sumBy(this.tableProduct.rows, 'sold');
    },
    totalSale() {
      return lodash.sumBy(this.tableProduct.rows, 'sale');
    },
    headerStats() {
      return [
        {
          key: 'totalProduct',
          text: this.$t('SHOP_TOTAL_PRODUCT'),
          value: this.totalProduct,
        },
        {
          key: 'totalCategory',
          text: this.$t('SHOP_TOTAL_CATEGORY'),
          value: this.groupByData.category.data.length,
        },
        {
          key: 'totalBrand',
          text: this.$t('SHOP_TOTAL_BRAND'),
          value: this.groupByData.brand.data.length,
        },
        {
          key: 'totalSold',
          text: this.$t('SHOP_TOTAL_SOLD'),
          value: this.totalSold,
        },
        {
          key: 'totalSale',
          text: this.$t('SHOP_TOTAL_SALE'),
          value: this.totalSale,
        },
        {
          key: 'totalFollower',
          text: this.$t('SHOP_TOTAL_FOLLOWER'),
          value: 0,
        },
      ];
    },
    tableTopSellColum() {
      return [
        {
          title: '#',
          type: 'index',
          width: 60,
        },
        {
          title: '##',
          key: 'text',
          width: 200,
        },
        {
          title: this.$t('PRODUCT'),
          key: 'totalProduct',
          render: (h, params) => {
            const text = [
              addCommas(params.row.totalProduct),
              `(${calcPercentage(params.row.totalProduct, this.totalProduct, 0)}%)`,
            ].join(' ');
            return h('span', text);
          },
        },
        {
          title: this.$t('PRODUCT_MODEL_SOLD'),
          key: 'totalSold',
          render: (h, params) => {
            const text = [
              addCommas(params.row.totalSold),
              `(${calcPercentage(params.row.totalSold, this.totalSold, 0)}%)`,
            ].join(' ');

            return h('span', text);
          },
        },
        {
          title: this.$t('PRODUCT_MODEL_TOTAL_SALE'),
          key: 'totalSale',
          render: (h, params) => {
            const text = [
              addCommas(params.row.totalSale),
              `(${calcPercentage(params.row.totalSale, this.totalSale, 0)}%)`,
            ].join(' ');

            return h('span', text);
          },
        },
      ];
    },
  },
};
</script>
