import '@/types/Store/Shopee/Product';
import clone from 'clone';
import lodash from 'lodash';
import moment from 'moment';
import arrayDedupe from 'array-dedupe';
import configShopee from '@/config/shopee';
import { sortArrayRand, contentPhoneReplace } from '@/lib/utils/utils';
import { loggerShopee } from '@/plugins/logger';
import { imageUrl, videoData as getVideoData, productUrl } from './render';

const configShopeeProduct = configShopee.product;
const STOCK_DEFAULT = 111;

const stockListWarehouse = (stock = 0, listWarehouseId = []) => {
  if (stock > 200000) {
    stock = 200000;
  }

  const result = {
    stock,
    stock_setting_list: [
      {
        sellable_stock: stock,
      },
    ],
  };

  if (listWarehouseId && listWarehouseId.length) {
    result.stock_setting_list = listWarehouseId.map((warehouseId) => ({
      location_id: warehouseId,
      sellable_stock: stock,
    }));
  }

  return result;
};

export const priceFix = (price, fixVal = 100000) => {
  if (price && price > 0) {
    return price / fixVal;
  }

  return 0;
};

export const priceListFix = (data) => {
  const listKey = ['price_max', 'price_min', 'price_before_discount', 'price', 'price_max_before_discount', 'price_min_before_discount'];
  listKey.forEach((keyPrice) => {
    if (data[keyPrice]) {
      data[keyPrice] = priceFix(data[keyPrice]);
    }
  });
  return data;
};

export const refactorProduct = (product, fixPrice = true) => {
  let productRaw = clone(product);

  if (fixPrice) {
    productRaw = priceListFix(productRaw);
  }

  const videoData = getVideoData(productRaw.video_info_list);

  const listModel = (productRaw.models || [])
    .sort((item1, item2) => {
      if (item1.extinfo && item1.extinfo.tier_index && item1.extinfo.tier_index.length) {
        return item1.extinfo.tier_index[0] - item2.extinfo.tier_index[0];
      }
      return true;
    })
    .map((variation) => {
      let image = '';
      let tierList = [];

      if (fixPrice) {
        variation = priceListFix(variation);
      }
      variation.sku = (variation.modelid || variation.id).toString();

      if (variation.extinfo && variation.extinfo.tier_index && variation.extinfo.tier_index.length) {
        variation.extinfo.tier_index.forEach((indexId, indexTier) => {
          const keyPathImage = `[${indexTier}]images[${indexId}]`;
          image = lodash.get(productRaw.tier_variations, keyPathImage, image);
        });

        tierList = variation.extinfo.tier_index.map((val, index) => {
          const tier = productRaw.tier_variations[index];
          const tierValue = tier.options[val];
          return {
            text: tier.name,
            value: tierValue,
          };
        });
      }

      return {
        ...variation,
        image,
        tier: tierList,
      };
    });

  const listTier = (productRaw.tier_variations || []).map((tier) => ({
    ...tier,
    images: tier.images && tier.images.length ? tier.images.map((id) => imageUrl(id)) : [],
  }));

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

  return {
    ...productRaw,
    platform: 'shopee',
    productId: productRaw.itemid,
    shopId: productRaw.shopid,
    sku: productRaw.itemid.toString(),
    image: imageUrl(productRaw.image),
    images: productRaw.images.map((id) => imageUrl(id)),
    long_images: (productRaw.long_images || []).map((id) => imageUrl(id)),
    models: listModel,
    tier_variations: listTier,
    weight: 0,
    dimension,
    url: productUrl(productRaw.itemid, productRaw.shopid),
    video: videoData.urlDefault,
    videoData,
  };
};

/**
 *
 * @param {ShopeeSellerProductDetail} productData
 * @param {Array} videoAppend
 * @returns {object}
 */
export const syncVideoProduct = (productData, videoAppend = []) => {
  const videoList = [
    ...(productData.video_list || []),
    ...videoAppend.map((videoData) => ({
      ...videoData,
      version: 1,
    })),
  ];

  return {
    id: productData.id,
    video_list: arrayDedupe(videoList, ['video_id']).filter((item) => item.version),
  };
};

/**
 *
 * @param {ShopeeProductData} dataProduct
 * @param {ShopeeProductAttribute[]} listAttrProduct
 * @param {ProductCloneEditPayload} editParam
 * @param {Array} listWarehouseId
 * @returns {ShopeePayloadProductCreate}
 */
export const renderCloneProduct = (dataProduct, listAttrProduct = [], editParam = {}, listWarehouseId = []) => {
  const renderPrice = (priceCurrent, priceBeforeDiscount) => {
    const editPrice = editParam.price.change.trim();
    let price = editParam.price.beforeDiscount && priceBeforeDiscount ? priceBeforeDiscount : priceCurrent;

    if (editPrice && price) {
      if (editPrice.indexOf('%') !== -1) {
        price *= Number(editPrice.replace('%', '')) / 100;
      } else if (editPrice.indexOf('$') !== -1) {
        price = Number(editPrice.replace('$', ''));
      } else {
        price = Number(editPrice) + Number(price);
      }
      return Math.round(price / 100) * 100;
    }
    return price;
  };

  const productSku = (dataProduct.sku || dataProduct.parent_sku || dataProduct.itemid).toString();
  const productWeight = Number(lodash.get(dataProduct, 'weight', 0)) || lodash.get(dataProduct, 'dimension.weight', 0) || Number(editParam.weight || 1);

  const price = renderPrice(dataProduct.price, dataProduct.price_before_discount).toString();
  const stockOriginal = dataProduct.stock;

  const isPreorder = dataProduct.is_pre_order || dataProduct.pre_order || false;

  let dayShip = dataProduct.estimated_days || dataProduct.days_to_ship || 0;

  if (!isPreorder && dayShip > configShopeeProduct.daysToShip.normal) {
    dayShip = configShopeeProduct.daysToShip.normal;
  }

  if (isPreorder && (dayShip < configShopeeProduct.daysToShip.preOrder.min || dayShip > configShopeeProduct.daysToShip.preOrder.max)) {
    dayShip = configShopeeProduct.daysToShip.preOrder.current;
  }

  const brandName = dataProduct.brand || 'No Brand';
  const brandId = dataProduct.brand_id || 0;

  const expiryDateAttribute = listAttrProduct.find((attr) => attr.name === 'Expiry Date' || [100061].includes(attr.attribute_id));

  const setExpiredDay = Number(lodash.get(editParam, 'expiredDay', 0)) || 365;
  const setExpiredUnix = moment().add(setExpiredDay, 'day').unix().toString();

  const setStockDefault = Number(lodash.get(editParam, 'stock', 0)) || 0;

  const attributeList = listAttrProduct
    .map((attrData) => {
      try {
        const {
          children: listValAttr, attribute_id: attributeId, mandatory: isMandatory, attribute_info: attributeInfo, name: attributeName,
        } = attrData;

        let isMatchAttr = false;
        let customVal = null;
        let selectAttrId = listValAttr && listValAttr.length ? listValAttr[0].value_id : 0;
        let selectAttrValue = '';

        const attrMatch = dataProduct.attributes && dataProduct.attributes.length ? dataProduct.attributes.find((elAttr) => elAttr.attribute_id === attributeId || elAttr.id === attributeId) : null;

        if (attrMatch) {
          if (attrMatch.attribute_value_id) {
            selectAttrId = attrMatch.attribute_value_id;
            isMatchAttr = true;
          } else if (attrMatch.custom_value) {
            customVal = attrMatch.custom_value;
            isMatchAttr = true;
          } else if (attrMatch.value) {
            const findAttr = listValAttr.find(({ display_name }) => display_name === attrMatch.value);

            if (findAttr && findAttr.value_id) {
              selectAttrId = findAttr.value_id;
              selectAttrValue = attrMatch.value;
              isMatchAttr = true;
            } else {
              const isValUnit = !!(attributeInfo && attributeInfo.attribute_unit_list && attributeInfo.attribute_unit_list.length);
              if (isValUnit) {
                const raw_value = attrMatch.value.match(/(^\d*)/)[0];
                const unit = attrMatch.value.replace(raw_value, '');
                const unitExist = attributeInfo.attribute_unit_list.find((val) => val === unit);
                if (raw_value && unit && unitExist && Number(raw_value) && !isNaN(raw_value)) {
                  customVal = {
                    raw_value,
                    unit,
                  };
                  selectAttrId = 0;
                  isMatchAttr = true;
                }
              } else {
                customVal = {
                  raw_value: attrMatch.value,
                  unit: '',
                };
                selectAttrId = 0;
                isMatchAttr = true;
              }
            }
          }
        }

        const attributeTypeId = attrData.attribute_info.input_validation_type;
        let allowCustom = !!attributeTypeId;

        if (isMandatory && !selectAttrId && !customVal) {
          if ([1, 2].includes(attributeTypeId)) {
            customVal = { raw_value: '999999', unit: '' };
            allowCustom = true;
          }
        }

        const returnAttr = !!((selectAttrId || (customVal && allowCustom)) && (isMandatory || isMatchAttr));

        if (returnAttr) {
          const selected = {
            attribute_name: attributeName,
            attribute_id: attributeId,
            mandatory: isMandatory,
          };

          if (selectAttrId) {
            selected.attribute_value_id = selectAttrId;
          }

          if (customVal && allowCustom) {
            selected.custom_value = customVal;
          }

          if (selectAttrValue) {
            selected.attribute_text = selectAttrValue;
          }

          if (attributeName === 'Expiry Date' || [100061].includes(attributeId)) {
            if (!Number(lodash.get(selected, 'custom_value.raw_value', 0))) {
              lodash.set(selected, 'custom_value.raw_value', setExpiredUnix);
            }
          }

          return selected;
        }

        return null;
      } catch (error) {
        loggerShopee.error({
          msg: 'PRODUCT_ATTRIBUTE_RENDER_ERROR',
          error,
        });
        return null;
      }
    })
    .filter((attr) => attr);

  if (expiryDateAttribute) {
    const hasExpiryDateAttr = attributeList.find((attr) => attr.attribute_id === expiryDateAttribute.attribute_id);

    if (!hasExpiryDateAttr) {
      attributeList.push({
        attribute_id: expiryDateAttribute.attribute_id,
        custom_value: {
          raw_value: setExpiredUnix,
          unit: '',
        },
      });
    }
  }

  dataProduct.models = dataProduct.models && dataProduct.models.length ? dataProduct.models.filter((el) => el.name) : [];

  if (dataProduct.models && dataProduct.models.length) {
    dataProduct.models = dataProduct.models.map((elModel, indexModel) => {
      if (!elModel.extinfo) {
        elModel.extinfo = {};
      }
      if (!elModel.extinfo.tier_index || !elModel.extinfo.tier_index.length) {
        elModel.extinfo.tier_index = [indexModel];
      }
      return elModel;
    });
  }

  if (dataProduct.models && dataProduct.models.length && (!dataProduct.tier_variations || !dataProduct.tier_variations.length)) {
    dataProduct.tier_variations = [
      {
        images: [],
        name: 'Variation',
        options: dataProduct.models.map((el) => el.name),
      },
    ];
  }

  const isHaveMultiVariant = !!(dataProduct.models && dataProduct.models.length && dataProduct.tier_variations && dataProduct.tier_variations.length && dataProduct.tier_variations.length <= dataProduct.models.length);

  if (isHaveMultiVariant && dataProduct.models.length > configShopee.maxModelCount && dataProduct.tier_variations.length === 1) {
    dataProduct.models = dataProduct.models.slice(0, configShopee.maxModelCount);
    const newDataModels = clone(dataProduct.models);
    dataProduct.tier_variations = dataProduct.tier_variations.map((elTier, indexTier) => {
      let indexNew = 0;
      elTier.options = elTier.options.filter((elOption, indexOption) => {
        const checkActive = dataProduct.models.find((elModel, indexModel) => {
          if (elModel.extinfo.tier_index[indexTier] === indexOption) {
            newDataModels[indexModel].extinfo.tier_index[indexTier] = indexNew;
            indexNew++;
            return elModel;
          }
        });

        if (checkActive) {
          return elOption;
        }
      });
      return elTier;
    });
    dataProduct.models = newDataModels;
  }

  let videoList = [];

  if (editParam.video && editParam.video.clone && dataProduct.video_info_list && dataProduct.video_info_list.length) {
    videoList = dataProduct.video_info_list
      .map((videoData) => ({
        ...videoData,
        version: 1,
      }))
      .filter((item) => item.video_id);
  }

  const stockMain = stockOriginal || setStockDefault || STOCK_DEFAULT;

  let modelList = [
    {
      id: 0,
      is_default: true,
      name,
      price,
      sku: productSku,
      tier_index: [0],
      ...stockListWarehouse(stockMain, listWarehouseId),
    },
  ];

  if (isHaveMultiVariant) {
    modelList = dataProduct.models.map((model) => {
      const isHasStock = lodash.get(model, 'has_stock', true);
      const getStock = model.real_stock || model.model_stock || model.real_stock || setStockDefault || STOCK_DEFAULT;
      const setStock = isHasStock ? getStock : 0;

      return {
        id: 0,
        sku: (model.sku || model.modelid || model.id || '').toString(),
        name: model.name,
        stock: setStock,
        price: renderPrice(model.price, model.price_before_discount).toString(),
        tier_index: model.extinfo.tier_index,
        ...stockListWarehouse(setStock, listWarehouseId),
      };
    });
  }

  const tierList = isHaveMultiVariant
    ? dataProduct.tier_variations.map((variation) => ({
      name: variation.name,
      images: variation.images && variation.images.length ? variation.images : [],
      options: variation.options.map((value, index) => (value.length > 20 ? `${value.substring(0, 18)}_${index + 1}` : value)),
    }))
    : [
      {
        images: [],
        name: '',
        options: [''],
      },
    ];

  const dimension = {
    width: Number(lodash.get(dataProduct, 'dimension.width', 0)) || 0,
    height: Number(lodash.get(dataProduct, 'dimension.height', 0)) || 0,
    length: Number(lodash.get(dataProduct, 'dimension.length', 0)) || 0,
  };

  const logisticsList = editParam.logisticsChannels.map((channelid) => ({
    price: '0',
    cover_shipping_fee: false,
    enabled: true,
    item_flag: '0',
    channelid,
    sizeid: 0,
  }));

  const sizeChartImage = lodash.get(dataProduct, 'size_chart', '');

  /** @type {ShopeePayloadProductCreate} */
  const payloadProduct = clone({
    id: 0,
    name: [editParam.title.prepend, dataProduct.name, editParam.title.append].join(' ').trim(),
    brand: brandName,
    brand_id: brandId,
    images: editParam.image.spin ? sortArrayRand(dataProduct.images) : dataProduct.images,
    long_images: [],
    description: contentPhoneReplace([editParam.description.prepend, dataProduct.description, editParam.description.append].join('\n').trim(), editParam.replace.phone),
    category_path: dataProduct.categories.map((elCat) => elCat.catid),
    attributes: attributeList,
    category_recommend: [],
    price,
    parent_sku: productSku,
    wholesale_list: [],
    installment_tenures: {},
    weight: productWeight,
    dimension,
    model_list: modelList,
    tier_variation: tierList,
    logistics_channels: logisticsList,
    unlisted: editParam.unlisted,
    add_on_deal: [],
    video_list: videoList,
    days_to_ship: (dayShip <= 2 && dayShip > 0) || isPreorder ? dayShip : 2,
    ds_cat_rcmd_id: '0',
    condition: lodash.get(dataProduct, 'condition', 1),
    size_chart: sizeChartImage,
    size_chart_info: lodash.get(dataProduct, 'size_chart_info', null),
    pre_order: isPreorder,
    installment_tenrues: {},
    ...stockListWarehouse(stockMain, listWarehouseId),
  });

  if (isHaveMultiVariant && payloadProduct.tier_variation && payloadProduct.tier_variation.length) {
    payloadProduct.tier_variation = payloadProduct.tier_variation.map((tier) => {
      if (!tier.name) {
        tier.name = 'default';
      }

      if (!tier.options || !tier.options.length || (tier.options.length === 1 && tier.options[0] === '')) {
        tier.options = ['default'];
      }
      return tier;
    });
  }

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

  if (dataProduct.long_images && dataProduct.long_images.length) {
    payloadProduct.long_images = dataProduct.long_images;
  }

  if (editParam.description.json && lodash.has(dataProduct, 'rich_text_description.paragraph_list')) {
    payloadProduct.description_json = dataProduct.rich_text_description.paragraph_list;
  }

  if (dataProduct.size_chart_info && payloadProduct.size_chart_info.size_chart_id) {
    payloadProduct.size_chart_info.size_chart_id = 0;
  }

  if (!dataProduct.size_chart_info && sizeChartImage) {
    payloadProduct.size_chart_info = {
      size_chart_id: 0,
      size_chart: sizeChartImage,
    };
  }

  return payloadProduct;
};

/**
 * @param {Array<object>} descriptionJson
 * @param {string} descriptionText
 * @returns {Array}
 */
export const overrideDescriptionJson = (descriptionJson, descriptionText) => {
  const textLines = descriptionText.split('\n');
  const descriptionTextList = [];
  const descriptionImageList = descriptionJson.filter((item) => item.img_id);

  textLines.forEach((line) => {
    const trimmed = line.trim();

    if (trimmed.length === 0) {
      descriptionTextList.push({
        'type': 10001,
        'text': null,
        'img_id': null,
        'ratio': null,
        'description_type': 1,
        'empty_paragraph_count': 1,
      });
      return;
    }

    descriptionTextList.push({
      'type': 0,
      'text': line,
      'img_id': null,
      'ratio': null,
      'description_type': 1,
      'empty_paragraph_count': null,
    });
  });

  return [
    ...descriptionTextList,
    ...descriptionImageList,
  ];
};
