import React from 'react';
import {mount} from '../../build/enzyme';
import {KeyCodes} from '../../utils/constants';

import {TabPanel, TabItem, NavDropdown} from '..';

class TestContainer extends React.Component {
    render() {
        let {children, ...props} = this.props;

        return <li {...props}>{children}</li>;
    }
}

const fakeContext = {
    router: {
        isActive: (location, indexOnly) => location === '/active/path',
        createHref: () => {}
    }
};

const simplePanel = (
    <TabPanel data-test-automation-id="simplePanel">
        <TabItem to="/not/active/path" data-test-automation-id="notActiveItem">
            Item 1
        </TabItem>
        <TabItem to="/active/path" data-test-automation-id="activeItem">
            Item 2
        </TabItem>
        <TabItem to="/another/not/active/path" data-test-automation-id="anotherNotActiveItem">
            Item 3
        </TabItem>
    </TabPanel>
);

const complexPanel = (
    <TabPanel data-test-automation-id="complexPanel">
        <TabItem to="/not/active/path" id="tab-item-1">
            Valid Item 1
        </TabItem>
        <NavDropdown to="/active/path" title="valid item" data-test-automation-id="navDropdown">
            <TabItem to="/item1">NavDropdown Item 1</TabItem>
            <TabItem to="/item2">NavDropdown Item 2</TabItem>
            <TabItem to="/item3">NavDropdown Item 3</TabItem>
        </NavDropdown>
        <TestContainer role="tab" id="test-container-1">
            <span>Valid Item 3</span>
        </TestContainer>
        <TestContainer role="menuitem" id="test-container-2">
            <span>Valid Item 4</span>
        </TestContainer>
        <TestContainer role="unknown" id="test-container-3">
            <span>Invalid Item 5</span>
        </TestContainer>
    </TabPanel>
);
const COMPLEX_PANEL_TAB_INDEXES = {
    TAB_ITEM_0: 0,
    NAV_DROPDOWN_1: 1,
    TEST_CONTAINER_2: 2,
    TEST_CONTAINER_3: 3,
    TEST_CONTAINER_4_INVALID: 4
};

describe('TabPanel', () => {
    //---------------------------------------------------------
    it('activates a tab according to current url', () => {
        let wrapper = mount(simplePanel, {context: fakeContext});

        let {active} = wrapper
            .findByTestAutomation('activeItem')
            .find('NavItem')
            .props();
        expect(active).toBe(true);
    });
    //---------------------------------------------------------
    it('opens NavDropdown with keyboard', () => {
        let wrapper = mount(complexPanel, {context: fakeContext});

        wrapper
            .findByTestAutomation('navDropdown')
            .last()
            .simulate('keyDown', {
                keyCode: KeyCodes.ARROW_DOWN
            });

        let dropDownMenu = wrapper.find('DropdownMenu');
        let {open} = dropDownMenu.props();

        expect(open).toBe(true);
    });
    //---------------------------------------------------------
    it('will work if appears several times at a page', () => {
        let panels = (
            <React.Fragment>
                {simplePanel}
                {complexPanel}
            </React.Fragment>
        );
        let wrapper = mount(panels, {context: fakeContext});
        let simplePanelWrapper = wrapper.findByTestAutomation('simplePanel').first();
        let simplePanelInstance = simplePanelWrapper.instance();
        let complexPanelWrapper = wrapper.findByTestAutomation('complexPanel').first();
        let complexPanelInstance = complexPanelWrapper.instance();

        expect(simplePanelWrapper.exists()).toBe(true);
        expect(complexPanelWrapper.exists()).toBe(true);

        let actualSimplePanelFocusedItemIndex = 2;
        simplePanelWrapper
            .find('TabItem a')
            .last()
            .simulate('click');
        expect(simplePanelInstance.state.focusedItemIndex).toBe(actualSimplePanelFocusedItemIndex);

        let expectedSimplePanelFocusedItemIndex = 1;
        simplePanelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_UP
        });
        expect(simplePanelInstance.state.focusedItemIndex).toBe(
            expectedSimplePanelFocusedItemIndex
        );

        let actualComplexPanelFocusedItemIndex = COMPLEX_PANEL_TAB_INDEXES.TEST_CONTAINER_3;
        complexPanelWrapper.find('#test-container-2 span').simulate('click');
        expect(complexPanelInstance.state.focusedItemIndex).toBe(
            actualComplexPanelFocusedItemIndex
        );

        let expectedComplexPanelFocusedItemIndex = COMPLEX_PANEL_TAB_INDEXES.TAB_ITEM_0;
        complexPanelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_DOWN
        });
        expect(complexPanelInstance.state.focusedItemIndex).toBe(
            expectedComplexPanelFocusedItemIndex
        );
    });
    //---------------------------------------------------------
    it('correctly moves focus on right keyboard button keyDown event', () => {
        let panelWrapper = mount(complexPanel, {context: fakeContext});
        let panelInstance = panelWrapper.instance();

        panelInstance.setFocusedItemByIndex(COMPLEX_PANEL_TAB_INDEXES.TAB_ITEM_0);

        panelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_RIGHT
        });
        expect(panelInstance.state.focusedItemIndex).toBe(COMPLEX_PANEL_TAB_INDEXES.NAV_DROPDOWN_1);

        panelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_RIGHT
        });
        expect(panelInstance.state.focusedItemIndex).toBe(
            COMPLEX_PANEL_TAB_INDEXES.TEST_CONTAINER_2
        );

        panelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_RIGHT
        });
        expect(panelInstance.state.focusedItemIndex).toBe(
            COMPLEX_PANEL_TAB_INDEXES.TEST_CONTAINER_3
        );

        panelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_RIGHT
        });
        expect(panelInstance.state.focusedItemIndex).toBe(COMPLEX_PANEL_TAB_INDEXES.TAB_ITEM_0);
    });
    //---------------------------------------------------------
    it('correctly moves focus on left keyboard button keyDown event', () => {
        let panelWrapper = mount(complexPanel, {context: fakeContext});
        let panelInstance = panelWrapper.instance();

        panelInstance.setFocusedItemByIndex(COMPLEX_PANEL_TAB_INDEXES.TAB_ITEM_0);

        panelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_LEFT
        });
        expect(panelInstance.state.focusedItemIndex).toBe(
            COMPLEX_PANEL_TAB_INDEXES.TEST_CONTAINER_3
        );

        panelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_LEFT
        });
        expect(panelInstance.state.focusedItemIndex).toBe(
            COMPLEX_PANEL_TAB_INDEXES.TEST_CONTAINER_2
        );

        panelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_LEFT
        });
        expect(panelInstance.state.focusedItemIndex).toBe(COMPLEX_PANEL_TAB_INDEXES.NAV_DROPDOWN_1);

        panelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_LEFT
        });
        expect(panelInstance.state.focusedItemIndex).toBe(COMPLEX_PANEL_TAB_INDEXES.TAB_ITEM_0);
    });
    //---------------------------------------------------------
    it('correctly moves focus on up keyboard button keyDown event', () => {
        let panelWrapper = mount(complexPanel, {context: fakeContext});
        let panelInstance = panelWrapper.instance();

        panelInstance.setFocusedItemByIndex(COMPLEX_PANEL_TAB_INDEXES.TAB_ITEM_0);

        panelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_UP
        });
        expect(panelInstance.state.focusedItemIndex).toBe(
            COMPLEX_PANEL_TAB_INDEXES.TEST_CONTAINER_3
        );

        panelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_UP
        });
        expect(panelInstance.state.focusedItemIndex).toBe(
            COMPLEX_PANEL_TAB_INDEXES.TEST_CONTAINER_2
        );

        panelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_UP
        });
        expect(panelInstance.state.focusedItemIndex).toBe(COMPLEX_PANEL_TAB_INDEXES.NAV_DROPDOWN_1);

        panelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_UP
        });
        expect(panelInstance.state.focusedItemIndex).toBe(COMPLEX_PANEL_TAB_INDEXES.TAB_ITEM_0);
    });
    //---------------------------------------------------------
    it('correctly moves focus on down keyboard button keyDown event', () => {
        let panelWrapper = mount(complexPanel, {context: fakeContext});
        let panelInstance = panelWrapper.instance();

        panelInstance.setFocusedItemByIndex(COMPLEX_PANEL_TAB_INDEXES.TEST_CONTAINER_2);

        panelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_DOWN
        });
        expect(panelInstance.state.focusedItemIndex).toBe(
            COMPLEX_PANEL_TAB_INDEXES.TEST_CONTAINER_3
        );

        panelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_DOWN
        });
        expect(panelInstance.state.focusedItemIndex).toBe(COMPLEX_PANEL_TAB_INDEXES.TAB_ITEM_0);

        panelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_DOWN
        });
        expect(panelInstance.state.focusedItemIndex).toBe(COMPLEX_PANEL_TAB_INDEXES.NAV_DROPDOWN_1);

        panelWrapper
            .findByTestAutomation('navDropdown')
            .last()
            .simulate('keyDown', {
                keyCode: KeyCodes.ARROW_DOWN
            });
        expect(panelInstance.state.focusedItemIndex).toBe(COMPLEX_PANEL_TAB_INDEXES.NAV_DROPDOWN_1);

        panelWrapper.simulate('keyDown', {
            keyCode: KeyCodes.ARROW_DOWN
        });

        let dropDownMenu = panelWrapper.find('DropdownMenu');
        let {open} = dropDownMenu.props();

        expect(open).toBe(true);
    });
});
