import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
import React, { useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import { getPosition, scrollTop } from 'dom-lib';
import partial from 'lodash/partial';
import camelCase from 'lodash/camelCase';
import isNumber from 'lodash/isNumber';
import { DateUtils, scrollTopAnimation, TimeZone, useClassNames } from '../utils';
import { useCalendarContext } from './CalendarContext';
var defaultProps = {
  classPrefix: 'calendar-time-dropdown',
  as: 'div'
};

/**
 * Get the effective range of hours, minutes and seconds
 * @param meridian
 */
export function getRanges(meridian) {
  return {
    hours: {
      start: 0,
      end: meridian ? 11 : 23
    },
    minutes: {
      start: 0,
      end: 59
    },
    seconds: {
      start: 0,
      end: 59
    }
  };
}
/**
 * Convert the 24-hour clock to the 12-hour clock
 * @param hours
 */

export function getMeridianHours(hours) {
  return hours >= 12 ? hours - 12 : hours;
}

var getTime = function getTime(props) {
  var format = props.format,
      timeZone = props.timeZone,
      date = props.date,
      showMeridian = props.showMeridian;
  var time = date || TimeZone.zonedDate(timeZone);
  var nextTime = {};

  if (!format) {
    return nextTime;
  }

  if (/(H|h)/.test(format)) {
    var hours = DateUtils.getHours(time);
    nextTime.hours = showMeridian ? getMeridianHours(hours) : hours;
  }

  if (/m/.test(format)) {
    nextTime.minutes = DateUtils.getMinutes(time);
  }

  if (/s/.test(format)) {
    nextTime.seconds = DateUtils.getSeconds(time);
  }

  return nextTime;
};

var scrollTo = function scrollTo(time, row) {
  if (!row) {
    return;
  }

  Object.entries(time).forEach(function (_ref) {
    var type = _ref[0],
        value = _ref[1];
    var container = row.querySelector("[data-type=\"" + type + "\"]");
    var node = container === null || container === void 0 ? void 0 : container.querySelector("[data-key=\"" + type + "-" + value + "\"]");

    if (node && container) {
      var _getPosition = getPosition(node, container),
          top = _getPosition.top;

      scrollTopAnimation(container, top, scrollTop(container) !== 0);
    }
  });
};

var TimeDropdown = /*#__PURE__*/React.forwardRef(function (props, ref) {
  var Component = props.as,
      className = props.className,
      classPrefix = props.classPrefix,
      show = props.show,
      showMeridian = props.showMeridian,
      rest = _objectWithoutPropertiesLoose(props, ["as", "className", "classPrefix", "show", "showMeridian"]);

  var _useCalendarContext = useCalendarContext(),
      locale = _useCalendarContext.locale,
      format = _useCalendarContext.format,
      timeZone = _useCalendarContext.timeZone,
      date = _useCalendarContext.date,
      onSelect = _useCalendarContext.onChangePageTime;

  var rowRef = useRef(null);
  useEffect(function () {
    var time = getTime({
      format: format,
      timeZone: timeZone,
      date: date,
      showMeridian: showMeridian
    }); // The currently selected time scrolls to the visible range.

    show && scrollTo(time, rowRef.current);
  }, [date, format, show, showMeridian, timeZone]);

  var handleClick = function handleClick(type, d, event) {
    var nextDate = date || new Date();

    switch (type) {
      case 'hours':
        nextDate = DateUtils.setHours(date, d);
        break;

      case 'minutes':
        nextDate = DateUtils.setMinutes(date, d);
        break;

      case 'seconds':
        nextDate = DateUtils.setSeconds(date, d);
        break;
    }

    onSelect === null || onSelect === void 0 ? void 0 : onSelect(nextDate, event);
  };

  var _useClassNames = useClassNames(classPrefix),
      prefix = _useClassNames.prefix,
      rootPrefix = _useClassNames.rootPrefix,
      merge = _useClassNames.merge;

  var renderColumn = function renderColumn(type, active) {
    if (!isNumber(active)) {
      return null;
    }

    var _getRanges$type = getRanges(showMeridian)[type],
        start = _getRanges$type.start,
        end = _getRanges$type.end;
    var items = [];
    var hideFunc = props[camelCase("hide_" + type)];
    var disabledFunc = props[camelCase("disabled_" + type)];

    for (var i = start; i <= end; i += 1) {
      if (!(hideFunc === null || hideFunc === void 0 ? void 0 : hideFunc(i, date))) {
        var disabled = disabledFunc === null || disabledFunc === void 0 ? void 0 : disabledFunc(i, date);
        var itemClasses = prefix('cell', {
          'cell-active': active === i,
          'cell-disabled': disabled
        });
        items.push( /*#__PURE__*/React.createElement("li", {
          key: i,
          role: "menuitem"
        }, /*#__PURE__*/React.createElement("a", {
          role: "button",
          className: itemClasses,
          tabIndex: -1,
          "data-key": type + "-" + i,
          onClick: !disabled ? partial(handleClick, type, i) : null
        }, showMeridian && type === 'hours' && i === 0 ? '12' : i)));
      }
    }

    return /*#__PURE__*/React.createElement("div", {
      className: prefix('column'),
      role: "listitem"
    }, /*#__PURE__*/React.createElement("div", {
      className: prefix('column-title')
    }, locale === null || locale === void 0 ? void 0 : locale[type]), /*#__PURE__*/React.createElement("ul", {
      "data-type": type,
      role: "menu"
    }, items));
  };

  var time = getTime({
    format: format,
    timeZone: timeZone,
    date: date,
    showMeridian: showMeridian
  });
  var classes = merge(className, rootPrefix(classPrefix));
  return /*#__PURE__*/React.createElement(Component, _extends({
    role: "list"
  }, DateUtils.omitHideDisabledProps(rest), {
    ref: ref,
    className: classes
  }), /*#__PURE__*/React.createElement("div", {
    className: prefix('content')
  }, /*#__PURE__*/React.createElement("div", {
    className: prefix('row'),
    ref: rowRef
  }, renderColumn('hours', time.hours), renderColumn('minutes', time.minutes), renderColumn('seconds', time.seconds))));
});
TimeDropdown.displayName = 'TimeDropdown';
TimeDropdown.defaultProps = defaultProps;
TimeDropdown.propTypes = {
  show: PropTypes.bool,
  showMeridian: PropTypes.bool,
  className: PropTypes.string,
  classPrefix: PropTypes.string,
  disabledDate: PropTypes.func,
  disabledHours: PropTypes.func,
  disabledMinutes: PropTypes.func,
  disabledSeconds: PropTypes.func,
  hideHours: PropTypes.func,
  hideMinutes: PropTypes.func,
  hideSeconds: PropTypes.func
};
export default TimeDropdown;