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 _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 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';
import { locales } from "@pisell/utils";
import { getCacheParams, getServeStartTime, getLastServer, flexibleObj, getServiceTimes, findNextDuration, getDays, isSessionProduct } from "../utils";
import { isOption } from "../../ticketBooking/components/addServiceVariant/utils";

// 获取当前剩余量
var getUseableEventCount = function getUseableEventCount(eventList, current) {
  return (eventList || []).reduce(function (pre, event) {
    return pre - event.pax;
  }, current || 0);
};

// 判断两个时间段是否有冲突
var isConflict = function isConflict(event, current) {
  var eventStart = dayjs(event.start_at);
  var eventEnd = dayjs(event.end_at);
  var currentStart = dayjs(current.start_at);
  var _isBefore = currentStart.isBefore(eventEnd);
  var _isAfter = true;

  // 如果传递结束时间,则比对结束时间
  if (current.end_at) {
    var currentEnd = dayjs(current.end_at);
    _isAfter = currentEnd.isAfter(eventStart);
  }

  // 检查是否有重叠
  return _isBefore && _isAfter;
};

// 从times中找可用的time
export var getResourceTimeIsUsable = function getResourceTimeIsUsable(item, cacheItem, resourceItem) {
  // 当前资源的开始时间
  var startDate = dayjs(dayjs(cacheItem._extend.start_date).format("YYYY-MM-DD") + ' ' + getServeStartTime(cacheItem._extend.start_time));

  // 是否为灵活时长
  var isFlexible = flexibleObj.isFlexible(cacheItem._extend.duration);

  // 是否在最大预约数量的区间内
  var isMaxLimitRange = false;

  // 是否在日期范围内
  var isDateRange = false;

  // 是否在数量范围内
  var isCountRange = false;
  var time = _objectSpread({}, item);

  // 当前time的开始时间
  var timeStartDate = dayjs(time.start_date + " " + time.start_time).subtract(1, "second");

  // 当前time的结束时间
  var timeEndDate = dayjs(time.end_date + " " + time.end_time).add(1, "second");

  // 总剩余量
  var totalCount = getUseableEventCount(time.event_list, resourceItem.capacity);

  // 当前预约量
  var currentCount = getSumCapacity({
    cacheItem: cacheItem
  });

  // 已预约的列表
  var eventList = time.event_list || [];

  // todo: event_list数据会进行合并 id不准确
  // 编辑时过滤当前预约
  if (cacheItem !== null && cacheItem !== void 0 && cacheItem.booking_id) {
    eventList = eventList.filter(function (event) {
      return event.id !== (cacheItem === null || cacheItem === void 0 ? void 0 : cacheItem.booking_id);
    });
  }
  var endDate = null;
  // 是否去计算数量
  var isCalcCount = true;

  /**
   * 从这里为判断是否在时间范围内
   */
  if (isFlexible) {
    // 如果有event, 那么灵活时长时间只能在 最后一个event的结束时间 ~ time的结束时间内
    // if (eventList.length) {
    //   timeStartDate = (eventList).reduce((max: any, event: any) => {
    //     const endAt = dayjs(event.end_at);
    //     return endAt.isAfter(max) ? endAt : max;
    //   }, dayjs(eventList[0].end_at));
    // }

    isDateRange = startDate.isAfter(timeStartDate) && startDate.isBefore(timeEndDate);

    // 如果灵活时长不在范围内, 则认为是已约满
    if (!isDateRange && eventList.length) {
      isCalcCount = false;
      isDateRange = true;
      isCountRange = false;
    }
  } else {
    // 其余判断 开始时间 和 结束时间 是否都在范围内
    endDate = startDate.add(flexibleObj.getValue(cacheItem._extend.duration), "minute");

    // 是否在time范围内
    var isTimeRange = startDate.isAfter(timeStartDate) && endDate.isBefore(timeEndDate);
    if (isTimeRange) {
      isDateRange = true;
    }
  }
  if (isCalcCount) {
    // 如果 预约人数超过总容量, 则不可用
    // if (totalCount < currentCount) {
    // isCountRange = false;
    // } else {
    /**
    * 从这里判断预约量
    */

    // 取出已预约列表和当前预约重叠的时间段
    var conflict = (eventList || []).filter(function (d) {
      return isConflict({
        start_at: d.start_at,
        end_at: d.end_at
      }, {
        start_at: startDate,
        end_at: endDate
      });
    });

    // 同一时间段内只能进行一个预约，无论容量是否已满。
    if (resourceItem.resourceType === 'single') {
      // 0代表着不重叠,则满足条件
      if (conflict.length === 0) {
        isCountRange = true;
      } else {
        isCountRange = false;
      }
    } else {
      // 减去重叠的总量
      var conflictCount = getUseableEventCount(conflict, resourceItem.capacity);

      // 当前预约量 <= 总剩余容量
      if (currentCount <= conflictCount) {
        isCountRange = true;
      } else {
        isCountRange = false;
      }
    }

    // }
  }

  // 是否可用  只判断是否在日期范围内, 
  var isUsable = isDateRange && isCountRange;

  // 储存到拓展数据内
  time._extend = {
    isMaxLimitRange: isMaxLimitRange,
    isDateRange: isDateRange,
    isCountRange: isCountRange,
    isUsable: isUsable
  };
  return time;
};
export var getSumCapacity = function getSumCapacity(_ref) {
  var _cacheItem$_extend;
  var cacheItem = _ref.cacheItem;
  var isCalcQuantity = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  var sum = 0;
  var _iterator = _createForOfIteratorHelper(cacheItem._extend.capacity || []),
    _step;
  try {
    for (_iterator.s(); !(_step = _iterator.n()).done;) {
      var item = _step.value;
      sum += item.value;
    }
  } catch (err) {
    _iterator.e(err);
  } finally {
    _iterator.f();
  }
  return sum * (isCalcQuantity ? (cacheItem === null || cacheItem === void 0 || (_cacheItem$_extend = cacheItem._extend) === null || _cacheItem$_extend === void 0 ? void 0 : _cacheItem$_extend.quantity) || 1 : 1);
};

/**
 * @title: 查找是否有可用的time
 * @description:
 * @param {any} resourceItem
 * @return {*}
 * @Author: zhiwei.Wang
 * @Date: 2024-01-09 13:57
 */
export var formatTimes = function formatTimes(resourceItem, cacheItem) {
  // 可用的time列表
  var usableTimes = [];
  var _resourceItem = _objectSpread({}, resourceItem);
  var sum = getSumCapacity({
    cacheItem: cacheItem
  });

  // 如果可预约数量大于等于当前预约数量
  if (_resourceItem.capacity >= sum) {
    // 循环times  区分可用和不可用的 并打上标记
    _resourceItem.times = _resourceItem.times.map(function (time) {
      var _time = getResourceTimeIsUsable(time, cacheItem, _resourceItem);
      // 取出可用的列表
      if (_time !== null && _time !== void 0 && _time._extend.isDateRange) {
        usableTimes.push(_time);
      }
      return _time;
    });
  }

  // 获取第一个最佳的time
  var _time = (usableTimes || []).sort(function (a, b) {
    var aEndDate = dayjs(a.end_date + " " + a.end_time).valueOf();
    var bEndDate = dayjs(b.end_date + " " + b.end_time).valueOf();
    return aEndDate - bEndDate;
  })[0];
  resourceItem._extend = _objectSpread(_objectSpread({}, resourceItem._extend), {}, {
    usableTime: _time
  });
  return resourceItem;
};
export var getErrorList = function getErrorList(resource, cacheItem) {
  if (!(cacheItem !== null && cacheItem !== void 0 && cacheItem.id)) {
    return [{
      label: locales.getText('pisell2.text.no-product-added'),
      type: "products"
    }];
  }
  if (!resource) {
    return [];
  }
  var list = [];
  // 当前资源不可用
  if (!resource.usable) {
    var _cacheItem$_data, _resource$_extend;
    var _getServiceTimes = getServiceTimes(cacheItem),
      startDate = _getServiceTimes.startDate,
      endDate = _getServiceTimes.endDate;
    // 如果跨天  结束时间前面加一个明天
    var startText = startDate.format("hh:mm A");
    var endText = endDate.format("hh:mm A");
    if (dayjs(endDate).isAfter(startDate, "day")) {
      endText = locales.getText('pisell1.text.tomorrow') + endText;
    }
    var isSingle = (cacheItem === null || cacheItem === void 0 || (_cacheItem$_data = cacheItem._data) === null || _cacheItem$_data === void 0 || (_cacheItem$_data = _cacheItem$_data.resourceMaps) === null || _cacheItem$_data === void 0 || (_cacheItem$_data = _cacheItem$_data[resource === null || resource === void 0 ? void 0 : resource.form_id]) === null || _cacheItem$_data === void 0 ? void 0 : _cacheItem$_data.type) === "single";
    if (!((_resource$_extend = resource._extend) !== null && _resource$_extend !== void 0 && _resource$_extend.usableTime)) {
      list.push({
        label: locales.getText('pisell1.text.resource-error-message-2')(resource.labelText, startText, endText),
        type: "time"
      });
    } else {
      var _resource$_extend2;
      if (!((_resource$_extend2 = resource._extend) !== null && _resource$_extend2 !== void 0 && (_resource$_extend2 = _resource$_extend2.usableTime) !== null && _resource$_extend2 !== void 0 && (_resource$_extend2 = _resource$_extend2._extend) !== null && _resource$_extend2 !== void 0 && _resource$_extend2.isCountRange)) {
        list.push({
          label: locales.getText('pisell1.text.resource-error-message-3')(resource.labelText, startText, endText),
          type: "limit"
        });
      }
    }
  }

  // 平行资源日历拖动优化需求
  // 拖入到未绑定的资源中
  if (resource.unbound) {
    list.push({
      label: locales.getText('pisell1.text.resource-error-message-unbound'),
      type: "time"
    });
  }
  return list;
};

/**
 * @title: 格式化资源, 添加自定义参数
 * @description:
 * @param {any} resourceItem
 * @return {*}
 * @Author: zhiwei.Wang
 * @Date: 2024-01-09 13:40
 */
export var formatResource = function formatResource(resourceItem, cacheItem, formatLabel) {
  var _resourceItem$_extend;
  // 当前资源
  var _resourceItem = _objectSpread({}, resourceItem);
  // 格式化times里面的数据
  _resourceItem = formatTimes(_resourceItem, cacheItem);

  // 格式化label
  _resourceItem.labelText = _resourceItem.main_field;
  var usable = (_resourceItem$_extend = _resourceItem._extend.usableTime) === null || _resourceItem$_extend === void 0 || (_resourceItem$_extend = _resourceItem$_extend._extend) === null || _resourceItem$_extend === void 0 ? void 0 : _resourceItem$_extend.isUsable;
  _resourceItem.usable = usable;
  if (formatLabel) {
    _resourceItem.label = formatLabel(_resourceItem);
  }
  return _resourceItem;
};

// 获取预约时间偏好设置
export var getAppointmentTimingPreference = function getAppointmentTimingPreference(state) {
  var _state$bookingConfig;
  return (state === null || state === void 0 || (_state$bookingConfig = state.bookingConfig) === null || _state$bookingConfig === void 0 || (_state$bookingConfig = _state$bookingConfig.config) === null || _state$bookingConfig === void 0 || (_state$bookingConfig = _state$bookingConfig.information_tab) === null || _state$bookingConfig === void 0 ? void 0 : _state$bookingConfig.appointment_timing_preference) || "sequential";
};

/**
 * @title: 创建服务的开始时间和结束时间
 * @description: 
 * @param {any} state
 * @param {any} item
 * @return {*}
 * @Author: zhiwei.Wang
 * @Date: 2024-01-26 14:09
 */
export var getServiceStartTimeAndEndTime = function getServiceStartTimeAndEndTime(state, cacheItem, timeObj) {
  var _state$service$value, _cacheItem$duration, _cacheItem$_extend2;
  // 自定义商品不需要时间相关处理，直接返回基础扩展参数
  if (cacheItem !== null && cacheItem !== void 0 && cacheItem.isCustomItem) {
    return {
      duration: null // 自定义商品没有时长概念
    };
  }
  var appointmentTimingPreference = getAppointmentTimingPreference(state);

  // 获取上一个服务商品（过滤掉自定义商品）
  var lastServer = getLastServer((_state$service$value = state.service.value) === null || _state$service$value === void 0 ? void 0 : _state$service$value.filter(function (item) {
    return !item.isCustomItem;
  }));

  // 下一个商品的扩展参数
  var _extend = {
    // 时长: 当前商品时长 > 第一个时长
    duration: findNextDuration(cacheItem.duration, timeObj === null || timeObj === void 0 ? void 0 : timeObj.durationSlicesBasedOnTime, cacheItem === null || cacheItem === void 0 || (_cacheItem$duration = cacheItem.duration) === null || _cacheItem$duration === void 0 ? void 0 : _cacheItem$duration.value)
  };

  // 如果有上一个商品, 将上一个商品的某些参数 设置到新商品上
  if (lastServer) {
    var lastServerStartDate = lastServer._extend.startDate;
    var lastServerEndDate = lastServer._extend.endDate;

    // 同时预约模式
    if (appointmentTimingPreference === 'parallel') {
      _extend.start_time = lastServerStartDate.format('HH:mm');
    } else {
      // 如果上个服务商品的结束时间跨天, 那么设置为最后一个时间段,  不跨天则取上一个的结束时间
      if (dayjs(lastServerEndDate).isAfter(lastServerStartDate, "day")) {
        var _timeObj$timeSlices;
        _extend.start_time = timeObj === null || timeObj === void 0 ? void 0 : timeObj.timeSlices[(timeObj === null || timeObj === void 0 || (_timeObj$timeSlices = timeObj.timeSlices) === null || _timeObj$timeSlices === void 0 ? void 0 : _timeObj$timeSlices.length) - 1].value;
      } else {
        _extend.start_time = lastServerEndDate.format("HH:mm");
      }
    }
  } else {
    // 没有上一个商品  资源为 0
    // _extend.resource = 0;

    var findNextSliceProps = {
      date: ''
    };

    // 从缓存里读默认参数,  如果有 则需要默认选中某些参数,  添加完商品后则删除
    var serviceParams = getCacheParams();
    if (serviceParams) {
      var str = serviceParams.start_date;
      if (str) {
        // 选中开始时间
        findNextSliceProps.date = dayjs(str).format('HH:mm');
      }
    }

    // 只有选择了带 HH:mm的日期才选中, 否则使用当前日期
    if (findNextSliceProps.date && findNextSliceProps.date !== '00:00') {
      _extend.start_time = findNextSliceProps.date;
    } else {
      if (cacheItem.currentDefaultTime) {
        _extend.start_time = cacheItem.currentDefaultTime;
      } else {
        // 没有预设日期, 则使用当前 https://www.yuque.com/feg4xm/manual/tzvrnt05ifihkndg
        _extend.start_time = dayjs().format('HH:mm');
      }
    }
  }
  _extend = _objectSpread(_objectSpread({}, _extend), cacheItem._extend);

  // 计算服务的开始和结束时间
  var _getServiceTimes2 = getServiceTimes({
      _extend: _extend
    }),
    startDate = _getServiceTimes2.startDate,
    endDate = _getServiceTimes2.endDate;
  _extend.startDate = startDate;
  _extend.endDate = endDate;
  var session = cacheItem === null || cacheItem === void 0 || (_cacheItem$_extend2 = cacheItem._extend) === null || _cacheItem$_extend2 === void 0 || (_cacheItem$_extend2 = _cacheItem$_extend2.other) === null || _cacheItem$_extend2 === void 0 ? void 0 : _cacheItem$_extend2.session;
  if (isSessionProduct(cacheItem) && session) {
    _extend.start_date = session.start_at;
    _extend.startDate = session.start_at;
    _extend.start_time = session.start_time;
    _extend.end_date = session.end_at;
    _extend.endDate = session.end_at;
    _extend.duration = getDays({
      _extend: _extend
    }, 'minutes');
  }
  return _extend;
};

// 是否是无规格无套餐商品的非预约商品
export var getIsNoSpecAndPackage = function getIsNoSpecAndPackage(product) {
  var _product$variant;
  if ((product === null || product === void 0 ? void 0 : product.extension_type) !== 'normal') {
    return false;
  }
  // 编辑状态参数判断
  if (product !== null && product !== void 0 && product.isEditBooking) {
    var _product$product_bund, _product$product_sku;
    return (product === null || product === void 0 || (_product$product_bund = product.product_bundle) === null || _product$product_bund === void 0 ? void 0 : _product$product_bund.length) === 0 && (product === null || product === void 0 ? void 0 : product.product_variant_id) === 0 && ((product === null || product === void 0 || (_product$product_sku = product.product_sku) === null || _product$product_sku === void 0 || (_product$product_sku = _product$product_sku.option) === null || _product$product_sku === void 0 ? void 0 : _product$product_sku.length) || 0) === 0;
  }
  return (product === null || product === void 0 ? void 0 : product.is_bundle) === 0 && ((product === null || product === void 0 || (_product$variant = product.variant) === null || _product$variant === void 0 ? void 0 : _product$variant.length) || 0) === 0 && !isOption(product);
};