import PromiseMap from 'p-map';
import { getImageUrlData, uploadImageBloob } from '@/api/shopee/image';
import configShopee from '@/config/shopee';
import numberPrecision from 'number-precision';
import { getTiktokImageUrl } from './render';
import { CacheTiktokImageShopee } from '@/plugins/store/cache';

const configShopeeProduct = configShopee.product;

/**
 *
 * @param {number} priceOrigin
 * @param {string} priceChange
 * @returns
 */
const priceChangeValue = (priceOrigin, priceChange) => {
  if (priceChange.indexOf('%') !== -1) {
    priceOrigin *= Number(priceChange.replace('%', '')) / 100;
  } else if (priceChange.indexOf('$') !== -1) {
    priceOrigin = Number(priceChange.replace('$', ''));
  } else {
    priceOrigin = Number(priceChange) + Number(priceChange);
  }

  return numberPrecision.round(priceOrigin, 0);
};

export class TiktokProductMirgateShopee {
  static getTiktokImageUrl = getTiktokImageUrl;

  /**
   *
   * @param {TiktokPdpProductId} tiktokProduct
   */
  constructor(tiktokProduct) {
    /** @type {TiktokPdpProductId} */
    this.tiktokProduct = tiktokProduct;

    this.listAttribute = [];
    this.listWarehouse = [];
    this.listCategory = [];
    this.listLogistic = [];
    this.listVideo = [];
  }

  /**
   * @param {TiktokProductMirgateShopeePayload}payloadMigrate
   * @returns {ShopeePayloadProductCreate}
   */
  getPayload(payloadMigrate) {
    const productInfo = this.tiktokProduct.initialData.productInfo;
    const productBase = productInfo.product_base;
    const listSaleProp = productInfo.sale_props;
    const listSku = productInfo.skus;

    const productSku = payloadMigrate.sku || productInfo.product_id.toString();

    const tierVariation = listSaleProp.map((prop) => {
      return {
        name: prop.prop_name,
        options: prop.sale_prop_values.map((item) => item.prop_value.substring(0, configShopeeProduct.modelVariationNameMax)),
        images: prop.has_image ? prop.sale_prop_values.map((item) => item.image.id) : [],
      };
    });

    const dimension = {
      width: 0,
      height: 0,
      length: 0,
    };

    const listImage = productBase.images.map((img) => img.id);

    const weight = payloadMigrate.weight || 100;

    const name = payloadMigrate.name || productBase.title;

    const description = (payloadMigrate.description || JSON.parse(productInfo.product_base.desc_detail).map((item) => item.text).filter((text) => text).join('\n')).trim();

    const listModel = listSku.map((modelSku, skuIndex) => {
      const stock = modelSku.stock || 0;
      let price = ((payloadMigrate.beforeDiscount) ? modelSku.price.original_price_value : modelSku.price.real_price.price_val) || modelSku.price.original_price_value;

      if (payloadMigrate.priceChange) {
        price = priceChangeValue(Number(price), payloadMigrate.priceChange).toString();
      }

      const tier = modelSku.sku_sale_props.map((pv, propIndex) => listSaleProp[propIndex].sale_prop_values.findIndex((v) => v.prop_value_id === pv.prop_value_id));

      const stockListNornmal = [{
        sellable_stock: stock,
      }];

      const stoclListWarehouse = this.listWarehouse.map((warehouseId) => {
        return {
          location_id: warehouseId,
          sellable_stock: stock,
        };
      });
      return {
        is_default: !skuIndex,
        id: 0,
        sku: modelSku.sku_id.toString(),
        name: modelSku.sku_sale_props.map((item) => item.prop_value).join(' / '),
        tier_index: tier,
        price,
        stock,
        stock_setting_list: this.listWarehouse.length ? stoclListWarehouse : stockListNornmal,
      };
    });

    const modelDefault = listModel.find((item) => item.is_default);

    /** @type {ShopeePayloadProductCreate} */
    const productReturn = {
      ...modelDefault,
      id: 0,
      name,
      status: productInfo.status,
      images: listImage,
      long_images: [],
      category_path: this.listCategory,
      parent_sku: productSku,
      description,
      video_list: this.listVideo,
      attributes: this.listAttribute,
      logistics_channels: this.listLogistic,
      weight,
      dimension,
      brand: 'NoBrand',
      brand_id: 0,
      tier_variation: tierVariation,
      model_list: listModel,
      pre_order: false,
      days_to_ship: configShopeeProduct.daysToShip.normal,
      condition: 1,
      size_chart_info: {
        size_chart: '',
        size_chart_id: 0,
      },
      ds_cat_rcmd_id: '',
      unlisted: payloadMigrate.unListed,
      add_on_deal: [],
      category_recommend: [],
      wholesale_list: [],
      installment_tenures: {},
      enable_model_level_dts: false,
    };

    productReturn.name = productReturn.name.substring(0, configShopeeProduct.maxTitle);
    productReturn.description = productReturn.description.substring(0, configShopeeProduct.maxDescription);

    return productReturn;
  }

  /**
   *
   * @param {string} imageUri
   */
  async mirgateImageUrl(imageUri) {
    const CacheImage = new CacheTiktokImageShopee(imageUri);
    const getCache = await CacheImage.get();

    if (getCache) {
      return getCache;
    }

    const imageUrl = getTiktokImageUrl(imageUri);

    const { blob: blobImage } = await getImageUrlData(imageUrl);

    const imageId = await uploadImageBloob(blobImage);

    await CacheImage.set(imageId);

    return imageId;
  }

  async mirgateImageList(callbackLog) {
    const productInfo = this.tiktokProduct.initialData.productInfo;

    productInfo.product_base.images = await PromiseMap(productInfo.product_base.images, async (imageData, imageIndex) => {
      if (callbackLog) {
        callbackLog({
          imageUrl: imageData.uri,
          imageIndex: `${imageIndex + 1}/${productInfo.product_base.images.length}`,
        });
      }

      imageData.id = await this.mirgateImageUrl(imageData.uri);
      return imageData;
    }, {
      concurrency: 2,
    });

    productInfo.sale_props = await PromiseMap(productInfo.sale_props, async (prop) => {
      if (prop.has_image) {
        prop.sale_prop_values = await PromiseMap(prop.sale_prop_values, async (value, imageIndex) => {
          if (value.image && value.image.uri) {
            if (callbackLog) {
              callbackLog({
                imageUrl: value.image.uri,
                imageIndex: `${imageIndex + 1}/${prop.sale_prop_values.length}`,
              });
            }

            value.image.id = await this.mirgateImageUrl(value.image.uri);
          }
          return value;
        });
      }

      return prop;
    }, {
      concurrency: 2,
    });
  }
}
