import React from 'react';
import '@testing-library/jest-dom/extend-expect';
import { fireEvent, render, waitFor } from '@testing-library/react';
import { IconHome, IconGrain } from '@defencedigital/icon-library';
import { Sidebar, SidebarNav, SidebarNavItem, SidebarUser, SidebarWrapper } from '.';
import { Link } from '../../Link';
import { Notification, Notifications } from '../NotificationPanel';
var user = /*#__PURE__*/React.createElement(SidebarUser, {
  initials: "HN",
  name: "Horatio Nelson"
});
var userWithLinks = /*#__PURE__*/React.createElement(SidebarUser, {
  initials: "HN",
  name: "Horatio Nelson",
  userLink: /*#__PURE__*/React.createElement(Link, {
    href: "/user-profile"
  }, "Profile"),
  exitLink: /*#__PURE__*/React.createElement(Link, {
    href: "/logout"
  }, "Logout")
});
var notifications = /*#__PURE__*/React.createElement(Notifications, {
  link: /*#__PURE__*/React.createElement(Link, {
    href: "notifications"
  })
}, /*#__PURE__*/React.createElement(Notification, {
  link: /*#__PURE__*/React.createElement(Link, {
    href: "notifications/1"
  }),
  name: "User 1",
  action: "added a new comment to your",
  on: "review",
  when: new Date('2019-11-05T14:25:02.178Z'),
  description: "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores"
}), /*#__PURE__*/React.createElement(Notification, {
  link: /*#__PURE__*/React.createElement(Link, {
    href: "notifications/2"
  }),
  name: "User 2",
  action: "added a new comment to your",
  on: "review",
  when: new Date('2019-11-01T14:25:02.178Z'),
  description: "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores"
}));
describe('Sidebar', function () {
  var wrapper;
  describe('when `initialIsOpen` is set', function () {
    beforeEach(function () {
      wrapper = render( /*#__PURE__*/React.createElement(SidebarWrapper, null, /*#__PURE__*/React.createElement(Sidebar, {
        initialIsOpen: true,
        icon: /*#__PURE__*/React.createElement(IconGrain, null),
        title: "Application Name"
      }, /*#__PURE__*/React.createElement(SidebarNav, null, /*#__PURE__*/React.createElement(SidebarNavItem, {
        icon: /*#__PURE__*/React.createElement(IconHome, null),
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/dashboard"
        }, "Dashboard")
      }), /*#__PURE__*/React.createElement(SidebarNavItem, {
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/reports"
        }, "Reports")
      }))), /*#__PURE__*/React.createElement("main", null, "Hello, World!")));
      fireEvent.mouseEnter(wrapper.getAllByTestId('sidebar-nav-item')[0]);
    });
    it('should display the text titles for navigation items', function () {
      expect(wrapper.queryByText('Dashboard')).toBeInTheDocument();
    });
  });
  describe('when rendered in React strict mode', function () {
    it('should not throw deprecation warning about findDOMNode', function () {
      expect(function () {
        wrapper = render( /*#__PURE__*/React.createElement(React.StrictMode, null, /*#__PURE__*/React.createElement(Sidebar, null)));
        fireEvent.mouseOver(wrapper.getByTestId('sidebar'));
      }).not.toThrow(/findDOMNode is deprecated in StrictMode/);
    });
  });
  describe('when composed with minimal props', function () {
    beforeEach(function () {
      wrapper = render( /*#__PURE__*/React.createElement(Sidebar, null));
    });
    it('does not render the header', function () {
      expect(wrapper.queryByTestId('sidebar-head')).not.toBeInTheDocument();
    });
  });
  describe('when composed with single level of navigaton and header items', function () {
    beforeEach(function () {
      wrapper = render( /*#__PURE__*/React.createElement(SidebarWrapper, null, /*#__PURE__*/React.createElement(Sidebar, {
        icon: /*#__PURE__*/React.createElement(IconGrain, null),
        title: "Application Name"
      }, /*#__PURE__*/React.createElement(SidebarNav, null, /*#__PURE__*/React.createElement(SidebarNavItem, {
        icon: /*#__PURE__*/React.createElement(IconHome, null),
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/dashboard"
        }, "Dashboard")
      }), /*#__PURE__*/React.createElement(SidebarNavItem, {
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/reports"
        }, "Reports")
      }))), /*#__PURE__*/React.createElement("main", null, "Hello, World!")));
    });
    describe('and sidebar is collapsed', function () {
      it('should not render any user information', function () {
        expect(wrapper.queryByTestId('sidebar-user-open')).not.toBeInTheDocument();
        expect(wrapper.queryByTestId('sidebar-user-closed')).not.toBeInTheDocument();
        expect(wrapper.queryByTestId('sidebar-user-closed-children')).not.toBeInTheDocument();
      });
      it('should not display the sidebar handle', function () {
        expect(wrapper.queryByTestId('sidebar-handle')).not.toBeInTheDocument();
      });
      it('should apply the correct `aria-label` attribute to the navigation links', function () {
        expect(wrapper.getAllByTestId('sidebar-nav-item')[0]).toHaveAttribute('aria-label', 'Dashboard');
      });
      it('should not render the application name', function () {
        expect(wrapper.queryByText('Application Name')).not.toBeInTheDocument();
      });
      it('should not display the text titles for navigation items', function () {
        expect(wrapper.queryByText('Dashboard')).not.toBeInTheDocument();
      });
      describe('and we hover over a top level nav item', function () {
        beforeEach(function () {
          fireEvent.mouseEnter(wrapper.getAllByTestId('sidebar-nav-item')[0]);
        });
        it('should display the sidebar handle', function () {
          expect(wrapper.queryByTestId('sidebar-handle')).toBeInTheDocument();
        });
        it('should apply the correct `aria-label` value to the handle', function () {
          expect(wrapper.getByTestId('sidebar-handle')).toHaveAttribute('aria-label', 'Expand sidebar');
        });
        it('should display a tooltip on hover', function () {
          expect(wrapper.queryAllByTestId('tooltip')).toHaveLength(1);
        });
        describe('and we move the mouse away', function () {
          beforeEach(function () {
            fireEvent.mouseLeave(wrapper.getAllByTestId('sidebar-nav-item')[0]);
          });
          it('should display a tooltip on hover', function () {
            expect(wrapper.queryAllByTestId('tooltip')).toHaveLength(0);
          });
        });
      });
    });
    describe('and sidebar is expanded', function () {
      beforeEach(function () {
        fireEvent.mouseEnter(wrapper.getAllByTestId('sidebar-nav-item')[0]);
        wrapper.getByTestId('sidebar-handle').click();
      });
      it('should apply the correct `aria-label` value to the handle', function () {
        expect(wrapper.getByTestId('sidebar-handle')).toHaveAttribute('aria-label', 'Collapse sidebar');
      });
      it('should render the application name', function () {
        expect(wrapper.queryByText('Application Name')).toBeInTheDocument();
      });
      it('should display the text titles for navigation items', function () {
        expect(wrapper.queryByText('Dashboard')).toBeInTheDocument();
      });
      it('should not disply a tooltip on hover', function () {
        expect(wrapper.queryAllByTestId('tooltip')).toHaveLength(0);
      });
      describe('and we hover over a top level nav item', function () {
        beforeEach(function () {
          fireEvent.mouseEnter(wrapper.getAllByTestId('sidebar-nav-item')[0]);
        });
        it('should not display a tooltip on hover', function () {
          expect(wrapper.queryAllByTestId('tooltip')).toHaveLength(0);
        });
      });
    });
  });
  describe('when composed with a user with user or exit links', function () {
    beforeEach(function () {
      wrapper = render( /*#__PURE__*/React.createElement(SidebarWrapper, null, /*#__PURE__*/React.createElement(Sidebar, {
        icon: /*#__PURE__*/React.createElement(IconGrain, null),
        title: "Application Name",
        user: user
      }, /*#__PURE__*/React.createElement(SidebarNav, null, /*#__PURE__*/React.createElement(SidebarNavItem, {
        icon: /*#__PURE__*/React.createElement(IconHome, null),
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/dashboard"
        }, "Dashboard")
      }), /*#__PURE__*/React.createElement(SidebarNavItem, {
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/reports"
        }, "Reports")
      }))), /*#__PURE__*/React.createElement("main", null, "Hello, World!")));
    });
    describe('and the sidebar is collapsed', function () {
      it('should render the correct user information', function () {
        expect(wrapper.queryByTestId('sidebar-user-closed')).not.toBeInTheDocument();
        expect(wrapper.queryByTestId('sidebar-user-open')).not.toBeInTheDocument();
        expect(wrapper.queryByTestId('sidebar-user-closed-children')).toBeInTheDocument();
      });
    });
    describe('and the sidebar is expanded', function () {
      beforeEach(function () {
        fireEvent.mouseEnter(wrapper.getAllByTestId('sidebar-nav-item')[0]);
        wrapper.getByTestId('sidebar-handle').click();
      });
      it('should not render the exit link', function () {
        expect(wrapper.queryByTestId('sidebar-exit-link')).not.toBeInTheDocument();
      });
      it('should not render the user profile link', function () {
        expect(wrapper.queryByTestId('sidebar-user-link')).not.toBeInTheDocument();
      });
    });
  });
  describe('when composed with a user menu, user link and exit link', function () {
    beforeEach(function () {
      wrapper = render( /*#__PURE__*/React.createElement(SidebarWrapper, null, /*#__PURE__*/React.createElement(Sidebar, {
        icon: /*#__PURE__*/React.createElement(IconGrain, null),
        title: "Application Name",
        user: userWithLinks
      }, /*#__PURE__*/React.createElement(SidebarNav, null, /*#__PURE__*/React.createElement(SidebarNavItem, {
        icon: /*#__PURE__*/React.createElement(IconHome, null),
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/dashboard"
        }, "Dashboard")
      }), /*#__PURE__*/React.createElement(SidebarNavItem, {
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/reports"
        }, "Reports")
      }))), /*#__PURE__*/React.createElement("main", null, "Hello, World!")));
    });
    describe('and sidebar is collapsed', function () {
      it('should render the correct user information', function () {
        expect(wrapper.queryByTestId('sidebar-user-closed-children')).toBeInTheDocument();
        expect(wrapper.queryByTestId('sidebar-user-closed')).not.toBeInTheDocument();
        expect(wrapper.queryByTestId('sidebar-user-open')).not.toBeInTheDocument();
      });
      describe('and the avatar is clicked', function () {
        beforeEach(function () {
          wrapper.getByText('HN').click();
        });
        it('should show the links', function () {
          expect(wrapper.getByText('Profile')).toBeInTheDocument();
          expect(wrapper.getByText('Logout')).toBeInTheDocument();
        });
        describe('and the avatar is clicked again', function () {
          beforeEach(function () {
            wrapper.getByText('HN').click();
          });
          it('should not show the links', function () {
            return waitFor(function () {
              expect(wrapper.queryByText('Profile')).not.toBeVisible();
              expect(wrapper.queryByText('Logout')).not.toBeVisible();
            });
          });
          describe('and the elsewhere in the document is clicked', function () {
            beforeEach(function () {
              fireEvent(document, new MouseEvent('mousedown', {
                bubbles: true,
                cancelable: true
              }));
            });
            it('should not show the links', function () {
              return waitFor(function () {
                expect(wrapper.queryByText('Profile')).not.toBeVisible();
                expect(wrapper.queryByText('Logout')).not.toBeVisible();
              });
            });
          });
        });
      });
    });
    describe('and the sidebar is expanded', function () {
      beforeEach(function () {
        fireEvent.mouseEnter(wrapper.getAllByTestId('sidebar-nav-item')[0]);
        wrapper.getByTestId('sidebar-handle').click();
      });
      it('should render the correct user information', function () {
        expect(wrapper.queryByTestId('sidebar-user-open')).toBeInTheDocument();
        expect(wrapper.queryByTestId('sidebar-user-closed')).not.toBeInTheDocument();
        expect(wrapper.queryByTestId('sidebar-user-closed-children')).not.toBeInTheDocument();
      });
      it('should render the exit link', function () {
        expect(wrapper.queryByTestId('sidebar-exit-link')).toBeInTheDocument();
      });
    });
  });
  describe('when composed with notifications and the `hasUnreadNotification` prop is not set', function () {
    beforeEach(function () {
      wrapper = render( /*#__PURE__*/React.createElement(SidebarWrapper, null, /*#__PURE__*/React.createElement(Sidebar, {
        icon: /*#__PURE__*/React.createElement(IconGrain, null),
        title: "Application Name",
        notifications: notifications
      }, /*#__PURE__*/React.createElement(SidebarNav, null, /*#__PURE__*/React.createElement(SidebarNavItem, {
        icon: /*#__PURE__*/React.createElement(IconHome, null),
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/dashboard"
        }, "Dashboard")
      }), /*#__PURE__*/React.createElement(SidebarNavItem, {
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/reports"
        }, "Reports")
      }))), /*#__PURE__*/React.createElement("main", null, "Hello, World!")));
    });
    it('does not display the indicator dot', function () {
      expect(wrapper.queryByTestId('not-read')).not.toBeInTheDocument();
    });
  });
  describe('when composed with notifications and the `hasUnreadNotification prop is set`', function () {
    beforeEach(function () {
      wrapper = render( /*#__PURE__*/React.createElement(SidebarWrapper, null, /*#__PURE__*/React.createElement(Sidebar, {
        icon: /*#__PURE__*/React.createElement(IconGrain, null),
        title: "Application Name",
        notifications: notifications,
        hasUnreadNotification: true
      }, /*#__PURE__*/React.createElement(SidebarNav, null, /*#__PURE__*/React.createElement(SidebarNavItem, {
        icon: /*#__PURE__*/React.createElement(IconHome, null),
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/dashboard"
        }, "Dashboard")
      }), /*#__PURE__*/React.createElement(SidebarNavItem, {
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/reports"
        }, "Reports")
      }))), /*#__PURE__*/React.createElement("main", null, "Hello, World!")));
    });
    describe('and sidebar is collapsed', function () {
      it('does not display the button title', function () {
        expect(wrapper.queryByText('Notifications')).not.toBeInTheDocument();
      });
      it('displays the correct number of unread notifications', function () {
        expect(wrapper.getByTestId('not-read')).toHaveTextContent('2');
      });
      describe('and the notification button is clicked', function () {
        beforeEach(function () {
          wrapper.getByTestId('notification-button').click();
        });
        it('shows the notifications', function () {
          expect(wrapper.getByText('User 1')).toBeInTheDocument();
          expect(wrapper.getByText('User 2')).toBeInTheDocument();
        });
        describe('and the notification button is clicked again', function () {
          beforeEach(function () {
            wrapper.getByTestId('notification-button').click();
          });
          it('should not show the notifications', function () {
            return waitFor(function () {
              expect(wrapper.queryByText('User 1')).not.toBeVisible();
              expect(wrapper.queryByText('User 2')).not.toBeVisible();
            });
          });
          describe('and then elsewhere in the document is clicked', function () {
            beforeEach(function () {
              fireEvent(document, new MouseEvent('mousedown', {
                bubbles: true,
                cancelable: true
              }));
            });
            it('should not show the notifications', function () {
              return waitFor(function () {
                expect(wrapper.queryByText('User 1')).not.toBeVisible();
                expect(wrapper.queryByText('User 2')).not.toBeVisible();
              });
            });
          });
        });
      });
    });
    describe('and sidebar is expanded', function () {
      beforeEach(function () {
        fireEvent.mouseEnter(wrapper.getAllByTestId('sidebar-nav-item')[0]);
        wrapper.getByTestId('sidebar-handle').click();
      });
      it('does display the button title', function () {
        expect(wrapper.queryByText('Notifications')).toBeInTheDocument();
      });
      it('displays the correct number of unread notifications', function () {
        expect(wrapper.getByTestId('not-read')).toHaveTextContent('2');
      });
    });
  });
  describe('when composed with nested navigation', function () {
    beforeEach(function () {
      wrapper = render( /*#__PURE__*/React.createElement(SidebarWrapper, null, /*#__PURE__*/React.createElement(Sidebar, {
        icon: /*#__PURE__*/React.createElement(IconGrain, null),
        title: "Application Name",
        notifications: notifications,
        hasUnreadNotification: true
      }, /*#__PURE__*/React.createElement(SidebarNav, null, /*#__PURE__*/React.createElement(SidebarNavItem, {
        icon: /*#__PURE__*/React.createElement(IconHome, null),
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/dashboard"
        }, "Dashboard")
      }, /*#__PURE__*/React.createElement(SidebarNavItem, {
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/sub-nav-item-1"
        }, "Sub-nav-item 1")
      }), /*#__PURE__*/React.createElement(SidebarNavItem, {
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/sub-nav-item-2"
        }, "Sub-nav-item 2")
      })), /*#__PURE__*/React.createElement(SidebarNavItem, {
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/reports"
        }, "Reports")
      }))), /*#__PURE__*/React.createElement("main", null, "Hello, World!")));
    });
    describe('and the sidebar is collapsed', function () {
      it('does not render the sub nav', function () {
        expect(wrapper.queryAllByTestId('sidebar-sub-nav')).toHaveLength(0);
      });
    });
    describe('and the sidebar is expanded', function () {
      beforeEach(function () {
        fireEvent.mouseEnter(wrapper.getAllByTestId('sidebar-nav-item')[0]);
        wrapper.getByTestId('sidebar-handle').click();
      });
      it('renders the expand button for the correct top-level menu item', function () {
        expect(wrapper.getByTestId('sub-menu-expand-button')).toBeInTheDocument();
      });
      describe('and the expand button is clicked', function () {
        beforeEach(function () {
          wrapper.getByTestId('sub-menu-expand-button').click();
        });
        it('renders the sub nav', function () {
          expect(wrapper.getByText('Sub-nav-item 1')).toBeInTheDocument();
          expect(wrapper.getByText('Sub-nav-item 2')).toBeInTheDocument();
        });
        describe('and the expand button is clicked again', function () {
          beforeEach(function () {
            wrapper.getByTestId('sub-menu-expand-button').click();
          });
          it('should not show the sub nav', function () {
            return waitFor(function () {
              expect(wrapper.queryByText('Sub-nav-item 1')).not.toBeVisible();
              expect(wrapper.queryByText('Sub-nav-item 2')).not.toBeVisible();
            });
          });
          describe('and then elsewhere in the document is clicked', function () {
            beforeEach(function () {
              fireEvent(document, new MouseEvent('mousedown', {
                bubbles: true,
                cancelable: true
              }));
            });
            it('should not show the sub nav', function () {
              return waitFor(function () {
                expect(wrapper.queryByText('Sub-nav-item 1')).not.toBeVisible();
                expect(wrapper.queryByText('Sub-nav-item 2')).not.toBeVisible();
              });
            });
          });
        });
      });
    });
  });
  describe('when composed with arbitrary props', function () {
    beforeEach(function () {
      wrapper = render( /*#__PURE__*/React.createElement(SidebarWrapper, {
        "data-arbitrary": "arbitrary-wrapper"
      }, /*#__PURE__*/React.createElement(Sidebar, {
        "data-arbitrary": "arbitrary-sidebar",
        notifications: notifications
      }, /*#__PURE__*/React.createElement(SidebarNav, {
        "data-arbitrary": "arbitrary-nav"
      }, /*#__PURE__*/React.createElement(SidebarNavItem, {
        "data-arbitrary": "arbitrary-nav-item",
        icon: /*#__PURE__*/React.createElement(IconHome, null),
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/dashboard"
        }, "Dashboard")
      }, /*#__PURE__*/React.createElement(SidebarNavItem, {
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/sub-nav-item-1"
        }, "Sub-nav-item 1")
      }), /*#__PURE__*/React.createElement(SidebarNavItem, {
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/sub-nav-item-2"
        }, "Sub-nav-item 2")
      })), /*#__PURE__*/React.createElement(SidebarNavItem, {
        link: /*#__PURE__*/React.createElement(Link, {
          href: "/reports"
        }, "Reports")
      }))), /*#__PURE__*/React.createElement("main", null, "Hello, World!")));
    });
    it('should spread arbitrary props on the sidebar wrapper', function () {
      expect(wrapper.getByTestId('sidebar-wrapper')).toHaveAttribute('data-arbitrary', 'arbitrary-wrapper');
    });
    it('should spread arbitrary props on the sidebar', function () {
      expect(wrapper.getByTestId('sidebar')).toHaveAttribute('data-arbitrary', 'arbitrary-sidebar');
    });
    it('should spread arbitrary props on the sidebar nav', function () {
      expect(wrapper.getByTestId('sidebar-nav')).toHaveAttribute('data-arbitrary', 'arbitrary-nav');
    });
    it('should spread arbitrary props on the sidebar nav item', function () {
      expect(wrapper.getAllByTestId('sidebar-nav-item')[0]).toHaveAttribute('data-arbitrary', 'arbitrary-nav-item');
    });
  });
});