var _excluded = ["form_id", "id", "times"];
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import dayjs from 'dayjs';
/**
 * 生成当前月份的所有日期
 * @param startDate 开始日期
 * @param endDate 结束日期
 * @param type 类型：按月查 ｜ 按周查
 * @returns 日期列表
 */
export var generateMonthDates = function generateMonthDates(startDate, endDate, type) {
  // 如果是按月查询需要从01号开始，如果是按周查询以开始结束时间为准
  var start = type === 'day' ? dayjs(startDate).format('YYYY-MM-DD') : dayjs(startDate).format('YYYY-MM-01');
  var end = dayjs(endDate).format('YYYY-MM-DD');
  var dates = [];
  var currentDate = dayjs(start);
  while (dayjs(currentDate).isBefore(dayjs(end), 'day') || dayjs(currentDate).isSame(dayjs(end), 'day')) {
    dates.push({
      date: dayjs(currentDate).format('YYYY-MM-DD'),
      week: dayjs(currentDate).format('ddd'),
      weekNum: dayjs(currentDate).day(),
      status: 'available'
    });
    currentDate = dayjs(currentDate).add(1, 'day');
  }
  return dates;
};

/**
 * 禁用所有日期
 * @param dates 日期列表
 * @returns 日期列表
 */
export var disableAllDates = function disableAllDates(dates) {
  return dates.map(function (date) {
    return _objectSpread(_objectSpread({}, date), {}, {
      status: 'unavailable'
    });
  });
};

/**
 * 禁用某一天之前的日期，如不传则默认今天
 * @param dates 日期列表
 * @param oneDay 日期
 * @returns 日期列表
 */
export var disableDatesBeforeOneDay = function disableDatesBeforeOneDay(dates, oneDay) {
  var day = oneDay ? dayjs(oneDay).format('YYYY-MM-DD') : dayjs().format('YYYY-MM-DD');
  return dates.map(function (date) {
    if (dayjs(date.date).isBefore(day, 'day')) {
      return _objectSpread(_objectSpread({}, date), {}, {
        status: 'unavailable'
      });
    } else {
      return date;
    }
  });
};

/**
 * 根据资源中的日期处理出每个日期下存在的可用资源，根据form_id进行分类
 * @param resources 资源列表
 * @param dates 日期列表
 * @returns 日期列表
 */
export var handleAvailableDateByResource = function handleAvailableDateByResource(resources, dates) {
  var dateMap = {};
  resources.forEach(function (resource) {
    var form_id = resource.form_id,
      id = resource.id,
      times = resource.times,
      others = _objectWithoutProperties(resource, _excluded);
    times.forEach(function (time) {
      var start_at = time.start_at;
      var date = dayjs(start_at).format('YYYY-MM-DD');
      if (!dateMap[date]) {
        dateMap[date] = [_objectSpread(_objectSpread({
          form_id: form_id,
          id: id
        }, others), {}, {
          times: [time]
        })];
      } else {
        var _dateMap$date$filter;
        var temp = (_dateMap$date$filter = dateMap[date].filter(function (item) {
          return item.id === id;
        })) === null || _dateMap$date$filter === void 0 ? void 0 : _dateMap$date$filter[0];
        if (temp) {
          temp.times.push(time);
        } else {
          dateMap[date].push(_objectSpread(_objectSpread({
            form_id: form_id,
            id: id
          }, others), {}, {
            times: [time]
          }));
        }
      }
    });
  });
  return dates.map(function (date) {
    var resource = dateMap[date.date];
    if (resource) {
      return _objectSpread(_objectSpread({}, date), {}, {
        resource: resource
      });
    } else {
      return _objectSpread(_objectSpread({}, date), {}, {
        status: 'unavailable',
        resource: []
      });
    }
  });
};

/**
 * 根据规则判定哪些日期是可用的
 * @param dates 日期列表
 * @param rules 提前量规则
 * @returns 日期列表
 */
export var handleAvailableDatesByRules = function handleAvailableDatesByRules(dates, rules) {
  var newDates = disableDatesBeforeOneDay(dates);
  if (!(rules !== null && rules !== void 0 && rules.length)) {
    return newDates;
  }
  var scheduleMap = {}; // 日程列表
  var latestStartDate = ''; // 最晚开始日期
  var earliestEndDate = ''; // 最早结束日期
  var resourceFormIds = [];
  rules.forEach(function (rule) {
    var _rule$schedule, _rule$resourceFormIds;
    // 如果有日程列表，需要将它去重加入到scheduleMap
    if (rule !== null && rule !== void 0 && (_rule$schedule = rule.schedule) !== null && _rule$schedule !== void 0 && _rule$schedule.length) {
      var _iterator = _createForOfIteratorHelper(rule.schedule),
        _step;
      try {
        for (_iterator.s(); !(_step = _iterator.n()).done;) {
          var item = _step.value;
          // 判断item.date是否在dates的开始和结束日期范围内，如果不在则跳过
          if (dayjs(item.date).isBefore(dayjs(newDates[0].date), 'day')) {
            continue;
          }
          // 判断日程日期是否超过了dates中的最后一个日期，如果超过了则循环break
          if (dayjs(item.date).isAfter(dayjs(newDates[newDates.length - 1].date), 'day')) {
            break;
          }
          // 在范围内的日程如果scheduleMap中不存在，则加入到scheduleMap
          if (!scheduleMap[item.date]) {
            scheduleMap[item.date] = item;
          } else {
            if (!item.isExcluded) {
              scheduleMap[item.date].isExcluded = false;
            }
          }
        }
      } catch (err) {
        _iterator.e(err);
      } finally {
        _iterator.f();
      }
    }
    var _ref = (rule === null || rule === void 0 ? void 0 : rule.cut_off_time) || {},
      future_day = _ref.future_day,
      unit = _ref.unit,
      unit_type = _ref.unit_type;
    // 预定天数存在，则开始计算从当前时间开始往后推预定天数作为结束时间
    if (future_day) {
      var endDate = dayjs().add(future_day, 'day');
      if (!earliestEndDate || endDate.isBefore(dayjs(earliestEndDate), 'day')) {
        earliestEndDate = endDate.format('YYYY-MM-DD');
      }
    } else if (future_day === 0) {
      var _endDate = dayjs();
      if (!earliestEndDate || _endDate.isBefore(dayjs(earliestEndDate), 'day')) {
        earliestEndDate = _endDate.format('YYYY-MM-DD');
      }
    }

    // 如果存在提前预约时间，则开始计算从当前时间开始往后推提前预约时间作为开始时间
    if (unit && unit_type) {
      var startDate = dayjs(dayjs().add(unit, unit_type).format('YYYY-MM-DD'));
      if (!latestStartDate || startDate.isAfter(dayjs(latestStartDate), 'day')) {
        latestStartDate = startDate.format('YYYY-MM-DD');
      }
    }
    if (rule !== null && rule !== void 0 && (_rule$resourceFormIds = rule.resourceFormIds) !== null && _rule$resourceFormIds !== void 0 && _rule$resourceFormIds.length) {
      // 去重
      resourceFormIds = _toConsumableArray(new Set([].concat(_toConsumableArray(resourceFormIds), _toConsumableArray(rule === null || rule === void 0 ? void 0 : rule.resourceFormIds))));
    }
  });
  newDates = newDates.map(function (date) {
    var _date$resource, _resourceFormIds;
    var disabledDate = _objectSpread(_objectSpread({}, date), {}, {
      status: 'unavailable'
    });
    var hasScheduleConfig = rules.find(function (n) {
      var _n$schedule;
      return (_n$schedule = n.schedule) === null || _n$schedule === void 0 ? void 0 : _n$schedule.length;
    });
    // 如果外面穿了 schedule，但是这个时候scheduleMap为空，则设置为不可用
    // 这种情况为，商品设置了 5.1-5.31 可用，资源设置了 5.1-6.30 可用，session 类商品详情弹窗里里看到的6 月以后的日期都应该是不可用的
    if (Object.keys(scheduleMap).length === 0 && hasScheduleConfig) {
      return _objectSpread(_objectSpread({}, date), {}, {
        color: '',
        status: 'unavailable'
      });
    }
    // 根据日程判断日期是否可用
    if (Object.keys(scheduleMap).length) {
      var schedule = scheduleMap[date.date];
      // 如果日程不存在 或者 日程存在但是需要排除，则设置为不可用
      if (!schedule || schedule !== null && schedule !== void 0 && schedule.isExcluded) {
        return _objectSpread(_objectSpread({}, date), {}, {
          color: schedule === null || schedule === void 0 ? void 0 : schedule.color,
          status: 'unavailable'
        });
      } else {
        date.color = schedule === null || schedule === void 0 ? void 0 : schedule.color;
        disabledDate.color = schedule === null || schedule === void 0 ? void 0 : schedule.color;
      }
    }

    // 如果资源不存在，则设置为不可用
    if (!(date !== null && date !== void 0 && (_date$resource = date.resource) !== null && _date$resource !== void 0 && _date$resource.length)) {
      return disabledDate;
    }
    if (latestStartDate || earliestEndDate) {
      // 如果时间在最早开始时间之前，则设置为不可用
      if (latestStartDate && dayjs(date.date).isBefore(latestStartDate, 'day')) {
        return disabledDate;
      }
      // 如果时间在最早结束时间之后，则设置为不可用
      if (earliestEndDate && dayjs(date.date).isAfter(earliestEndDate, 'day')) {
        return disabledDate;
      }
    }

    // 如果存在资源form_id，则开始计算资源form_id在日期上是否全部存在
    if ((_resourceFormIds = resourceFormIds) !== null && _resourceFormIds !== void 0 && _resourceFormIds.length) {
      var hasReourceCount = 0;
      resourceFormIds.forEach(function (formId) {
        var _date$resource2;
        if ((date === null || date === void 0 || (_date$resource2 = date.resource) === null || _date$resource2 === void 0 ? void 0 : _date$resource2.find(function (item) {
          return item.form_id === formId;
        })) !== undefined) {
          hasReourceCount++;
        }
      });
      // 如果所需要的资源在日期上不足，则设置为不可用
      if (hasReourceCount < resourceFormIds.length) {
        return disabledDate;
      }
    }
    return date;
  });
  return newDates;
};