Source: utils/parameters.js

/**
 * @namespace Utils
 * @description Other instruments for normal working project
 */


import DomService from '../initiators/domService';

/**
 * @memberof Utils
 * @constructor Parameters
 * @param {string} selector - selector to main wrapper for promotion block
 * @example
 * const params = parameters.parse('.Promotion');
 */
export default class Parameters {
  defaultParams = {
    startDate: 'none',
    endDate: 'none',
    withoutTimer: false,
    name: '', // normal name ex "WINTER FROST DISCOUNTS UP TO -70%"
    timerFace: 'daily', // daily || hourly || counter
    timerDirection: 'decrement', // decrement || increment
    closeCookieLifeTime: '-1', // in days -> -1 (to end promotion) || 1-9999 (days promotion is close)
    timerCounter: 1,
    popupId: 'unusedBlockId',
    locale: 'en',
    errors: false,
    errorMessage: '',
    isLink: 0,
    link: 'empty',
    targetBlank: 1,
    isSticky: 1,
    promocodePageId: false,
  };
  params = {};

  /**
   * @method Parameters#parse
   * @memberof Utils
   * @description Parse and return all params
   * @param {string} selector jQuery selector
   * @example
   * const params = new Parameters();
   * params.parse('.Promotion');
   * @return {Object}
   */
  parse(selector) {
    const el = DomService.get(selector);
    const dataSet = DomService.data(el);
    this.params = this.prepareData({
      ...this.defaultParams,
      ...dataSet,
    });
    return this.params;
  }

  /**
   * @method Parameters#update
   * @memberof Utils
   * @description Parse and return all params
   * @param {Object} data new data
   * @example
   * const params = new Parameters();
   * params.update({});
   * @return {Object}
   */
  update(data) {
    return this.prepareData({
      ...this.params,
      ...data,
    });
  }

  /**
   * @method Parameters#prepareData
   * @memberof Utils
   * @description prepare data for all initiators
   * @param {Object} data row parameters
   * @return {Object} data
   */
  prepareData(data) {
    const other = { ...data, ...this.other(data) };
    const lang = { ...other, ...this.lang(other) };
    const time = { ...lang, ...this.time(lang) };
    const flipClock = { ...time, ...this.flipClock(time) };
    const banner = { ...flipClock, ...this.banner(flipClock) };
    const validate = { ...banner, ...this.validate(banner) };
    if (validate.errors) throw new Error(validate.errorMessage);
    return validate;
  }

  /**
   * @method Parameters#validate
   * @memberof Utils
   * @description prepare data for time
   * @param {Object} data row parameters
   * @return {Object} validate data
   */
  validate = (data) => {
    const newData = data;
    if (data.startDate === 'none') return data;
    if (!newData.name.length) {
      newData.errorMessage = 'Field "data-name" is not valid. Is required.';
    } else if (JSON.stringify(new Date(newData.startDate)) === 'null') {
      newData.errorMessage = 'Value "data-start-date" is not valid. Format mm/dd/yyy hh:mm:ss and is required.';
    } else if (JSON.stringify(new Date(newData.endDate)) === 'null') {
      newData.errorMessage = 'Value "data-end-date" is not valid. Format mm/dd/yyy hh:mm:ss and is required.';
    }

    if (newData.errorMessage.length) newData.errors = true;
    return newData;
  };

  /**
   * @method Parameters#other
   * @memberof Utils
   * @description prepare data for other
   * @param {Object} data row parameters
   * @return {Object} data
   */
  other = data => ({
    ...data,
    id: data.name.toLowerCase().replace(' ', '_'),
    targetBlank: parseInt(data.targetBlank, 10),
    isSticky: parseInt(data.isSticky, 10),
  });

  /**
   * @method Parameters#lang
   * @memberof Utils
   * @description prepare data for lang
   * @param {Object} data row parameters
   * @return {Object} data
   */
  lang = (data) => {
    const newData = data;
    switch (newData.locale) {
      case 'br':
        newData.locale = 'pt';
        break;
      case 'cn':
        newData.locale = 'zh';
        break;
      case 'se':
        newData.locale = 'sv';
        break;
      default:
        break;
    }
    return newData;
  };

  /**
   * @method Parameters#time
   * @memberof Utils
   * @description prepare data for time
   * @param {Object} data row parameters
   * @return {Object} data
   */
  time = (data) => {
    const endDateMs = new Date(data.endDate).getTime();
    const startDateMs = new Date(data.startDate).getTime();
    const currentDateMs = new Date().getTime();
    return {
      ...data,
      endDateMs,
      startDateMs,
      currentDateMs,
      endDateS: endDateMs / 1000,
      startDateS: startDateMs / 1000,
      currentDateS: currentDateMs / 1000,
    };
  };

  /**
   * @method Parameters#flipClock
   * @memberof Utils
   * @description prepare data for flipClock
   * @param {Object} data row parameters
   * @return {Object} final Data
   */
  flipClock = (data) => {
    const newData = data;
    newData.withoutTimer = data.startDate === 'none';
    newData.language = newData.locale;
    newData.countdown = newData.timerDirection === 'decrement';
    newData.time = (newData.endDateS - newData.currentDateS);
    newData.timerCounter = parseInt(newData.timerCounter, 10);
    const {
      endDateMs,
      startDateMs,
      timerCounter,
      currentDateMs,
    } = newData;

    switch (newData.timerFace) {
      case 'daily':
        newData.clockFace = 'PlasmaDailyCounter';
        break;
      case 'hourly':
        newData.clockFace = 'PlasmaHourlyCounter';
        break;
      case 'counter':
        newData.clockFace = 'counter';
        newData.timeInterval = Math.ceil((endDateMs - startDateMs) / timerCounter);
        newData.time = (endDateMs - currentDateMs) / newData.timeInterval;
        break;
      default:
        newData.clockFace = newData.timerFace;
        break;
    }
    return newData;
  };

  /**
   * @method Parameters#banner
   * @memberof Utils
   * @description prepare data for banner and popup
   * @param {Object} data row parameters
   * @return {Object} final Data
   */
  banner = data => ({
    ...data,
    href: data.link === 'empty' ? '#' : data.link,
    isLink: parseInt(data.isLink, 10),
  });
}