import PromiseMap from 'p-map';
import delay from 'delay';
import moment from 'moment';
import {
  createFlashSaleIdFromTime, updateFlashSaleSetListProduct, updateFlashSaleIndexListProduct,
} from '@/api/shopee/seller/flashsale';
import {
  apiFlashsaleSchedulerGetId, apiFlashsaleSchedulerSetId, apiFlashsaleSchedulerList,
} from '@/api/autoshopee/shopee/flashsale';
import i18n from '@/plugins/i18n';
import { loggerShopee } from '@/plugins/logger';
import { getKvLockApi, getFlashSaleDataTimeId } from './get';

export const createFlashsaleFromSchedulerId = async (schedulerId, isForce = false) => {
  const { KvLocker } = await getKvLockApi('create', schedulerId, 20);

  if (isForce) {
    if (!KvLocker) {
      loggerShopee.log({
        msg: 'FLASHSALE_SCHEDULER_ID_LOCKED',
        schedulerId,
      });
      return null;
    }
  }

  /** @type {FlashSaleListScheduler} */
  const flashSaleData = await apiFlashsaleSchedulerGetId(schedulerId);

  if (!flashSaleData) {
    throw {
      msg: 'FLASHSALE_CRON_ID_NOT_FOUND',
      errorMsg: i18n.t('FLASHSALE_SCHEDULER_GET_NOT_FOUND'),
    };
  }

  if (flashSaleData.isDone && flashSaleData.isSuccess && flashSaleData.flashsaleId) {
    return flashSaleData.flashsaleId;
  }

  const { startTime } = flashSaleData.timeSlot;
  const timeSlotId = flashSaleData.timeId;

  if (moment(new Date(startTime)) < moment()) {
    throw {
      msg: 'FLASHSALE_CRON_ID_NOT_FOUND',
      time: flashSaleData.timeSlot.labelTime,
      errorMsg: i18n.t('FLASHSALE_AUTO_TIME_WAS_PASSED'),
    };
  }

  let flashSaleId = 0;

  const getFlashsaleExist = await getFlashSaleDataTimeId(Number(timeSlotId));

  if (getFlashsaleExist) {
    if (getFlashsaleExist.enabled_item_count && getFlashsaleExist.item_count) {
      flashSaleId = getFlashsaleExist.flash_sale_id;
      await apiFlashsaleSchedulerSetId(schedulerId, flashSaleId);

      return flashSaleId;
    }

    flashSaleId = getFlashsaleExist.flash_sale_id;
  }

  if (!flashSaleId) {
    const createFlashsaleId = await createFlashSaleIdFromTime(timeSlotId);
    flashSaleId = createFlashsaleId.flash_sale_id;
  }

  if (!flashSaleId) {
    throw {
      msg: 'CREATE_FLASHSALE_SCHEDULER_ID_ERROR',
      time: flashSaleData.timeSlot.labelTime,
      errorMsg: i18n.t('FLASHSALE_AUTO_CREATE_ID_ERROR'),
    };
  }

  await updateFlashSaleSetListProduct(flashSaleId, flashSaleData.listSet).catch(() => {});

  await updateFlashSaleIndexListProduct(flashSaleId, flashSaleData.listIndex).catch(() => {});

  await apiFlashsaleSchedulerSetId(schedulerId, flashSaleId);

  await KvLocker.removeKv().catch(() => {});

  return flashSaleId;
};

export const createFlashsaleFromSchedulerShopId = async (shopId, callbackFlashsale = null) => {
  if (!shopId) {
    throw 'SHOPEE_FLASHSALE_SCHEDULER_VALIDATE_SHOP_ID_REQUIRED';
  }

  const { KvLocker } = await getKvLockApi('shop', shopId, 30);

  if (!KvLocker) {
    loggerShopee.log({
      msg: 'FLASHSALE_SHOP_ID_LOCKED',
      shopId,
    });
    return [];
  }

  const listFlashsaleCreated = [];

  /** @type {FlashSaleListScheduler[]} */
  const listFetchAll = await apiFlashsaleSchedulerList(shopId);

  /**
   * @param {FlashSaleListScheduler} fsScheduler
   * @returns {boolean}
   */
  const isSchedulerMatch = (fsScheduler) => {
    if (!fsScheduler || !fsScheduler._id) {
      return false;
    }
    return !fsScheduler.flashsaleId
      && fsScheduler.active
      && moment(new Date(fsScheduler.timeSchedule)) < moment() && moment(new Date(fsScheduler.timeFlashsale)) > moment();
  };

  const listScheduler = listFetchAll.filter((item) => isSchedulerMatch(item));

  await PromiseMap(listScheduler, async (fsScheduler, fsIndex) => {
    if (!fsScheduler || !fsScheduler._id) {
      loggerShopee.error({
        msg: 'FLASHSALE_SCHEDULER_INVALID_ITEM',
        fsScheduler,
        fsIndex,
      });
      return;
    }

    await createFlashsaleFromSchedulerId(fsScheduler._id).then((flashSaleId) => {
      if (!flashSaleId) {
        throw 'FLASHSALE_CREATE_EMPTY_ID';
      }

      listFlashsaleCreated.push(flashSaleId);

      loggerShopee.log({
        msg: 'FLASHSALE_CHEDULER_CREATE_SUCCESS',
        flashSaleId,
        fsScheduler,
      });

      if (callbackFlashsale) {
        callbackFlashsale({
          flashsaleData: fsScheduler,
          current: fsIndex + 1,
          total: listScheduler.length,
        });
      }
    }).catch((error) => {
      loggerShopee.error({
        msg: 'FLASHSALE_CHEDULER_CREATE_ERROR',
        error,
        fsScheduler,
      });
    });

    await delay(1000);
  }, {
    concurrency: 1,
  });

  await KvLocker.removeKv().catch(() => {});

  return listFlashsaleCreated;
};
