import * as React from 'react'
import { render } from '../__utils/test-utils'
import userEvent from '@testing-library/user-event'
import * as UtilsModule from '../utils/index'
import { breakpoints } from '@planview/pv-utilities'
import {
    ToolbarSectionLeft,
    ToolbarSectionRight,
    NavigationBar,
    LogoProjectPlace,
    ToolbarButtonEmptyInverse,
    ToolbarSeparator,
} from '../index'
import { Activity, Board, User } from '@planview/pv-icons'
import { ListItem } from '@planview/pv-uikit'
import { UserMenu } from './user-menu'

const originalGetBreakPoint = UtilsModule.getBreakPoint

describe('NavigationBar', () => {
    const AdaptiveComponent = ({ url = '/' }: { url?: string | null }) => (
        <NavigationBar
            aria-label="test navigation"
            logo={
                <LogoProjectPlace
                    url={url || undefined}
                    label="ProjectPlace home"
                />
            }
        >
            <ToolbarSectionLeft>
                <ToolbarButtonEmptyInverse icon={<Activity />}>
                    Activities
                </ToolbarButtonEmptyInverse>
                <ToolbarSeparator data-testid="separator" />
            </ToolbarSectionLeft>
            <ToolbarSectionRight moreMenuLabel="More">
                <ToolbarButtonEmptyInverse
                    displayOn="tablet-landscape"
                    icon={<Board />}
                >
                    Boards
                </ToolbarButtonEmptyInverse>
            </ToolbarSectionRight>
            <UserMenu triggerElement={<User />}>
                <ListItem label="Log out" />
            </UserMenu>
        </NavigationBar>
    )
    describe('Layout', () => {
        describe('General', () => {
            it('should use correct role', () => {
                const { getByRole } = render(<AdaptiveComponent />)
                expect(
                    getByRole('navigation', { name: 'test navigation' })
                ).toBeInTheDocument()
            })
            it('user menu should be present', () => {
                const { getByRole } = render(<AdaptiveComponent />)
                expect(
                    getByRole('button', { name: 'User menu', expanded: false })
                ).toBeInTheDocument()
            })
            it('logo should be wrapped in anchor tag when using url', () => {
                const { getByLabelText } = render(<AdaptiveComponent />)
                expect(getByLabelText('ProjectPlace home')).toHaveAttribute(
                    'href',
                    '/'
                )
            })
            it('logo should not be wrapped in anchor tag when not using url', () => {
                const { getByRole } = render(<AdaptiveComponent url={null} />)
                expect(
                    getByRole('img', { name: 'ProjectPlace home' })
                ).toBeInTheDocument()
            })
        })
        describe('Adaptive layout', () => {
            afterAll(() => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.DESKTOP)
                )
            })
            describe('Desktop', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.DESKTOP)
                )
                it('all items should be present', () => {
                    const { getByText, getByTestId, queryByLabelText } = render(
                        <AdaptiveComponent />
                    )
                    expect(queryByLabelText('More')).not.toBeInTheDocument()
                    expect(getByText('Activities')).toBeInTheDocument()
                    expect(getByText('Boards')).toBeInTheDocument()
                    expect(getByTestId('separator')).toBeInTheDocument()
                })
            })
            describe('Tablet portrait', () => {
                it('labels should be collapsed, more menu should be present', () => {
                    jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                        originalGetBreakPoint(breakpoints.TABLET_PORTRAIT)
                    )
                    const { queryByTestId, queryByLabelText, queryByText } =
                        render(<AdaptiveComponent />)
                    expect(queryByLabelText('More')).toBeInTheDocument()
                    expect(queryByText('Activities')).not.toBeInTheDocument()
                    expect(queryByText('Boards')).not.toBeInTheDocument()
                    expect(queryByTestId('separator')).not.toBeInTheDocument()
                })
            })
        })
    })
    describe('Interaction', () => {
        it('should stop at all items', async () => {
            const { getByRole } = render(<AdaptiveComponent />)
            await userEvent.keyboard('{Tab}')
            expect(
                getByRole('link', { name: 'ProjectPlace home' })
            ).toHaveFocus()
            await userEvent.keyboard('{ArrowRight}')
            expect(getByRole('button', { name: 'Activities' })).toHaveFocus()
            await userEvent.keyboard('{ArrowRight}')
            expect(getByRole('button', { name: 'Boards' })).toHaveFocus()
            await userEvent.keyboard('{ArrowRight}')
            expect(getByRole('button', { name: 'User menu' })).toHaveFocus()
        })
    })
})
