import React from 'react';
import '@testing-library/jest-dom/extend-expect';
import { renderToStaticMarkup } from 'react-dom/server';
import { fireEvent, render, waitFor } from '@testing-library/react';
import { Popover } from '.';
var HOVER_ON_ME = 'Hover on me!';
var CONTENT_TEXT = 'This is some arbitrary JSX';
jest.useFakeTimers();
describe('Popover', function () {
  var content = /*#__PURE__*/React.createElement("pre", null, CONTENT_TEXT);
  var clickSpy;
  var wrapper;
  beforeEach(function () {
    jest.spyOn(global, 'setTimeout');
  });
  describe('when provided with arbitrary JSX content', function () {
    beforeEach(function () {
      clickSpy = jest.fn();
      wrapper = render( /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Popover, {
        content: content,
        "aria-label": "Hello, World!"
      }, /*#__PURE__*/React.createElement("div", null, HOVER_ON_ME)), /*#__PURE__*/React.createElement("button", {
        onClick: clickSpy
      }, "Click me!")));
    });
    it('allows button covered by Popover to be clicked when Popover is hidden', function () {
      wrapper.getByText('Click me!').click();
      expect(clickSpy).toHaveBeenCalledTimes(1);
    });
    describe('and the user hovers on the target element', function () {
      beforeEach(function () {
        fireEvent.mouseEnter(wrapper.getByText(HOVER_ON_ME));
      });
      afterEach(function () {
        jest.clearAllTimers();
      });
      it('should set the `aria-label` attribute to the supplied value', function () {
        expect(wrapper.getByTestId('popover')).toHaveAttribute('aria-label', 'Hello, World!');
      });
      it('should set the `aria-describedby` attribute to the ID of the content', function () {
        var contentId = wrapper.getByTestId('floating-box-content').getAttribute('id');
        expect(wrapper.getByTestId('popover')).toHaveAttribute('aria-describedby', contentId);
      });
      it('to be visible to the end user', function () {
        return waitFor(function () {
          expect(wrapper.getByTestId('floating-box-content')).toBeVisible();
        });
      });
      it('renders the provided arbitrary JSX', function () {
        expect(wrapper.getByTestId('floating-box-content').innerHTML).toContain(renderToStaticMarkup(content));
      });
      describe('and the user unhovers from the target element', function () {
        beforeEach(function () {
          fireEvent.mouseOut(wrapper.getByText(HOVER_ON_ME));
        });
        it('hid the `Popover` after 1000ms', function () {
          expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), 1000);
        });
        it('to not be visible to the end user', function () {
          return waitFor(function () {
            expect(wrapper.queryByText(CONTENT_TEXT)).not.toBeVisible();
          });
        });
      });
    });
  });
  describe('when the `Popover` uses the click mouse event', function () {
    beforeEach(function () {
      wrapper = render( /*#__PURE__*/React.createElement(Popover, {
        content: /*#__PURE__*/React.createElement("pre", null, "This is some arbitrary JSX"),
        isClick: true
      }, /*#__PURE__*/React.createElement("div", null, "Click on me")));
    });
    describe('and the user clicks on the target', function () {
      beforeEach(function () {
        fireEvent(wrapper.getByText('Click on me'), new MouseEvent('click', {
          bubbles: true,
          cancelable: true
        }));
      });
      it('to be visible to the end user', function () {
        return waitFor(function () {
          expect(wrapper.getByTestId('floating-box-content')).toBeVisible();
        });
      });
      it('should set the `aria-label` attribute to the defualt value', function () {
        expect(wrapper.getByTestId('popover')).toHaveAttribute('aria-label', 'Popover');
      });
      describe('and the user clicks on the target again', function () {
        beforeEach(function () {
          fireEvent(wrapper.getByText('Click on me'), new MouseEvent('click', {
            bubbles: true,
            cancelable: true
          }));
        });
        it('to not be visible to the end user', function () {
          return waitFor(function () {
            expect(wrapper.queryByText(CONTENT_TEXT)).not.toBeVisible();
          });
        });
      });
      describe('and the user clicks elsewhere in the document', function () {
        beforeEach(function () {
          fireEvent(document, new MouseEvent('mousedown', {
            bubbles: true,
            cancelable: true
          }));
        });
        it('to not be visible to the end user', function () {
          return waitFor(function () {
            expect(wrapper.queryByText(CONTENT_TEXT)).not.toBeVisible();
          });
        });
      });
    });
  });
  describe('when using a custom `closeDelay`', function () {
    beforeEach(function () {
      wrapper = render( /*#__PURE__*/React.createElement(Popover, {
        content: content,
        closeDelay: 100
      }, /*#__PURE__*/React.createElement("div", null, HOVER_ON_ME)));
    });
    describe('and the user hovers on the target element', function () {
      beforeEach(function () {
        fireEvent.mouseEnter(wrapper.getByText(HOVER_ON_ME));
      });
      describe('and the user unhovers from the target element', function () {
        beforeEach(function () {
          fireEvent.mouseOut(wrapper.getByText(HOVER_ON_ME));
        });
        it('hid the `Popover` after 100ms', function () {
          expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), 100);
        });
      });
    });
  });
  describe('when passing arbitrary props', function () {
    beforeEach(function () {
      wrapper = render( /*#__PURE__*/React.createElement(Popover, {
        content: content,
        "data-arbitrary": "arbitrary"
      }, /*#__PURE__*/React.createElement("div", null, HOVER_ON_ME)));
    });
    describe('and the user hovers on the target element', function () {
      beforeEach(function () {
        fireEvent.mouseEnter(wrapper.getByText(HOVER_ON_ME));
      });
      it('should spread arbitrary props', function () {
        return waitFor(function () {
          expect(wrapper.getByTestId('popover')).toHaveAttribute('data-arbitrary', 'arbitrary');
        });
      });
    });
  });
  describe('when the popover content changes after being hovered', function () {
    var initialContentId;
    beforeEach(function () {
      wrapper = render( /*#__PURE__*/React.createElement(Popover, {
        content: /*#__PURE__*/React.createElement(React.Fragment, null, "initial content")
      }, /*#__PURE__*/React.createElement("div", null, HOVER_ON_ME)));
      fireEvent.mouseEnter(wrapper.getByText(HOVER_ON_ME));
      initialContentId = wrapper.getByTestId('floating-box-content').id;
      wrapper.rerender( /*#__PURE__*/React.createElement(Popover, {
        content: /*#__PURE__*/React.createElement(React.Fragment, null, "new content")
      }, /*#__PURE__*/React.createElement("div", null, HOVER_ON_ME)));
    });
    it('does not generate a new content `id`', function () {
      expect(wrapper.getByTestId('floating-box-content')).toHaveAttribute('id', initialContentId);
    });
  });
});