import React from 'react'
import { mount, shallow } from 'enzyme'
import NavbarMenu from './index'
import MenuItemComponent from './MenuItemComponent'
import MenuDropdownComponent from './MenuDropdownComponent'
import { WrapperMenuDropdown, MenuItem, MenuOption } from './Wrappers'

const noop = () => {}

describe('components/Menus/NavbarMenu', () => {
  let mountedNavbarMenu
  let menuItems

  describe('when navbar has menu items', () => {
    it('should display the menu items', () => {
      menuItems = [
        {
          label: 'Home',
          active: true,
          onClick: noop
        },
        {
          label: 'Technology',
          onClick: noop
        }
      ]

      mountedNavbarMenu = shallow(<NavbarMenu menuItems={menuItems} />)

      expect(mountedNavbarMenu.find(MenuItemComponent)).toHaveLength(2)
    })

    it('should display the label of the menu item', () => {
      menuItems = [
        {
          label: 'Home',
          active: true,
          onClick: noop
        }
      ]

      mountedNavbarMenu = mount(<NavbarMenu menuItems={menuItems} />)
      expect(mountedNavbarMenu.text()).toEqual('Home')
    })

    it('should display the label of the menu dropdown', () => {
      menuItems = [
        {
          label: 'Home',
          dropdownMenuElements: []
        }
      ]

      mountedNavbarMenu = mount(<NavbarMenu menuItems={menuItems} />)
      expect(mountedNavbarMenu.text()).toEqual('Home')
    })

    describe('when user clicks on a menu item', () => {
      let mockOnclick

      beforeEach(() => {
        mockOnclick = jest.fn()

        menuItems = [
          {
            label: 'Home',
            onClick: mockOnclick
          }
        ]
      })

      it('should fire the onClick prop from menuItems', () => {
        mountedNavbarMenu = shallow(<NavbarMenu menuItems={menuItems} />)
        mountedNavbarMenu.find(MenuItemComponent).simulate('click')

        expect(mockOnclick).toBeCalled()
      })

      it('should display menu item as active', () => {
        mountedNavbarMenu = shallow(<NavbarMenu menuItems={menuItems} />)
        mountedNavbarMenu.find(MenuItemComponent).simulate('click')

        expect(mountedNavbarMenu.instance().state.activeStatus).toEqual([true])
      })
    })

    describe('when user clicks on a dropdown menu item', () => {
      it('should open a dropdown list of menu options', () => {
        menuItems = [
          {
            label: 'Home',
            dropdownMenuElements: [
              {
                label: 'Option 1',
                onClick: noop
              }
            ]
          }
        ]

        mountedNavbarMenu = mount(<NavbarMenu menuItems={menuItems} />)
        mountedNavbarMenu.find(MenuDropdownComponent).simulate('click')

        expect(
          mountedNavbarMenu
            .find(MenuDropdownComponent)
            .find(MenuOption)
            .text()
        ).toEqual('Option 1')
      })
    })

    describe("when a menu item's dropdown is visible/active", () => {
      let mockOnclick

      beforeEach(() => {
        mockOnclick = jest.fn()

        menuItems = [
          {
            label: 'Home',
            dropdownMenuElements: [
              {
                label: 'Option 1',
                onClick: mockOnclick
              }
            ]
          }
        ]

        mountedNavbarMenu = mount(<NavbarMenu menuItems={menuItems} />)
      })

      it('should be displayed with a caret', () => {
        expect(mountedNavbarMenu.find('span')).toHaveLength(1)
      })

      describe('when user clicks on a dropdown menu option', () => {
        beforeEach(() => {
          mountedNavbarMenu
            .find(MenuDropdownComponent)
            .find(MenuItem)
            .at(0)
            .simulate('click')

          mountedNavbarMenu
            .find(WrapperMenuDropdown)
            .find(MenuOption)
            .at(0)
            .simulate('click')
        })

        it('should fire the onClick prop', () => {
          expect(mockOnclick).toBeCalled()
        })

        it('should display the menu item as active', () => {
          expect(mountedNavbarMenu.instance().state.activeStatus).toEqual([
            true
          ])
        })
      })
    })
  })

  it('should match snapshot', () => {
    const completeMenuItemsCase = [
      {
        label: 'Home',
        active: true,
        onClick: noop
      },
      {
        label: 'Technology',
        onClick: noop
      },
      {
        label: 'Tokens',
        onClick: noop
      },
      {
        label: 'WhitePaper',
        dropdownMenuElements: [
          {
            label: 'Option 1',
            onClick: noop
          },
          {
            label: 'Option 2',
            onClick: noop
          },
          {
            label: 'Option 3',
            onClick: noop
          }
        ]
      }
    ]

    const wrapper = shallow(<NavbarMenu menuItems={completeMenuItemsCase} />)

    expect(wrapper).toMatchSnapshot()
  })
})
