import * as React from 'react'
import * as UtilsModule from '../utils/index'
import { render, screen } from '../__utils/test-utils'
import userEvent from '@testing-library/user-event'
import {
    Toolbar,
    ToolbarSectionLeft,
    ToolbarSectionRight,
    ToolbarDatePicker,
} from '../'
import { breakpoints } from '@planview/pv-utilities'
import { Calendar } from '@planview/pv-icons'

const originalGetBreakPoint = UtilsModule.getBreakPoint

describe('ToolbarDatePicker', () => {
    beforeEach(() => {
        userEvent.setup()
    })
    describe('Display', () => {
        it('should use label', () => {
            const { getByText } = render(
                <ToolbarDatePicker
                    label="This please"
                    value="2022-02-12"
                    defaultValue="2022-02-12"
                    placeholder="Not this please"
                />
            )
            expect(getByText('This please')).toBeInTheDocument()
        })
        it('should use value', () => {
            const { getByText } = render(
                <ToolbarDatePicker
                    value="2022-02-12"
                    defaultValue="2022-02-22"
                    placeholder="Not this please"
                />
            )
            expect(getByText('2022-02-12')).toBeInTheDocument()
        })
        it('should use defaultValue', () => {
            const { getByText } = render(
                <ToolbarDatePicker
                    defaultValue="2022-02-12"
                    placeholder="Not this please"
                />
            )
            expect(getByText('2022-02-12')).toBeInTheDocument()
        })
        it('should use placeholder', () => {
            const { getByText } = render(
                <ToolbarDatePicker placeholder="this please" />
            )
            expect(getByText('this please')).toBeInTheDocument()
        })
    })
    describe('Callbacks', () => {
        it('test onChange', async () => {
            const spy = jest.fn()
            const { getByLabelText } = render(
                <Toolbar label="demo">
                    <ToolbarSectionLeft>
                        <ToolbarDatePicker
                            placeholder="Please add date"
                            onChange={spy}
                        />
                    </ToolbarSectionLeft>
                </Toolbar>
            )
            await userEvent.keyboard('{Tab}')
            expect(getByLabelText('Please add date')).toHaveFocus()
            await userEvent.keyboard('{enter}')
            const input = screen.getByPlaceholderText('Please add date')
            expect(input).toHaveFocus()
            await userEvent.keyboard('2022-06-06{enter}')
            expect(spy).toHaveBeenCalledWith('2022-06-06')
        })
        it('test cancel', async () => {
            const spy = jest.fn()
            const { getByLabelText } = render(
                <Toolbar label="demo">
                    <ToolbarSectionLeft>
                        <ToolbarDatePicker
                            placeholder="Please add date"
                            onChange={spy}
                        />
                    </ToolbarSectionLeft>
                </Toolbar>
            )
            await userEvent.keyboard('{Tab}')
            expect(getByLabelText('Please add date')).toHaveFocus()
            await userEvent.keyboard('{enter}')
            const input = screen.getByPlaceholderText('Please add date')
            expect(input).toHaveFocus()
            await userEvent.keyboard('2022-06-06{escape}')
            expect(spy).not.toHaveBeenCalled()
        })
    })
    describe('Adaptive behavior', () => {
        describe('Desktop breakpoint', () => {
            it('datepicker should be present', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.DESKTOP)
                )
                const { getByText, queryByLabelText } = render(
                    <Toolbar label="demo">
                        <ToolbarSectionRight moreMenuLabel="test">
                            <ToolbarDatePicker placeholder="Please add date" />
                        </ToolbarSectionRight>
                    </Toolbar>
                )
                //Item should be in toolbar
                expect(getByText('Please add date')).toBeInTheDocument()
                //There should be no more menu
                expect(queryByLabelText('More')).not.toBeInTheDocument()
            })
        })
        describe('Tablet landscape breakpoint', () => {
            it('datepicker should be present', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.TABLET_LANDSCAPE)
                )
                const { getByText, queryByLabelText } = render(
                    <Toolbar label="demo">
                        <ToolbarSectionRight moreMenuLabel="test">
                            <ToolbarDatePicker placeholder="Please add date" />
                        </ToolbarSectionRight>
                    </Toolbar>
                )
                //Item should be in toolbar
                expect(getByText('Please add date')).toBeInTheDocument()
                //There should be no more menu
                expect(queryByLabelText('More')).not.toBeInTheDocument()
            })
        })
        describe('Table portrait breakpoint', () => {
            it('datepicker should be present', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.TABLET_PORTRAIT)
                )
                const { getByText, queryByLabelText } = render(
                    <Toolbar label="demo">
                        <ToolbarSectionRight moreMenuLabel="test">
                            <ToolbarDatePicker placeholder="Please add date" />
                        </ToolbarSectionRight>
                    </Toolbar>
                )
                //Item should be in toolbar
                expect(getByText('Please add date')).toBeInTheDocument()
                //There should be no more menu
                expect(queryByLabelText('More')).not.toBeInTheDocument()
            })
            it('datepicker should be present, but only icon', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.TABLET_PORTRAIT)
                )
                const { queryByText, queryByLabelText, getByLabelText } =
                    render(
                        <Toolbar label="demo">
                            <ToolbarSectionRight moreMenuLabel="test">
                                <ToolbarDatePicker
                                    icon={<Calendar />}
                                    placeholder="Please add date"
                                />
                            </ToolbarSectionRight>
                        </Toolbar>
                    )
                //Item should be in toolbar, but no visible text
                expect(queryByText('Please add date')).not.toBeInTheDocument()
                //Should have aria-label
                expect(getByLabelText('Please add date')).toBeInTheDocument()
                //There should be no more menu
                expect(queryByLabelText('More')).not.toBeInTheDocument()
            })
        })
        describe('Phone breakpoint', () => {
            it('datepicker should not be present', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.PHONE)
                )
                const { queryByText, queryByLabelText } = render(
                    <Toolbar label="demo">
                        <ToolbarSectionRight moreMenuLabel="test">
                            <ToolbarDatePicker placeholder="Please add date" />
                        </ToolbarSectionRight>
                    </Toolbar>
                )
                //Item should not be in toolbar
                expect(queryByText('Please add date')).not.toBeInTheDocument()
                expect(
                    queryByLabelText('Please add date')
                ).not.toBeInTheDocument()
                //There should be no more menu
                expect(queryByLabelText('More')).not.toBeInTheDocument()
            })
            it('datepicker should be present if set to phone', () => {
                jest.spyOn(UtilsModule, 'getBreakPoint').mockReturnValue(
                    originalGetBreakPoint(breakpoints.PHONE)
                )
                const { queryByText, queryByLabelText, getByLabelText } =
                    render(
                        <Toolbar label="demo">
                            <ToolbarSectionRight moreMenuLabel="test">
                                <ToolbarDatePicker
                                    displayOn="phone"
                                    icon={<Calendar />}
                                    placeholder="Please add date"
                                />
                            </ToolbarSectionRight>
                        </Toolbar>
                    )
                //Item should be in toolbar, but no visible text
                expect(queryByText('Please add date')).not.toBeInTheDocument()
                //Should have aria-label
                expect(getByLabelText('Please add date')).toBeInTheDocument()
                //There should be no more menu
                expect(queryByLabelText('More')).not.toBeInTheDocument()
            })
        })
    })
})
