import React from 'react'
import { render, snapshot } from '../utils/test-utils'
import { GridCellDefault } from './cell-default'
import { Calendar, Mail } from '@planview/pv-icons'
import { Avatar } from '@planview/pv-uikit'
import userEvent from '@testing-library/user-event'
import { overflow } from '@planview/pv-utilities'

jest.mock('@planview/pv-utilities', () => {
    const utilities: any = jest.requireActual('@planview/pv-utilities')
    return {
        __esModule: true,
        ...utilities,
        overflow: {
            ...utilities.overflow,
            isEllipsisActive: jest.fn().mockReturnValue(false),
        },
    }
})

describe('GridCellDefault', () => {
    snapshot('Minimal props', <GridCellDefault tabIndex={0} />)
    snapshot('Label', <GridCellDefault tabIndex={0} label="Cell content" />)
    snapshot('Icon', <GridCellDefault tabIndex={0} icon={<Calendar />} />)
    snapshot(
        'Icon and Label',
        <GridCellDefault
            tabIndex={0}
            icon={<Calendar />}
            label="Cell content"
        />
    )
    snapshot(
        'Avatar (string)',
        <GridCellDefault tabIndex={0} avatar="about:blank" />
    )
    snapshot(
        'Avatar (component)',
        <GridCellDefault tabIndex={0} avatar={<Avatar initials="DN" />} />
    )
    snapshot(
        'Avatar and Label',
        <GridCellDefault
            tabIndex={0}
            avatar={<Avatar initials="DN" />}
            label="Cell content"
        />
    )
    snapshot('Badge', <GridCellDefault tabIndex={0} badge={10} />)
    snapshot(
        'Badge and Label',
        <GridCellDefault tabIndex={0} badge={10} label="Cell content" />
    )
    snapshot(
        'WithCaret',
        <GridCellDefault tabIndex={0} withCaret label="Cell content" />
    )
    snapshot(
        'With link',
        <GridCellDefault
            label="Cell content"
            tabIndex={0}
            href="http://www.planview.com"
        />
    )
    snapshot(
        'With link and icon',
        <GridCellDefault
            label="Cell content"
            tabIndex={0}
            icon={<Mail />}
            href="http://www.planview.com"
        />
    )
    snapshot(
        'With numeric',
        <GridCellDefault label="1,000" tabIndex={0} numeric />
    )
    snapshot(
        'With numeric, left aligned',
        <GridCellDefault label="1,000" tabIndex={0} numeric align="left" />
    )
    snapshot(
        'With color',
        <GridCellDefault tabIndex={0} label="Cell content" color="red" />
    )
    snapshot(
        'With background color',
        <GridCellDefault
            tabIndex={0}
            label="Cell content"
            backgroundColor="red"
        />
    )

    describe('left content tooltip', () => {
        describe('with a badge', () => {
            describe('with tooltip content provided', () => {
                it('should show the tooltip on hover', async () => {
                    const { getByText, findByRole } = render(
                        <GridCellDefault
                            tabIndex={0}
                            badge="Long badge"
                            label="Cell content"
                            leftContentTooltip="Very nice"
                        />
                    )

                    await userEvent.hover(getByText('Long badge'))

                    expect(await findByRole('tooltip')).toHaveTextContent(
                        'Very nice'
                    )
                })
            })

            describe('without tooltip content provided', () => {
                it('should show the badge content when ellipsed', async () => {
                    jest.mocked(overflow.isEllipsisActive).mockReturnValue(true)

                    const { getByText, findByRole } = render(
                        <GridCellDefault
                            tabIndex={0}
                            badge="Long badge"
                            label="Cell content"
                        />
                    )

                    await userEvent.hover(getByText('Long badge'))

                    expect(await findByRole('tooltip')).toHaveTextContent(
                        'Long badge'
                    )
                })

                it('should not show a tooltip when not ellipsed', async () => {
                    jest.mocked(overflow.isEllipsisActive).mockReturnValue(
                        false
                    )

                    const { getByText, findByRole } = render(
                        <GridCellDefault
                            tabIndex={0}
                            badge="Long badge"
                            label="Cell content"
                        />
                    )

                    await userEvent.hover(getByText('Long badge'))

                    await expect(async () => {
                        await findByRole('tooltip', {}, { timeout: 300 })
                    }).rejects.toThrow(/Unable to find role="tooltip"/)
                })
            })
        })
    })

    describe('link', () => {
        it('should call onLinkClick when the link is clicked', async () => {
            const onLinkClick = jest.fn()
            const { getByRole } = render(
                <GridCellDefault
                    label="Cell content"
                    tabIndex={0}
                    href={{
                        url: 'http://www.planview.com',
                        /* Keeps JSDOM from throwing navigation not implemented error */
                        preventNavigation: true,
                    }}
                    onLinkClick={onLinkClick}
                />
            )

            await userEvent.click(getByRole('link'))

            expect(onLinkClick).toHaveBeenCalledTimes(1)
        })

        it('should call href.onClick when the link is clicked', async () => {
            const onClick = jest.fn()
            const { getByRole } = render(
                <GridCellDefault
                    label="Cell content"
                    tabIndex={0}
                    href={{
                        url: 'http://www.planview.com',
                        /* Keeps JSDOM from throwing navigation not implemented error */
                        preventNavigation: true,
                        onClick: onClick,
                    }}
                />
            )

            await userEvent.click(getByRole('link'))

            expect(onClick).toHaveBeenCalledTimes(1)
        })

        it('should prefer href.onClick if both onClick and onLinkClick are passed', async () => {
            const onLinkClick = jest.fn()
            const onClick = jest.fn()
            const { getByRole } = render(
                <GridCellDefault
                    label="Cell content"
                    tabIndex={0}
                    href={{
                        url: 'http://www.planview.com',
                        /* Keeps JSDOM from throwing navigation not implemented error */
                        preventNavigation: true,
                        onClick: onClick,
                    }}
                    onLinkClick={onLinkClick}
                />
            )

            await userEvent.click(getByRole('link'))

            expect(onClick).toHaveBeenCalledTimes(1)
            expect(onLinkClick).not.toHaveBeenCalled()
        })
    })
})
