import * as React from 'react'
import { render } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import * as UtilsModule from '../utils/index'
import { breakpoints } from '@planview/pv-utilities'
import {
    Toolbar,
    ToolbarSectionLeft,
    ToolbarSectionRight,
    ToolbarSeparator,
    ToolbarButtonGroup,
} from '../index'
import { ToolbarButtonEmpty, ToolbarButtonGhost } from '../button'
import { Activity, Card, Filter, PlusCircle } from '@planview/pv-icons'
import { ToolbarDropdownMenu } from '../dropdown'
import { ToolbarMoreMenu } from '../more-menu'
import { ListItem } from '@planview/pv-uikit'

const originalGetBreakPoint = UtilsModule.getBreakPoint

describe('pv-toolbar', () => {
    describe('Test adaptive layout', () => {
        const AdaptiveComponent = () => (
            <Toolbar label="test">
                <ToolbarSectionLeft></ToolbarSectionLeft>
                <ToolbarSectionRight moreMenuLabel="More">
                    <ToolbarButtonGroup groupLabel="test group label">
                        <ToolbarButtonEmpty icon={<Activity />}>
                            Group button 1
                        </ToolbarButtonEmpty>
                        <ToolbarButtonEmpty icon={<Card />}>
                            Group button 2
                        </ToolbarButtonEmpty>
                    </ToolbarButtonGroup>
                    <ToolbarButtonEmpty>Button 1</ToolbarButtonEmpty>
                    <ToolbarSeparator data-testid="separator" />
                    <ToolbarButtonEmpty icon={<Activity />} displayOn="desktop">
                        Button 2
                    </ToolbarButtonEmpty>
                </ToolbarSectionRight>
            </Toolbar>
        )
        describe('Desktop breakpoint', () => {
            it('All items should be present', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.DESKTOP)
                )
                const {
                    queryByTestId,
                    getByText,
                    getByTestId,
                    queryByLabelText,
                } = render(<AdaptiveComponent />)

                expect(queryByLabelText('More')).not.toBeInTheDocument()
                expect(getByText('Button 1')).toBeInTheDocument()
                expect(getByText('Button 2')).toBeInTheDocument()
                expect(queryByTestId('trigger')).not.toBeInTheDocument()
                expect(getByTestId('separator')).toBeInTheDocument()
            })

            it('Group button labels should be visible', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.DESKTOP)
                )
                const { getByText } = render(<AdaptiveComponent />)
                expect(getByText('Group button 1')).toBeInTheDocument()
                expect(getByText('Group button 2')).toBeInTheDocument()
            })
            it('Nested desktop item should be there', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.DESKTOP)
                )
                const { getByLabelText, getByText, queryByLabelText } = render(
                    <Toolbar label="demo">
                        <ToolbarSectionLeft></ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="More">
                            <div style={{ display: 'flex' }}>
                                <ToolbarButtonEmpty
                                    icon={<Filter />}
                                    tooltip="Filter"
                                />
                                <ToolbarButtonEmpty
                                    icon={<Activity />}
                                    displayOn="desktop"
                                    tooltip="Activity"
                                />
                            </div>
                            <ToolbarSeparator />
                            <ToolbarButtonGhost icon={<PlusCircle />}>
                                Add Stuff
                            </ToolbarButtonGhost>
                        </ToolbarSectionRight>
                    </Toolbar>
                )
                expect(queryByLabelText('More')).not.toBeInTheDocument()
                expect(getByLabelText('Filter')).toBeInTheDocument()
                expect(getByLabelText('Activity')).toBeInTheDocument()
                expect(getByText('Add Stuff')).toBeInTheDocument()
            })
        })

        describe('Tablet landscape breakpoint', () => {
            it('Desktop items should not be present. More menu should be present', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.TABLET_LANDSCAPE)
                )
                const { getByTestId, queryByText, getByText, getByRole } =
                    render(<AdaptiveComponent />)
                expect(getByText('Button 1')).toBeInTheDocument()
                expect(queryByText('Button 2')).not.toBeInTheDocument()
                expect(getByTestId('separator')).toBeInTheDocument()
                expect(
                    getByRole('button', { name: 'More' })
                ).toBeInTheDocument()
            })

            it('Group button labels should be visible', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.TABLET_LANDSCAPE)
                )
                const { getByText } = render(<AdaptiveComponent />)
                expect(getByText('Group button 1')).toBeInTheDocument()
                expect(getByText('Group button 2')).toBeInTheDocument()
            })
            it('Nested desktop items in middle should be moved to more menu', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.TABLET_LANDSCAPE)
                )
                const { getByLabelText, getByText, queryByLabelText } = render(
                    <Toolbar label="demo">
                        <ToolbarSectionLeft></ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="More">
                            <div style={{ display: 'flex' }}>
                                <ToolbarButtonEmpty
                                    icon={<Filter />}
                                    tooltip="Filter"
                                />
                                <ToolbarButtonEmpty
                                    icon={<Activity />}
                                    displayOn="desktop"
                                    tooltip="Activity"
                                />
                            </div>
                            <ToolbarSeparator />
                            <ToolbarButtonGhost icon={<PlusCircle />}>
                                Add Stuff
                            </ToolbarButtonGhost>
                        </ToolbarSectionRight>
                    </Toolbar>
                )
                expect(getByLabelText('More')).toBeInTheDocument()
                expect(getByLabelText('Filter')).toBeInTheDocument()
                expect(queryByLabelText('Activity')).not.toBeInTheDocument()
                expect(getByText('Add Stuff')).toBeInTheDocument()
            })
            it('No more menu if there are no desktop items to show in more menu', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.TABLET_LANDSCAPE)
                )
                const { getByLabelText, getByText, queryByLabelText } = render(
                    <Toolbar label="demo">
                        <ToolbarSectionLeft></ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="More">
                            <ToolbarButtonEmpty
                                icon={<Filter />}
                                tooltip="Filter"
                            />
                            <ToolbarButtonEmpty
                                icon={<Activity />}
                                tooltip="Activity"
                            />
                            <ToolbarSeparator />
                            <ToolbarButtonGhost icon={<PlusCircle />}>
                                Add Stuff
                            </ToolbarButtonGhost>
                        </ToolbarSectionRight>
                    </Toolbar>
                )
                expect(queryByLabelText('More')).not.toBeInTheDocument()
                expect(getByLabelText('Filter')).toBeInTheDocument()
                expect(getByLabelText('Activity')).toBeInTheDocument()
                expect(getByText('Add Stuff')).toBeInTheDocument()
            })
        })

        describe('Tablet portrait breakpoint', () => {
            it('Desktop items should not be present. More menu should be present', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.TABLET_PORTRAIT)
                )
                const { getByRole, queryByText, getByText, queryByTestId } =
                    render(
                        <Toolbar label="test">
                            <ToolbarSectionLeft></ToolbarSectionLeft>
                            <ToolbarSectionRight moreMenuLabel="More">
                                <ToolbarButtonEmpty>
                                    Button 1
                                </ToolbarButtonEmpty>
                                <ToolbarSeparator data-testid="separator" />
                                <ToolbarButtonEmpty
                                    icon={<Activity />}
                                    displayOn="desktop"
                                >
                                    Button 2
                                </ToolbarButtonEmpty>
                            </ToolbarSectionRight>
                        </Toolbar>
                    )
                expect(getByText('Button 1')).toBeInTheDocument()
                expect(queryByText('Button 2')).not.toBeInTheDocument()
                expect(queryByTestId('separator')).not.toBeInTheDocument()
                expect(
                    getByRole('button', { name: 'More' })
                ).toBeInTheDocument()
            })
            it('Group button labels should be not visible', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.TABLET_PORTRAIT)
                )
                const { queryByText, getByLabelText } = render(
                    <AdaptiveComponent />
                )
                //Visible labels should be gone
                expect(queryByText('Group button 1')).not.toBeInTheDocument()
                expect(queryByText('Group button 2')).not.toBeInTheDocument()
                //Replaced with aria-labels
                expect(getByLabelText('Group button 1')).toBeInTheDocument()
                expect(getByLabelText('Group button 2')).toBeInTheDocument()
            })
            it('No more menu if there are no desktop items to show in more menu', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.TABLET_PORTRAIT)
                )
                const { getByLabelText, queryByLabelText } = render(
                    <Toolbar label="demo">
                        <ToolbarSectionLeft></ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="More">
                            <ToolbarButtonEmpty
                                icon={<Filter />}
                                tooltip="Filter"
                            />
                            <ToolbarButtonEmpty
                                icon={<Activity />}
                                tooltip="Activity"
                            />
                            <ToolbarSeparator />
                            <ToolbarButtonGhost icon={<PlusCircle />}>
                                Add Stuff
                            </ToolbarButtonGhost>
                        </ToolbarSectionRight>
                    </Toolbar>
                )
                expect(queryByLabelText('More')).not.toBeInTheDocument()
                expect(getByLabelText('Filter')).toBeInTheDocument()
                expect(getByLabelText('Activity')).toBeInTheDocument()
                expect(getByLabelText('Add Stuff')).toBeInTheDocument()
            })
            it('Visible label should be visible only if preventLabelCollapse = true', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.TABLET_PORTRAIT)
                )
                const {
                    getByLabelText,
                    queryByLabelText,
                    getByText,
                    queryByText,
                } = render(
                    <Toolbar label="demo">
                        <ToolbarSectionLeft>
                            <ToolbarButtonEmpty
                                preventLabelCollapse
                                icon={<Filter />}
                            >
                                Filter
                            </ToolbarButtonEmpty>
                        </ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="More">
                            <ToolbarButtonEmpty icon={<Activity />}>
                                Activity
                            </ToolbarButtonEmpty>
                            <ToolbarSeparator />
                            <ToolbarButtonGhost
                                preventLabelCollapse
                                icon={<PlusCircle />}
                            >
                                Add Stuff
                            </ToolbarButtonGhost>
                        </ToolbarSectionRight>
                    </Toolbar>
                )
                //No aria labels on the buttons w preventLabelCollapse
                expect(queryByLabelText('Filter')).not.toBeInTheDocument()
                expect(queryByLabelText('Add Stuff')).not.toBeInTheDocument()
                //But they should have label
                expect(getByText('Filter')).toBeInTheDocument()
                expect(getByText('Add Stuff')).toBeInTheDocument()
                //This one should have aria-label, but no visible label
                expect(getByLabelText('Activity')).toBeInTheDocument()
                expect(queryByText('Activity')).not.toBeInTheDocument()
            })
            it('Phone items should still be there', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.TABLET_PORTRAIT)
                )
                const { getByLabelText, queryByLabelText, queryByText } =
                    render(
                        <Toolbar label="demo">
                            <ToolbarSectionLeft></ToolbarSectionLeft>
                            <ToolbarSectionRight moreMenuLabel="More">
                                <ToolbarButtonEmpty
                                    displayOn="phone"
                                    icon={<Activity />}
                                >
                                    Activity
                                </ToolbarButtonEmpty>
                                <ToolbarSeparator />
                                <ToolbarButtonGhost
                                    preventLabelCollapse
                                    displayOn="desktop"
                                    icon={<PlusCircle />}
                                >
                                    Add Stuff
                                </ToolbarButtonGhost>
                            </ToolbarSectionRight>
                        </Toolbar>
                    )
                //This one should have aria-label, but no visible label
                expect(getByLabelText('Activity')).toBeInTheDocument()
                expect(queryByText('Activity')).not.toBeInTheDocument()

                //Should be gone into more menu
                expect(queryByLabelText('Add Stuff')).not.toBeInTheDocument()
                expect(queryByText('Add Stuff')).not.toBeInTheDocument()
            })
            it('ToolbarButtonGroup displayOn Desktop should be in more menu', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.PHONE)
                )
                const { queryByText, getByLabelText } = render(
                    <Toolbar label="demo">
                        <ToolbarSectionLeft></ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="More">
                            <ToolbarButtonGroup
                                displayOn="desktop"
                                groupLabel="test"
                            >
                                <ToolbarButtonEmpty>Hello</ToolbarButtonEmpty>
                                <ToolbarButtonEmpty>World</ToolbarButtonEmpty>
                            </ToolbarButtonGroup>
                        </ToolbarSectionRight>
                    </Toolbar>
                )
                expect(queryByText('Hello')).not.toBeInTheDocument()
                expect(queryByText('World')).not.toBeInTheDocument()
                expect(getByLabelText('More')).toBeInTheDocument()
            })
        })
        describe('Phone breakpoint', () => {
            it('Only more menu should be present, no separator', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.PHONE)
                )
                const { getByRole, queryByText, queryByTestId } = render(
                    <AdaptiveComponent />
                )
                expect(queryByText('Group button 1')).not.toBeInTheDocument()
                expect(queryByText('Group button 2')).not.toBeInTheDocument()
                expect(queryByText('Button 1')).not.toBeInTheDocument()
                expect(queryByText('Button 2')).not.toBeInTheDocument()
                expect(
                    getByRole('button', { name: 'More' })
                ).toBeInTheDocument()
                expect(queryByTestId('separator')).not.toBeInTheDocument()
            })
            it('Visible label should be visible only if preventLabelCollapse = true', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.PHONE)
                )
                const { getByRole, queryByLabelText, getByText, queryByText } =
                    render(
                        <Toolbar label="demo">
                            <ToolbarSectionLeft>
                                <ToolbarButtonEmpty
                                    preventLabelCollapse
                                    icon={<Filter />}
                                >
                                    Filter
                                </ToolbarButtonEmpty>
                            </ToolbarSectionLeft>
                            <ToolbarSectionRight moreMenuLabel="More">
                                <ToolbarButtonEmpty icon={<Activity />}>
                                    Activity
                                </ToolbarButtonEmpty>
                                <ToolbarSeparator />
                                <ToolbarButtonGhost
                                    preventLabelCollapse
                                    icon={<PlusCircle />}
                                >
                                    Add Stuff
                                </ToolbarButtonGhost>
                            </ToolbarSectionRight>
                        </Toolbar>
                    )
                //No aria labels on the buttons w preventLabelCollapse in normal section
                expect(queryByLabelText('Filter')).not.toBeInTheDocument()
                //Should have a visible label
                expect(getByText('Filter')).toBeInTheDocument()

                //ToolbarSectionRight should be in more menu
                expect(
                    getByRole('button', { name: 'More' })
                ).toBeInTheDocument()
                expect(queryByLabelText('Add Stuff')).not.toBeInTheDocument()
                expect(queryByLabelText('Activity')).not.toBeInTheDocument()
                expect(queryByText('Activity')).not.toBeInTheDocument()
            })
            it('Phone items should still be there', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.PHONE)
                )
                const {
                    getByText,
                    getByLabelText,
                    queryByLabelText,
                    queryByText,
                } = render(
                    <Toolbar label="demo">
                        <ToolbarSectionLeft></ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="More">
                            <ToolbarDropdownMenu
                                displayOn="phone"
                                label="Test dropdown"
                                trigger={(p) => (
                                    <ToolbarButtonEmpty
                                        activated={p['aria-expanded']}
                                        {...p}
                                    >
                                        Open dropdown
                                    </ToolbarButtonEmpty>
                                )}
                            >
                                <ListItem label="item one" />
                            </ToolbarDropdownMenu>
                            <ToolbarButtonEmpty
                                displayOn="phone"
                                icon={<Activity />}
                            >
                                Activity
                            </ToolbarButtonEmpty>
                            <ToolbarSeparator />
                            <ToolbarButtonGhost
                                preventLabelCollapse
                                displayOn="desktop"
                                icon={<PlusCircle />}
                            >
                                Add Stuff
                            </ToolbarButtonGhost>
                        </ToolbarSectionRight>
                    </Toolbar>
                )
                //This one should have aria-label, but no visible label
                expect(getByLabelText('Activity')).toBeInTheDocument()
                expect(queryByText('Activity')).not.toBeInTheDocument()

                //Should be gone into more menu
                expect(queryByLabelText('Add Stuff')).not.toBeInTheDocument()
                expect(queryByText('Add Stuff')).not.toBeInTheDocument()

                //Dropdown should still be there
                expect(getByText('Open dropdown')).toBeInTheDocument()
            })
            it('ToolbarButtonGroup displayOn always: Buttons in group should ignore individual displayOn', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.PHONE)
                )
                const { getByText, queryByLabelText } = render(
                    <Toolbar label="demo">
                        <ToolbarSectionLeft></ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="More">
                            <ToolbarButtonGroup
                                displayOn="phone"
                                groupLabel="test"
                            >
                                <ToolbarButtonEmpty displayOn="desktop">
                                    Hello
                                </ToolbarButtonEmpty>
                                <ToolbarButtonEmpty displayOn="desktop">
                                    World
                                </ToolbarButtonEmpty>
                            </ToolbarButtonGroup>
                        </ToolbarSectionRight>
                    </Toolbar>
                )
                expect(getByText('Hello')).toBeInTheDocument()
                expect(getByText('World')).toBeInTheDocument()
                expect(queryByLabelText('More')).not.toBeInTheDocument()
            })
        })
    })
    describe('Test transformed items', () => {
        describe('Button -> DropdownListItem', () => {
            it('Tablet landscape breakpoint: Desktop Buttons should transformed to DropdownListItems', async () => {
                const spy1 = jest.fn()
                const spy2 = jest.fn()
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.TABLET_LANDSCAPE)
                )
                const { queryByText, getByRole } = render(
                    <Toolbar label="test">
                        <ToolbarSectionLeft></ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="More">
                            <ToolbarButtonEmpty
                                icon={<Activity />}
                                tooltip="Button with only tooltip"
                                displayOn="desktop"
                                onClick={spy1}
                            />
                            <ToolbarButtonEmpty icon={<Activity />}>
                                This button should not be in dropdown
                            </ToolbarButtonEmpty>
                            <ToolbarSeparator data-testid="separator" />
                            <ToolbarButtonEmpty
                                icon={<Activity />}
                                displayOn="desktop"
                                onClick={spy2}
                            >
                                Button with visible label
                            </ToolbarButtonEmpty>
                        </ToolbarSectionRight>
                    </Toolbar>
                )

                expect(
                    queryByText('Button with visible label')
                ).not.toBeInTheDocument()
                expect(
                    queryByText('This button should not be in dropdown')
                ).toBeInTheDocument()

                await userEvent.click(getByRole('button', { name: 'More' }))

                expect(
                    queryByText('Button with only tooltip')
                ).toBeInTheDocument()
                expect(
                    queryByText('Button with visible label')
                ).toBeInTheDocument()

                //Navigate to first item in dropdown 'Button with only tooltip'
                await userEvent.keyboard('{ArrowDown}{ArrowDown}{Enter}')

                expect(spy1).toHaveBeenCalledTimes(0)
                expect(spy2).toHaveBeenCalledTimes(1)
            })
            it('Phone breakpoint: All Buttons should transformed to DropdownListItems', async () => {
                const spy1 = jest.fn()
                const spy2 = jest.fn()
                const spy3 = jest.fn()
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.PHONE)
                )
                const { queryByText, getByRole } = render(
                    <Toolbar label="test">
                        <ToolbarSectionLeft></ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="More">
                            <ToolbarButtonEmpty
                                icon={<Activity />}
                                tooltip="Button with only tooltip"
                                displayOn="desktop"
                                onClick={spy1}
                            />
                            <ToolbarButtonEmpty
                                onClick={spy2}
                                icon={<Activity />}
                            >
                                This button should now be in dropdown
                            </ToolbarButtonEmpty>
                            <ToolbarSeparator data-testid="separator" />
                            <ToolbarButtonEmpty
                                icon={<Activity />}
                                displayOn="desktop"
                                onClick={spy3}
                            >
                                Button with visible label
                            </ToolbarButtonEmpty>
                        </ToolbarSectionRight>
                    </Toolbar>
                )

                expect(
                    queryByText('This button should now be in dropdown')
                ).not.toBeInTheDocument()

                await userEvent.click(getByRole('button', { name: 'More' }))

                expect(
                    queryByText('Button with only tooltip')
                ).toBeInTheDocument()
                expect(
                    queryByText('Button with visible label')
                ).toBeInTheDocument()
                expect(
                    queryByText('This button should now be in dropdown')
                ).toBeInTheDocument()

                await userEvent.keyboard('{ArrowDown}{ArrowDown}{Enter}')

                expect(spy1).toHaveBeenCalledTimes(0)
                expect(spy2).toHaveBeenCalledTimes(1)
                expect(spy3).toHaveBeenCalledTimes(0)
            })
        })
        describe('ButtonGroup -> DropdownGroup', () => {
            it('Phone breakpoint: ButtonGroup should be transformed to DropdownGroup with items', async () => {
                const spy1 = jest.fn()
                const spy2 = jest.fn()

                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.PHONE)
                )
                const { queryByText, getByRole } = render(
                    <Toolbar label="test">
                        <ToolbarSectionLeft></ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="More">
                            <ToolbarSeparator />
                            <ToolbarButtonGroup groupLabel="test label">
                                <ToolbarButtonEmpty
                                    icon={<Activity />}
                                    tooltip="Activity button"
                                    onClick={spy1}
                                />
                                <ToolbarButtonEmpty
                                    icon={<Card />}
                                    tooltip="Card button"
                                    onClick={spy2}
                                />
                            </ToolbarButtonGroup>
                        </ToolbarSectionRight>
                    </Toolbar>
                )

                expect(queryByText('Activity')).not.toBeInTheDocument()

                await userEvent.click(getByRole('button', { name: 'More' }))

                expect(queryByText('test label')).toBeInTheDocument()
                expect(queryByText('Activity button')).toBeInTheDocument()
                expect(queryByText('Card button')).toBeInTheDocument()

                await userEvent.keyboard('{ArrowDown}{ArrowDown}{Enter}')

                expect(spy1).toHaveBeenCalledTimes(0)
                expect(spy2).toHaveBeenCalledTimes(1)
            })
        })
        describe('Dropdown -> DropdownAccordion', () => {
            it('Phone breakpoint: Dropdown should be transformed to DropdownAccordion with items', async () => {
                const spy1 = jest.fn()
                const spy2 = jest.fn()

                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.PHONE)
                )
                const { queryByText, getByRole, baseElement } = render(
                    <Toolbar label="test">
                        <ToolbarSectionLeft></ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="More">
                            <ToolbarSeparator />
                            <ToolbarDropdownMenu
                                label="test dropdown"
                                trigger={() => (
                                    <ToolbarButtonEmpty>
                                        Open dropdown
                                    </ToolbarButtonEmpty>
                                )}
                            >
                                <ListItem
                                    onActivate={spy1}
                                    label="dropdown item 1"
                                />
                                <ListItem
                                    onActivate={spy2}
                                    label="dropdown item 2"
                                />
                            </ToolbarDropdownMenu>
                        </ToolbarSectionRight>
                    </Toolbar>
                )

                expect(queryByText('Open dropdown')).not.toBeInTheDocument()

                await userEvent.click(getByRole('button', { name: 'More' }))

                await userEvent.click(
                    getByRole('menuitem', { name: 'test dropdown' })
                )

                await userEvent.click(
                    /* For some reason, react testing library cannot find this with normal getByRole selection */
                    baseElement.querySelectorAll('[role="menuitemradio"]')[1]
                )

                expect(spy1).toHaveBeenCalledTimes(0)
                expect(spy2).toHaveBeenCalledTimes(1)
            })
        })
    })

    describe('Test keyboard navigation arrows', () => {
        beforeEach(() => {
            userEvent.setup()
        })
        it('Navigate to third item in first section', async () => {
            const spy1 = jest.fn()
            const { getByLabelText } = render(
                <Toolbar label="test">
                    <ToolbarSectionLeft>
                        <ToolbarButtonEmpty
                            tooltip="first button"
                            icon={<Activity />}
                        />
                        <ToolbarButtonEmpty
                            tooltip="second button"
                            icon={<Card />}
                        />
                        <ToolbarButtonEmpty
                            tooltip="third button"
                            onClick={spy1}
                            icon={<Card />}
                        />
                    </ToolbarSectionLeft>
                    <ToolbarSectionRight moreMenuLabel="More">
                        <ToolbarButtonEmpty icon={<Activity />} />
                        <ToolbarButtonEmpty icon={<Card />} />
                    </ToolbarSectionRight>
                </Toolbar>
            )
            await userEvent.keyboard('{Tab}')
            expect(getByLabelText('first button')).toHaveFocus()
            await userEvent.keyboard('{ArrowRight}')
            await userEvent.keyboard('{ArrowRight}')
            expect(getByLabelText('third button')).toHaveFocus()
            await userEvent.keyboard('{enter}')
            expect(spy1).toHaveBeenCalledTimes(1)
        })
        it('Navigate to last item in second section', async () => {
            jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                originalGetBreakPoint(breakpoints.DESKTOP)
            )
            const spy1 = jest.fn()
            const { getByLabelText } = render(
                <Toolbar label="test">
                    <ToolbarSectionLeft>
                        <ToolbarButtonEmpty
                            tooltip="first button"
                            icon={<Activity />}
                        />
                    </ToolbarSectionLeft>
                    <ToolbarSectionRight moreMenuLabel="More">
                        <ToolbarButtonEmpty icon={<Activity />} />
                        <ToolbarButtonEmpty
                            onClick={spy1}
                            tooltip="last button"
                            icon={<Card />}
                        />
                    </ToolbarSectionRight>
                </Toolbar>
            )
            await userEvent.keyboard('{Tab}')
            expect(getByLabelText('first button')).toHaveFocus()
            await userEvent.keyboard('{ArrowRight}')
            await userEvent.keyboard('{ArrowRight}')
            expect(getByLabelText('last button')).toHaveFocus()
            await userEvent.keyboard('{enter}')
            expect(spy1).toHaveBeenCalledTimes(1)
        })
        it('should not skip disabled buttons (but not call onClick)', async () => {
            jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                originalGetBreakPoint(breakpoints.DESKTOP)
            )
            const spy1 = jest.fn()
            const { getByLabelText } = render(
                <Toolbar label="test">
                    <ToolbarSectionLeft>
                        <ToolbarButtonEmpty
                            tooltip="first button"
                            icon={<Activity />}
                        />
                        <ToolbarButtonEmpty
                            disabled
                            aria-label="disabled button 1"
                            onClick={spy1}
                            icon={<Card />}
                        />
                    </ToolbarSectionLeft>
                    <ToolbarSectionRight moreMenuLabel="More">
                        <ToolbarButtonEmpty
                            tooltip="last button"
                            icon={<Card />}
                        />
                    </ToolbarSectionRight>
                </Toolbar>
            )
            await userEvent.keyboard('{Tab}')
            expect(getByLabelText('first button')).toHaveFocus()
            await userEvent.keyboard('{ArrowRight}')
            expect(getByLabelText('disabled button 1')).toHaveFocus()
            await userEvent.keyboard('{enter}')
            expect(spy1).toHaveBeenCalledTimes(0)
        })
    })
    describe('ToolbarMoreMenu', () => {
        describe('Breakpoint desktop', () => {
            it('Custom menu should be there, all items present', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.DESKTOP)
                )
                const { getByLabelText, getByRole } = render(
                    <Toolbar label="test">
                        <ToolbarSectionLeft></ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="custom more">
                            <ToolbarButtonEmpty
                                disabled
                                aria-label="disabled button 2"
                                displayOn="desktop"
                                icon={<Card />}
                            />
                            <ToolbarButtonEmpty
                                tooltip="last button"
                                displayOn="desktop"
                                icon={<Card />}
                            />
                            <ToolbarMoreMenu>
                                <ListItem label="hello" />
                            </ToolbarMoreMenu>
                        </ToolbarSectionRight>
                    </Toolbar>
                )
                expect(
                    getByRole('button', { name: 'custom more' })
                ).toBeInTheDocument()
                expect(getByLabelText('disabled button 2')).toBeInTheDocument()
                expect(getByLabelText('custom more')).toBeInTheDocument()
                expect(getByLabelText('last button')).toBeInTheDocument()
            })
        })
        describe('Breakpoint tablet landscape', () => {
            it('Custom menu should be there, desktop items in menu', async () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.TABLET_LANDSCAPE)
                )
                const { getByRole, queryByText } = render(
                    <Toolbar label="test">
                        <ToolbarSectionLeft></ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="custom more">
                            <ToolbarButtonEmpty
                                disabled
                                tooltip="disabled button 2"
                                displayOn="desktop"
                                icon={<Card />}
                            />
                            <ToolbarButtonEmpty
                                tooltip="last button"
                                displayOn="desktop"
                                icon={<Card />}
                            />
                            <ToolbarMoreMenu>
                                <ListItem label="hello" />
                            </ToolbarMoreMenu>
                        </ToolbarSectionRight>
                    </Toolbar>
                )

                await userEvent.click(
                    getByRole('button', { name: 'custom more' })
                )

                expect(queryByText('disabled button 2')).toBeInTheDocument()
                expect(queryByText('last button')).toBeInTheDocument()
                expect(queryByText('hello')).toBeInTheDocument()
            })
        })
        describe('Breakpoint tablet portrait', () => {
            it('Custom menu should be there, desktop items in menu', async () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.TABLET_PORTRAIT)
                )
                const { getByRole, queryByText } = render(
                    <Toolbar label="test">
                        <ToolbarSectionLeft></ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="custom more">
                            <ToolbarButtonEmpty
                                disabled
                                tooltip="disabled button 2"
                                displayOn="desktop"
                                icon={<Card />}
                            />
                            <ToolbarButtonEmpty
                                tooltip="last button"
                                displayOn="desktop"
                                icon={<Card />}
                            />
                            <ToolbarMoreMenu>
                                <ListItem label="hello" />
                            </ToolbarMoreMenu>
                        </ToolbarSectionRight>
                    </Toolbar>
                )

                await userEvent.click(
                    getByRole('button', { name: 'custom more' })
                )
                expect(queryByText('disabled button 2')).toBeInTheDocument()
                expect(queryByText('last button')).toBeInTheDocument()
                expect(queryByText('hello')).toBeInTheDocument()
            })
            it('More menu should be there, only non-desktop items but custom content', async () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.TABLET_PORTRAIT)
                )
                const { getByRole, container } = render(
                    <Toolbar label="test">
                        <ToolbarSectionLeft></ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="custom more">
                            <ToolbarButtonEmpty
                                disabled
                                tooltip="disabled button 2"
                                icon={<Card />}
                            />
                            <ToolbarButtonEmpty
                                tooltip="last button"
                                icon={<Card />}
                            />
                            <ToolbarMoreMenu>
                                <ListItem label="hello" />
                            </ToolbarMoreMenu>
                        </ToolbarSectionRight>
                    </Toolbar>
                )

                await userEvent.click(
                    getByRole('button', { name: 'custom more' })
                )
                //Make sure there is no divider line if no collapsed content
                expect(container.querySelector('hr')).not.toBeInTheDocument()
            })
        })
        describe('Breakpoint phone', () => {
            it('Custom menu should be there, desktop items in menu', async () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.PHONE)
                )
                const { getByRole, queryByText } = render(
                    <Toolbar label="test">
                        <ToolbarSectionLeft></ToolbarSectionLeft>
                        <ToolbarSectionRight moreMenuLabel="custom more">
                            <ToolbarButtonEmpty
                                disabled
                                tooltip="disabled button 2"
                                displayOn="desktop"
                                icon={<Card />}
                            />
                            <ToolbarButtonEmpty
                                tooltip="last button"
                                displayOn="desktop"
                                icon={<Card />}
                            />
                            <ToolbarMoreMenu>
                                <ListItem label="hello" />
                            </ToolbarMoreMenu>
                        </ToolbarSectionRight>
                    </Toolbar>
                )

                await userEvent.click(
                    getByRole('button', { name: 'custom more' })
                )
                expect(queryByText('disabled button 2')).toBeInTheDocument()
                expect(queryByText('last button')).toBeInTheDocument()
                expect(queryByText('hello')).toBeInTheDocument()
            })
        })
    })
    describe('Test conditional children patterns', () => {
        function renderComponent(showChildren: boolean) {
            return render(
                <Toolbar label="Test toolbar">
                    <ToolbarSectionLeft>
                        <ToolbarDropdownMenu
                            label="Dropdown item"
                            trigger={{ label: 'Trigger' }}
                        >
                            <ListItem label="Sample" />
                            {showChildren && <ListItem label="Returns false" />}
                            {showChildren ? (
                                <ListItem label="Returns null" />
                            ) : null}
                            {showChildren ? (
                                <ListItem label="Returns undefined" />
                            ) : undefined}
                            {showChildren ? (
                                <>
                                    <ListItem label="Returns Fragment" />
                                </>
                            ) : undefined}
                        </ToolbarDropdownMenu>
                    </ToolbarSectionLeft>
                    <ToolbarSectionRight moreMenuLabel="More options">
                        {showChildren ? (
                            <ToolbarButtonEmpty>
                                Returns undefined
                            </ToolbarButtonEmpty>
                        ) : undefined}
                        {showChildren ? (
                            <ToolbarButtonEmpty>
                                Returns null
                            </ToolbarButtonEmpty>
                        ) : null}
                        {showChildren && (
                            <ToolbarButtonEmpty>
                                Returns false
                            </ToolbarButtonEmpty>
                        )}
                        {showChildren && (
                            <>
                                <ToolbarSeparator />
                                <ToolbarButtonEmpty>
                                    Returns fragment
                                </ToolbarButtonEmpty>
                            </>
                        )}
                    </ToolbarSectionRight>
                </Toolbar>
            )
        }

        beforeEach(() => {
            userEvent.setup()
            jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                originalGetBreakPoint(breakpoints.DESKTOP)
            )
        })

        it('should render without additional buttons or errors', () => {
            const { queryAllByRole } = renderComponent(false)

            expect(queryAllByRole('button')).toHaveLength(1)
        })

        it('should render buttons', () => {
            const { queryAllByRole } = renderComponent(true)

            expect(queryAllByRole('button')).toHaveLength(5)
        })

        it('should render dropdown without additional items or errors', async () => {
            const { getByRole, queryAllByRole } = renderComponent(false)

            await userEvent.click(getByRole('button', { name: 'Trigger' }))

            expect(queryAllByRole('menuitemradio')).toHaveLength(1)
        })

        it('should render dropdown with additional items', async () => {
            const { getByRole, queryAllByRole } = renderComponent(true)
            await userEvent.click(getByRole('button', { name: 'Trigger' }))

            expect(queryAllByRole('menuitemradio')).toHaveLength(5)
        })
    })
})
