import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import clsx from 'clsx';
import IconButton from '@mui/material/IconButton';
import Typography from '@mui/material/Typography';
import { styled, useThemeProps } from '@mui/material/styles';
import { unstable_useEnhancedEffect as useEnhancedEffect, unstable_composeClasses as composeClasses } from '@mui/utils';
import { ClockPointer } from './ClockPointer';
import { useLocaleText, useUtils } from '../internals/hooks/useUtils';
import { CLOCK_HOUR_WIDTH, getHours, getMinutes } from './shared';
import { getClockUtilityClass } from './clockClasses';
import { formatMeridiem } from '../internals/utils/date-utils';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
var useUtilityClasses = function useUtilityClasses(ownerState) {
  var classes = ownerState.classes;
  var slots = {
    root: ['root'],
    clock: ['clock'],
    wrapper: ['wrapper'],
    squareMask: ['squareMask'],
    pin: ['pin'],
    amButton: ['amButton'],
    pmButton: ['pmButton'],
    meridiemText: ['meridiemText']
  };
  return composeClasses(slots, getClockUtilityClass, classes);
};
var ClockRoot = styled('div', {
  name: 'MuiClock',
  slot: 'Root',
  overridesResolver: function overridesResolver(_, styles) {
    return styles.root;
  }
})(function (_ref) {
  var theme = _ref.theme;
  return {
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    margin: theme.spacing(2)
  };
});
var ClockClock = styled('div', {
  name: 'MuiClock',
  slot: 'Clock',
  overridesResolver: function overridesResolver(_, styles) {
    return styles.clock;
  }
})({
  backgroundColor: 'rgba(0,0,0,.07)',
  borderRadius: '50%',
  height: 220,
  width: 220,
  flexShrink: 0,
  position: 'relative',
  pointerEvents: 'none'
});
var ClockWrapper = styled('div', {
  name: 'MuiClock',
  slot: 'Wrapper',
  overridesResolver: function overridesResolver(_, styles) {
    return styles.wrapper;
  }
})({
  '&:focus': {
    outline: 'none'
  }
});
var ClockSquareMask = styled('div', {
  name: 'MuiClock',
  slot: 'SquareMask',
  overridesResolver: function overridesResolver(_, styles) {
    return styles.squareMask;
  }
})(function (_ref2) {
  var ownerState = _ref2.ownerState;
  return _extends({
    width: '100%',
    height: '100%',
    position: 'absolute',
    pointerEvents: 'auto',
    outline: 0,
    // Disable scroll capabilities.
    touchAction: 'none',
    userSelect: 'none'
  }, ownerState.disabled ? {} : {
    '@media (pointer: fine)': {
      cursor: 'pointer',
      borderRadius: '50%'
    },
    '&:active': {
      cursor: 'move'
    }
  });
});
var ClockPin = styled('div', {
  name: 'MuiClock',
  slot: 'Pin',
  overridesResolver: function overridesResolver(_, styles) {
    return styles.pin;
  }
})(function (_ref3) {
  var theme = _ref3.theme;
  return {
    width: 6,
    height: 6,
    borderRadius: '50%',
    backgroundColor: (theme.vars || theme).palette.primary.main,
    position: 'absolute',
    top: '50%',
    left: '50%',
    transform: 'translate(-50%, -50%)'
  };
});
var ClockAmButton = styled(IconButton, {
  name: 'MuiClock',
  slot: 'AmButton',
  overridesResolver: function overridesResolver(_, styles) {
    return styles.amButton;
  }
})(function (_ref4) {
  var theme = _ref4.theme,
    ownerState = _ref4.ownerState;
  return _extends({
    zIndex: 1,
    position: 'absolute',
    bottom: 8,
    left: 8,
    paddingLeft: 4,
    paddingRight: 4,
    width: CLOCK_HOUR_WIDTH
  }, ownerState.meridiemMode === 'am' && {
    backgroundColor: (theme.vars || theme).palette.primary.main,
    color: (theme.vars || theme).palette.primary.contrastText,
    '&:hover': {
      backgroundColor: (theme.vars || theme).palette.primary.light
    }
  });
});
var ClockPmButton = styled(IconButton, {
  name: 'MuiClock',
  slot: 'PmButton',
  overridesResolver: function overridesResolver(_, styles) {
    return styles.pmButton;
  }
})(function (_ref5) {
  var theme = _ref5.theme,
    ownerState = _ref5.ownerState;
  return _extends({
    zIndex: 1,
    position: 'absolute',
    bottom: 8,
    right: 8,
    paddingLeft: 4,
    paddingRight: 4,
    width: CLOCK_HOUR_WIDTH
  }, ownerState.meridiemMode === 'pm' && {
    backgroundColor: (theme.vars || theme).palette.primary.main,
    color: (theme.vars || theme).palette.primary.contrastText,
    '&:hover': {
      backgroundColor: (theme.vars || theme).palette.primary.light
    }
  });
});
var ClockMeridiemText = styled(Typography, {
  name: 'MuiClock',
  slot: 'meridiemText',
  overridesResolver: function overridesResolver(_, styles) {
    return styles.meridiemText;
  }
})({
  overflow: 'hidden',
  whiteSpace: 'nowrap',
  textOverflow: 'ellipsis'
});

/**
 * @ignore - internal component.
 */
export function Clock(inProps) {
  var props = useThemeProps({
    props: inProps,
    name: 'MuiClock'
  });
  var ampm = props.ampm,
    ampmInClock = props.ampmInClock,
    autoFocus = props.autoFocus,
    children = props.children,
    value = props.value,
    handleMeridiemChange = props.handleMeridiemChange,
    isTimeDisabled = props.isTimeDisabled,
    meridiemMode = props.meridiemMode,
    _props$minutesStep = props.minutesStep,
    minutesStep = _props$minutesStep === void 0 ? 1 : _props$minutesStep,
    onChange = props.onChange,
    selectedId = props.selectedId,
    type = props.type,
    viewValue = props.viewValue,
    disabled = props.disabled,
    readOnly = props.readOnly,
    className = props.className;
  var ownerState = props;
  var utils = useUtils();
  var localeText = useLocaleText();
  var isMoving = React.useRef(false);
  var classes = useUtilityClasses(ownerState);
  var isSelectedTimeDisabled = isTimeDisabled(viewValue, type);
  var isPointerInner = !ampm && type === 'hours' && (viewValue < 1 || viewValue > 12);
  var handleValueChange = function handleValueChange(newValue, isFinish) {
    if (disabled || readOnly) {
      return;
    }
    if (isTimeDisabled(newValue, type)) {
      return;
    }
    onChange(newValue, isFinish);
  };
  var setTime = function setTime(event, isFinish) {
    var _ref6 = event,
      offsetX = _ref6.offsetX,
      offsetY = _ref6.offsetY;
    if (offsetX === undefined) {
      var rect = event.target.getBoundingClientRect();
      offsetX = event.changedTouches[0].clientX - rect.left;
      offsetY = event.changedTouches[0].clientY - rect.top;
    }
    var newSelectedValue = type === 'seconds' || type === 'minutes' ? getMinutes(offsetX, offsetY, minutesStep) : getHours(offsetX, offsetY, Boolean(ampm));
    handleValueChange(newSelectedValue, isFinish);
  };
  var handleTouchMove = function handleTouchMove(event) {
    isMoving.current = true;
    setTime(event, 'shallow');
  };
  var handleTouchEnd = function handleTouchEnd(event) {
    if (isMoving.current) {
      setTime(event, 'finish');
      isMoving.current = false;
    }
  };
  var handleMouseMove = function handleMouseMove(event) {
    // event.buttons & PRIMARY_MOUSE_BUTTON
    if (event.buttons > 0) {
      setTime(event.nativeEvent, 'shallow');
    }
  };
  var handleMouseUp = function handleMouseUp(event) {
    if (isMoving.current) {
      isMoving.current = false;
    }
    setTime(event.nativeEvent, 'finish');
  };
  var hasSelected = React.useMemo(function () {
    if (type === 'hours') {
      return true;
    }
    return viewValue % 5 === 0;
  }, [type, viewValue]);
  var keyboardControlStep = type === 'minutes' ? minutesStep : 1;
  var listboxRef = React.useRef(null);
  // Since this is rendered when a Popper is opened we can't use passive effects.
  // Focusing in passive effects in Popper causes scroll jump.
  useEnhancedEffect(function () {
    if (autoFocus) {
      // The ref not being resolved would be a bug in MUI.
      listboxRef.current.focus();
    }
  }, [autoFocus]);
  var handleKeyDown = function handleKeyDown(event) {
    // TODO: Why this early exit?
    if (isMoving.current) {
      return;
    }
    switch (event.key) {
      case 'Home':
        // annulate both hours and minutes
        handleValueChange(0, 'partial');
        event.preventDefault();
        break;
      case 'End':
        handleValueChange(type === 'minutes' ? 59 : 23, 'partial');
        event.preventDefault();
        break;
      case 'ArrowUp':
        handleValueChange(viewValue + keyboardControlStep, 'partial');
        event.preventDefault();
        break;
      case 'ArrowDown':
        handleValueChange(viewValue - keyboardControlStep, 'partial');
        event.preventDefault();
        break;
      default:
      // do nothing
    }
  };

  return /*#__PURE__*/_jsxs(ClockRoot, {
    className: clsx(className, classes.root),
    children: [/*#__PURE__*/_jsxs(ClockClock, {
      className: classes.clock,
      children: [/*#__PURE__*/_jsx(ClockSquareMask, {
        onTouchMove: handleTouchMove,
        onTouchEnd: handleTouchEnd,
        onMouseUp: handleMouseUp,
        onMouseMove: handleMouseMove,
        ownerState: {
          disabled: disabled
        },
        className: classes.squareMask
      }), !isSelectedTimeDisabled && /*#__PURE__*/_jsxs(React.Fragment, {
        children: [/*#__PURE__*/_jsx(ClockPin, {
          className: classes.pin
        }), value != null && /*#__PURE__*/_jsx(ClockPointer, {
          type: type,
          viewValue: viewValue,
          isInner: isPointerInner,
          hasSelected: hasSelected
        })]
      }), /*#__PURE__*/_jsx(ClockWrapper, {
        "aria-activedescendant": selectedId,
        "aria-label": localeText.clockLabelText(type, value, utils),
        ref: listboxRef,
        role: "listbox",
        onKeyDown: handleKeyDown,
        tabIndex: 0,
        className: classes.wrapper,
        children: children
      })]
    }), ampm && ampmInClock && /*#__PURE__*/_jsxs(React.Fragment, {
      children: [/*#__PURE__*/_jsx(ClockAmButton, {
        onClick: readOnly ? undefined : function () {
          return handleMeridiemChange('am');
        },
        disabled: disabled || meridiemMode === null,
        ownerState: ownerState,
        className: classes.amButton,
        title: formatMeridiem(utils, 'am'),
        children: /*#__PURE__*/_jsx(ClockMeridiemText, {
          variant: "caption",
          className: classes.meridiemText,
          children: formatMeridiem(utils, 'am')
        })
      }), /*#__PURE__*/_jsx(ClockPmButton, {
        disabled: disabled || meridiemMode === null,
        onClick: readOnly ? undefined : function () {
          return handleMeridiemChange('pm');
        },
        ownerState: ownerState,
        className: classes.pmButton,
        title: formatMeridiem(utils, 'pm'),
        children: /*#__PURE__*/_jsx(ClockMeridiemText, {
          variant: "caption",
          className: classes.meridiemText,
          children: formatMeridiem(utils, 'pm')
        })
      })]
    })]
  });
}