import PromiseMap from 'p-map';
import delay from 'delay';
import moment from 'moment';
import {
  apiFlashsaleSchedulerCreate, apiFlashsaleCampaignGetId, apiFlashsaleCampaignList, apiFlashsaleSchedulerSlot,
} from '@/api/autoshopee/shopee/flashsale';
import { loggerShopee } from '@/plugins/logger';

import { getKvLockApi, getListSlotTimeAll } from './get';

export const createScheduleFromCampaignId = async (campaignId, callbackScheduler = null) => {
  const { KvLocker } = await getKvLockApi('create-from-campaign', campaignId, 60);

  if (!KvLocker) {
    loggerShopee.log({
      msg: 'FLASHSALE_CAMPAIGN_ID_LOCKED',
      campaignId,
    });

    return [];
  }

  /** @type {FlashSaleCampaignScheduler} */
  const campaignData = await apiFlashsaleCampaignGetId(campaignId);

  if (!campaignData) {
    return null;
  }

  const {
    shopId, shopName, listSet, listIndex, productCount, timeFlashsaleBefore, timeSchedulerBefore, timeSlotStart, timeSlotEnd,
  } = campaignData;

  const timeRangeEnd = moment().add(timeSchedulerBefore, 'hour').toDate();

  /** @type {FlashSaleScheduler[]} */
  const listSchedulerExisted = await apiFlashsaleSchedulerSlot(shopId);

  const listSlotTimeAll = await getListSlotTimeAll();

  const matchTimeSlot = (item) => {
    const { timeStart, timeEnd, timeSlotId } = item;

    if (moment(timeRangeEnd) < moment(timeEnd)) {
      return false;
    }

    const isExisted = listSchedulerExisted.some((itemScheduler) => Number(itemScheduler.timeId) === Number(timeSlotId));

    if (isExisted) {
      return false;
    }

    const currentHourStart = moment(timeStart).hour();

    if (!(currentHourStart >= timeSlotStart && currentHourStart <= timeSlotEnd)) {
      return false;
    }

    return true;
  };

  const listSlotTimeMatch = listSlotTimeAll.filter(matchTimeSlot);

  const listSchedulerCreated = [];

  await PromiseMap(listSlotTimeMatch, async (payloadSlotTime, timeIndex) => {
    const { timeSlotId, timeStart, timeEnd } = payloadSlotTime;

    const flashsaleName = `${moment(timeStart).format('YYYY/MM/DD')} - ${moment(timeStart).format('HH:mm:ss')} - ${moment(timeEnd).format('HH:mm:ss')}`;

    const timeSchedule = moment(timeStart).subtract(timeFlashsaleBefore, 'hour');

    const timeSlot = {
      label: flashsaleName,
      text: flashsaleName,
      labelTime: flashsaleName,
      date: moment(timeStart).format('YYYY/MM/DD'),
      startTime: timeStart,
      endTime: timeEnd,
      value: timeSlotId,
      timeId: timeSlotId,
    };

    /** @type {FlashSaleScheduler} */
    const payloadScheduler = {
      timeSlot,
      productCount,
      timeId: timeSlotId,
      campaignRef: campaignId,
      campaignName: campaignData.campaignName,
      listSet,
      listIndex,
      shopId,
      shopName,
      timeBefore: timeFlashsaleBefore,
      name: flashsaleName,
      timeLabel: flashsaleName,
      timeFlashsale: timeStart,
      timeSchedule,
    };

    await apiFlashsaleSchedulerCreate(payloadScheduler).then((flashsaleScheduler) => {
      listSchedulerCreated.push(flashsaleScheduler);

      if (callbackScheduler) {
        callbackScheduler({
          flashsaleScheduler,
          current: timeIndex + 1,
          total: listSlotTimeMatch.length,
        });
      }
    }).catch((error) => {
      loggerShopee.error({
        msg: 'FLASHSALE_CAMPAIGN_CREATE_SCHEDULER_ERROR',
        payloadScheduler,
        error,
      });
    });

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

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

  return listSchedulerCreated;
};

export const createScheduleFlashsaleFromCampaignShopId = async (shopId, callbackScheduler = null) => {
  if (!shopId) {
    throw 'SHOPEE_FLASHSALE_CAMPAIGN_VALIDATE_SHOP_ID_REQUIRED';
  }

  const { KvLocker } = await getKvLockApi('create-from-shop', shopId, 120);

  if (!KvLocker) {
    return [];
  }

  /** @type {FlashSaleCampaignScheduler[]} */
  const listCampaignAll = await apiFlashsaleCampaignList(shopId);

  const listCampaignScheduler = listCampaignAll.filter((item) => item.active && moment(item.timeCampaginStart) < moment() && moment(item.timeCampaginEnd) > moment());

  await PromiseMap(listCampaignScheduler, async (campaignData) => {
    await createScheduleFromCampaignId(campaignData._id, callbackScheduler).catch((error) => {
      loggerShopee.error({
        msg: 'FLASHSALE_CAMPAIGN_CREATE_SCHEDULER_ERROR',
        campaignData,
        error,
      });
    });
  }, {
    concurrency: 1,
  });

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

  return listCampaignScheduler;
};
