<template>
  <div>
    <!-- Search bar -->
    <div class="keyword-search-bar">
      <Input
        v-model="inputKeyword"
        :placeholder="$t('SEARCH_INPUT')"
        size="small"
        class="mr-5"
        style="width: 240px"
        @on-enter="onSearch"
      />
      <Button
        type="primary"
        size="small"
        :loading="query.loading"
        @click="onSearch"
      >
        {{ $t('SEARCH_BTN') }}
      </Button>
      <span
        v-if="query.loading"
        class="text-danger ml-10"
        style="font-size: 12px"
      >
        {{ $t('LOADING_TEXT') }} [{{ query.page * query.limit }} / {{ query.total }}]
      </span>
    </div>

    <!-- POPUP MODE: stats + open full -->
    <template v-if="isPopup">
      <div
        v-if="tableProduct.rows.length"
        class="popup-stats"
      >
        <Row :gutter="8">
          <Col
            v-for="stats in headerStats"
            :key="stats.key"
            :span="8"
          >
            <div class="popup-stats__card">
              <div class="popup-stats__label">{{ stats.text }}</div>
              <div class="popup-stats__value">{{ stats.value | addCommas }}</div>
            </div>
          </Col>
        </Row>

        <div class="popup-stats__actions">
          <Button
            type="primary"
            size="small"
            long
            @click="openFullPage"
          >
            {{ $t('SPY_PRODUCT_DATA') }}
          </Button>
        </div>
      </div>
    </template>

    <!-- FULL MODE -->
    <template v-else>
      <div v-if="tableProduct.rows.length">
        <Card
          dis-hover
          class="mb-10"
        >
          <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
        v-if="tableProduct.rows.length"
        class="keyword-toolbar"
      >
        <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"
          >
            {{ $t('COPY_URL') }} [{{ listSelected.length }}]
          </Button>
        </span>

        <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"
          />
        </span>
      </div>

      <div v-if="tableProduct.rows.length">
        <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="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>
    </template>
  </div>
</template>

<script>
import lodash from 'lodash';
import arrayDedupe from 'array-dedupe';
import queryString from 'query-string';
import { addCommas, calcPercentage } from '@/lib/utils/str';
import { exportSheet } from '@/lib/utils/excel';
import { shopeeSearchProductKeyword } from '@/api/shopee/client/search/index';
import { renderTableProduct, tableProductSpy } from '../mixin/Table';
import { getCurrentUrl } from '@/browser/tab';
import { isPopupEnv } from '@/browser/api';
import { openExternalUrl } from '@/browser/tab';

export default {
  name: 'ShopeeSearchKeyword',
  props: {
    keyword: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      inputKeyword: this.keyword,
      openPopup: false,
      listSelected: [],
      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],
      },
      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: {
    openFullPage() {
      const fullUrl = this.getRouterUrl(
        queryString.stringifyUrl({
          url: '/shopee/spy/search',
          query: { keyword: this.inputKeyword },
        }),
      );
      openExternalUrl(fullUrl);
    },
    onSearch() {
      if (!this.inputKeyword) {
        return;
      }

      this.fetchKeywordProduct();
    },
    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 }) {
      exportSheet(data, sheetName, `${label}-Keyword [${this.inputKeyword}].xls`);
    },
    exportExcelProduct() {
      exportSheet(this.tableProduct.rows, 'ShopeeProduct', `Keyword [${this.inputKeyword}].xls`);
    },
    async fetchKeywordProduct() {
      this.tableProduct.rows = [];
      this.listSelected = [];
      this.query.page = 0;
      this.query.loading = true;

      const keyword = this.inputKeyword;
      const limit = this.query.limit;
      const listProductFetch = [];

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

        try {
          const { listProduct, totalProduct } = await shopeeSearchProductKeyword(keyword, limit, page);

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

          if (totalProduct) {
            this.query.total = totalProduct;
          }

          listProductFetch.push(...listProduct);

          if (this.isPopup) {
            break;
          }
        } catch (error) {
          break;
        }
      }

      const deduped = arrayDedupe(listProductFetch, ['itemid']);
      this.tableProduct.rows = deduped.map(renderTableProduct);
      this.pagging.total = this.tableProduct.rows.length;

      this.query.loading = false;

      this.groupByProduct();
    },
  },
  async created() {
    if (this.keyword) {
      this.fetchKeywordProduct();
      return;
    }

    const tabUrl = await getCurrentUrl();

    if (tabUrl) {
      const parsed = queryString.parseUrl(tabUrl);

      if (parsed.query.keyword) {
        this.inputKeyword = parsed.query.keyword;
        this.fetchKeywordProduct();
      }
    }
  },
  computed: {
    isPopup() {
      return isPopupEnv;
    },
    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,
        },
      ];
    },
    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>

<style scoped>
.keyword-search-bar {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}

.keyword-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
  margin-top: 10px;
}

.popup-stats {
  margin-top: 8px;
}

.popup-stats__card {
  background: #fff;
  border: 1px solid #e8e8e8;
  border-radius: 4px;
  padding: 8px 10px;
  margin-bottom: 8px;
  text-align: center;
}

.popup-stats__label {
  font-size: 11px;
  color: #999;
  margin-bottom: 2px;
}

.popup-stats__value {
  font-size: 15px;
  font-weight: 700;
  color: #333;
}

.popup-stats__actions {
  margin-top: 4px;
}
</style>
