import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
var _excluded = ["componentFamily", "render", "renderWithProps", "values", "setNewValue"];
import * as React from 'react';
import { expect } from 'chai';
import { spy } from 'sinon';
import { screen, userEvent } from '@mui/monorepo/test/utils';
import { getExpectedOnChangeCount, getTextbox, openPicker } from 'test/utils/pickers';
import { jsx as _jsx } from "react/jsx-runtime";
export var testPickerOpenCloseLifeCycle = function testPickerOpenCloseLifeCycle(ElementToTest, options) {
  var componentFamily = options.componentFamily,
    render = options.render,
    renderWithProps = options.renderWithProps,
    values = options.values,
    setNewValue = options.setNewValue,
    pickerParams = _objectWithoutProperties(options, _excluded);
  if (componentFamily !== 'picker') {
    return;
  }
  var viewWrapperRole = pickerParams.type === 'date-range' && pickerParams.variant === 'desktop' ? 'tooltip' : 'dialog';
  describe('Picker open / close lifecycle', function () {
    it('should not open on mount if `props.open` is false', function () {
      render( /*#__PURE__*/_jsx(ElementToTest, {}));
      expect(screen.queryByRole(viewWrapperRole)).to.equal(null);
    });
    it('should open on mount if `prop.open` is true', function () {
      render( /*#__PURE__*/_jsx(ElementToTest, {
        open: true
      }));
      expect(screen.queryByRole(viewWrapperRole)).toBeVisible();
    });
    it('should not open when `prop.disabled` is true ', function () {
      var onOpen = spy();
      render( /*#__PURE__*/_jsx(ElementToTest, {
        disabled: true,
        onOpen: onOpen
      }));
      openPicker(pickerParams);
      expect(onOpen.callCount).to.equal(0);
    });
    it('should not open when `prop.readOnly` is true ', function () {
      var onOpen = spy();
      render( /*#__PURE__*/_jsx(ElementToTest, {
        readOnly: true,
        onOpen: onOpen
      }));
      openPicker(pickerParams);
      expect(onOpen.callCount).to.equal(0);
    });
    it('should call onChange, onClose (if desktop) and onAccept (if desktop) when selecting a value', function () {
      var onChange = spy();
      var onAccept = spy();
      var onClose = spy();
      var _renderWithProps = renderWithProps({
          onChange: onChange,
          onAccept: onAccept,
          onClose: onClose,
          defaultValue: values[0],
          open: true
        }),
        selectSection = _renderWithProps.selectSection;
      expect(onChange.callCount).to.equal(0);
      expect(onAccept.callCount).to.equal(0);
      expect(onClose.callCount).to.equal(0);

      // Change the value
      var newValue = setNewValue(values[0], {
        isOpened: true,
        selectSection: selectSection
      });
      expect(onChange.callCount).to.equal(getExpectedOnChangeCount(componentFamily, pickerParams));
      if (pickerParams.type === 'date-range') {
        newValue = setNewValue(newValue, {
          isOpened: true,
          setEndDate: true,
          selectSection: selectSection
        });
        newValue.forEach(function (value, index) {
          expect(onChange.lastCall.args[0][index]).toEqualDateTime(value);
        });
      } else {
        expect(onChange.lastCall.args[0]).toEqualDateTime(newValue);
      }
      expect(onAccept.callCount).to.equal(pickerParams.variant === 'mobile' ? 0 : 1);
      expect(onClose.callCount).to.equal(pickerParams.variant === 'mobile' ? 0 : 1);
    });
    it('should not select input content after closing on mobile', function () {
      if (pickerParams.variant !== 'mobile') {
        return;
      }
      var _renderWithProps2 = renderWithProps({
          defaultValue: values[0]
        }),
        selectSection = _renderWithProps2.selectSection;

      // Change the value
      setNewValue(values[0], {
        selectSection: selectSection
      });
      var textbox;
      if (pickerParams.type === 'date-range') {
        textbox = screen.getAllByRole('textbox')[0];
      } else {
        textbox = getTextbox();
      }
      expect(textbox.scrollLeft).to.be.equal(0);
    });
    it('should call onChange, onClose and onAccept when selecting a value and `props.closeOnSelect` is true', function () {
      var onChange = spy();
      var onAccept = spy();
      var onClose = spy();
      var _renderWithProps3 = renderWithProps({
          onChange: onChange,
          onAccept: onAccept,
          onClose: onClose,
          defaultValue: values[0],
          open: true,
          closeOnSelect: true
        }),
        selectSection = _renderWithProps3.selectSection;
      expect(onChange.callCount).to.equal(0);
      expect(onAccept.callCount).to.equal(0);
      expect(onClose.callCount).to.equal(0);

      // Change the value
      var newValue = setNewValue(values[0], {
        isOpened: true,
        selectSection: selectSection
      });
      expect(onChange.callCount).to.equal(getExpectedOnChangeCount(componentFamily, pickerParams));
      if (pickerParams.type === 'date-range') {
        newValue = setNewValue(newValue, {
          isOpened: true,
          setEndDate: true,
          selectSection: selectSection
        });
        newValue.forEach(function (value, index) {
          expect(onChange.lastCall.args[0][index]).toEqualDateTime(value);
        });
      } else {
        expect(onChange.lastCall.args[0]).toEqualDateTime(newValue);
      }
      expect(onAccept.callCount).to.equal(1);
      expect(onClose.callCount).to.equal(1);
    });
    it('should not call onChange or onAccept when selecting the same value', function () {
      var onChange = spy();
      var onAccept = spy();
      var onClose = spy();
      var _renderWithProps4 = renderWithProps({
          onChange: onChange,
          onAccept: onAccept,
          onClose: onClose,
          open: true,
          value: values[0],
          closeOnSelect: true
        }),
        selectSection = _renderWithProps4.selectSection;

      // Change the value (same value)
      setNewValue(values[0], {
        isOpened: true,
        applySameValue: true,
        selectSection: selectSection
      });
      if (pickerParams.type === 'date-range') {
        setNewValue(values[0], {
          isOpened: true,
          applySameValue: true,
          setEndDate: true,
          selectSection: selectSection
        });
      }
      expect(onChange.callCount).to.equal(0);
      expect(onAccept.callCount).to.equal(0);
      expect(onClose.callCount).to.equal(1);
    });
    it('should not call onClose or onAccept when selecting a date and `props.closeOnSelect` is false', function () {
      var onChange = spy();
      var onAccept = spy();
      var onClose = spy();
      var _renderWithProps5 = renderWithProps({
          onChange: onChange,
          onAccept: onAccept,
          onClose: onClose,
          defaultValue: values[0],
          open: true,
          closeOnSelect: false
        }),
        selectSection = _renderWithProps5.selectSection;

      // Change the value
      var newValue = setNewValue(values[0], {
        isOpened: true,
        selectSection: selectSection
      });
      var initialChangeCount = getExpectedOnChangeCount(componentFamily, pickerParams);
      expect(onChange.callCount).to.equal(initialChangeCount);
      if (pickerParams.type === 'date-range') {
        newValue = setNewValue(newValue, {
          isOpened: true,
          setEndDate: true,
          selectSection: selectSection
        });
        newValue.forEach(function (value, index) {
          expect(onChange.lastCall.args[0][index]).toEqualDateTime(value);
        });
      } else {
        expect(onChange.lastCall.args[0]).toEqualDateTime(newValue);
      }
      expect(onAccept.callCount).to.equal(0);
      expect(onClose.callCount).to.equal(0);

      // Change the value
      var newValueBis = setNewValue(newValue, {
        isOpened: true,
        selectSection: selectSection
      });
      if (pickerParams.type === 'date-range') {
        expect(onChange.callCount).to.equal(3);
        newValueBis = setNewValue(newValueBis, {
          isOpened: true,
          setEndDate: true,
          selectSection: selectSection
        });
        newValueBis.forEach(function (value, index) {
          expect(onChange.lastCall.args[0][index]).toEqualDateTime(value);
        });
      } else {
        expect(onChange.callCount).to.equal(initialChangeCount + getExpectedOnChangeCount(componentFamily, pickerParams) - (
        // meridiem does not change this time in case of multi section digital clock
        pickerParams.type === 'time' || pickerParams.type === 'date-time' ? 1 : 0));
        expect(onChange.lastCall.args[0]).toEqualDateTime(newValueBis);
      }
      expect(onAccept.callCount).to.equal(0);
      expect(onClose.callCount).to.equal(0);
    });
    it('should call onClose and onAccept with the live value when pressing Escape', function () {
      var onChange = spy();
      var onAccept = spy();
      var onClose = spy();
      var _renderWithProps6 = renderWithProps({
          onChange: onChange,
          onAccept: onAccept,
          onClose: onClose,
          defaultValue: values[0],
          open: true,
          closeOnSelect: false
        }),
        selectSection = _renderWithProps6.selectSection;

      // Change the value (already tested)
      var newValue = setNewValue(values[0], {
        isOpened: true,
        selectSection: selectSection
      });

      // Dismiss the picker
      userEvent.keyPress(document.activeElement, {
        key: 'Escape'
      });
      expect(onChange.callCount).to.equal(getExpectedOnChangeCount(componentFamily, pickerParams));
      expect(onAccept.callCount).to.equal(1);
      if (pickerParams.type === 'date-range') {
        newValue.forEach(function (value, index) {
          expect(onChange.lastCall.args[0][index]).toEqualDateTime(value);
        });
      } else {
        expect(onChange.lastCall.args[0]).toEqualDateTime(newValue);
      }
      expect(onClose.callCount).to.equal(1);
    });
    it('should call onClose when clicking outside of the picker without prior change', function test() {
      // TODO: Fix this test and enable it on mobile and date-range
      if (pickerParams.variant === 'mobile' || pickerParams.type === 'date-range') {
        this.skip();
      }
      var onChange = spy();
      var onAccept = spy();
      var onClose = spy();
      render( /*#__PURE__*/_jsx(ElementToTest, {
        onChange: onChange,
        onAccept: onAccept,
        onClose: onClose,
        value: values[0],
        open: true,
        closeOnSelect: false
      }));

      // Dismiss the picker
      userEvent.mousePress(document.body);
      expect(onChange.callCount).to.equal(0);
      expect(onAccept.callCount).to.equal(0);
      expect(onClose.callCount).to.equal(1);
    });
    it('should call onClose and onAccept with the live value when clicking outside of the picker', function test() {
      // TODO: Fix this test and enable it on mobile and date-range
      if (pickerParams.variant === 'mobile' || pickerParams.type === 'date-range') {
        this.skip();
      }
      var onChange = spy();
      var onAccept = spy();
      var onClose = spy();
      var _renderWithProps7 = renderWithProps({
          onChange: onChange,
          onAccept: onAccept,
          onClose: onClose,
          defaultValue: values[0],
          open: true,
          closeOnSelect: false
        }),
        selectSection = _renderWithProps7.selectSection;

      // Change the value (already tested)
      var newValue = setNewValue(values[0], {
        isOpened: true,
        selectSection: selectSection
      });

      // Dismiss the picker
      userEvent.mousePress(document.body);
      expect(onChange.callCount).to.equal(getExpectedOnChangeCount(componentFamily, pickerParams));
      expect(onAccept.callCount).to.equal(1);
      expect(onAccept.lastCall.args[0]).toEqualDateTime(newValue);
      expect(onClose.callCount).to.equal(1);
    });
    it('should not call onClose or onAccept when clicking outside of the picker if not opened', function () {
      var onChange = spy();
      var onAccept = spy();
      var onClose = spy();
      render( /*#__PURE__*/_jsx(ElementToTest, {
        onChange: onChange,
        onAccept: onAccept,
        onClose: onClose,
        closeOnSelect: false
      }));

      // Dismiss the picker
      userEvent.mousePress(document.body);
      expect(onChange.callCount).to.equal(0);
      expect(onAccept.callCount).to.equal(0);
      expect(onClose.callCount).to.equal(0);
    });
    it('should not call onClose or onAccept when pressing escape when picker is not opened', function () {
      var onChange = spy();
      var onAccept = spy();
      var onClose = spy();
      render( /*#__PURE__*/_jsx(ElementToTest, {
        onChange: onChange,
        onAccept: onAccept,
        onClose: onClose
      }));

      // Dismiss the picker
      userEvent.keyPress(document.body, {
        key: 'Escape'
      });
      expect(onChange.callCount).to.equal(0);
      expect(onAccept.callCount).to.equal(0);
      expect(onClose.callCount).to.equal(0);
    });
  });
};