import React from 'react'
import { act, renderHook } from '@testing-library/react'
import { GridProvider } from '../context/grid-context'
import { useRangePaste } from './use-range-paste'
import type { GridRangeSelection, GridRowData } from '../types'
import type { UseGridReturn } from './use-grid'
import { createGrid } from './use-grid'

describe('useRangePaste', () => {
    let grid: UseGridReturn

    const mockContainer = document.createElement('div')
    const mockRange: GridRangeSelection<GridRowData> = {
        from: { rowId: 'row1', columnId: 'col1' },
        to: { rowId: 'row2', columnId: 'col2' },
    }
    const mockRangeData = {
        rowIds: ['row1', 'row2'],
        columnIds: ['col1', 'col2'],
    }
    const mockOnBulkCellChange = jest.fn()

    beforeEach(() => {
        grid = createGrid()

        grid.dispatch({
            type: 'applyProps',
            payload: {
                actionsMenuPresent: false,
                columns: [
                    {
                        id: 'col1',
                        label: 'Column 1',
                        cell: {
                            editable: true,
                        },
                    },
                    {
                        id: 'col2',
                        label: 'Column 2',
                        cell: {
                            editable: true,
                        },
                    },
                ],
                rows: [
                    { id: 'row1', col1: 'R1C1', col2: 'R1C2' },
                    { id: 'row2', col1: 'R2C1', col2: 'R2C2' },
                ],
                footerEnabled: false,
                rowDrag: { enabled: false },
            },
        })

        jest.spyOn(grid.selectors, 'selectIsEditing').mockReturnValue(false)
        jest.spyOn(grid.selectors, 'selectRangeSelection').mockReturnValue(
            mockRange
        )
        jest.spyOn(grid.selectors, 'selectRangeIds').mockReturnValue(
            mockRangeData
        )
        jest.spyOn(grid.selectors, 'selectIsSpreadsheet').mockReturnValue(true)
        jest.spyOn(grid.selectors, 'selectCurrentFocus').mockReturnValue({
            area: 'body',
            rowId: 'row1',
            columnId: 'col1',
            subFocus: 'first',
        })

        jest.spyOn(grid.api.rangeSelection, 'select').mockImplementation()
        jest.spyOn(grid.api.focus, 'set').mockImplementation()

        mockOnBulkCellChange.mockReset().mockReturnValue(true)
    })

    it('should return undefined when not a spreadsheet', () => {
        jest.mocked(grid.selectors.selectIsSpreadsheet).mockReturnValue(false)

        const { result } = renderHook(
            () => useRangePaste(mockOnBulkCellChange, mockContainer),
            {
                wrapper: ({ children }) => (
                    <GridProvider {...grid}>{children}</GridProvider>
                ),
            }
        )

        expect(result.current).toBeUndefined()
    })

    it('should return undefined when onBulkCellChange is not provided', () => {
        const { result } = renderHook(
            () => useRangePaste(undefined, mockContainer),
            {
                wrapper: ({ children }) => (
                    <GridProvider {...grid}>{children}</GridProvider>
                ),
            }
        )

        expect(result.current).toBeUndefined()
    })

    it('should return handlePaste function when is a spreadsheet and onBulkCellChange is provided', () => {
        const { result } = renderHook(
            () => useRangePaste(mockOnBulkCellChange, mockContainer),
            {
                wrapper: ({ children }) => (
                    <GridProvider {...grid}>{children}</GridProvider>
                ),
            }
        )

        expect(result.current).toBeInstanceOf(Function)
    })

    it('handlePaste should do nothing when there is no range selection', () => {
        jest.mocked(grid.selectors.selectRangeSelection).mockReturnValue(null)

        const { result } = renderHook(
            () => useRangePaste(mockOnBulkCellChange, mockContainer),
            {
                wrapper: ({ children }) => (
                    <GridProvider {...grid}>{children}</GridProvider>
                ),
            }
        )

        const mockEvent = {
            preventDefault: jest.fn(),
            clipboardData: {
                getData: jest.fn(),
            },
        } as unknown as React.ClipboardEvent

        act(() => {
            result.current?.(mockEvent)
        })

        expect(mockEvent.preventDefault).not.toHaveBeenCalled()
        expect(mockOnBulkCellChange).not.toHaveBeenCalled()
    })

    it('handlePaste should do nothing when no clipboard data is available', () => {
        const { result } = renderHook(
            () => useRangePaste(mockOnBulkCellChange, mockContainer),
            {
                wrapper: ({ children }) => (
                    <GridProvider {...grid}>{children}</GridProvider>
                ),
            }
        )

        const mockEvent = {
            preventDefault: jest.fn(),
            clipboardData: {
                getData: jest.fn().mockReturnValue(''),
            },
        } as unknown as React.ClipboardEvent

        act(() => {
            result.current?.(mockEvent)
        })

        expect(mockEvent.preventDefault).toHaveBeenCalled()
        expect(mockOnBulkCellChange).not.toHaveBeenCalled()
    })

    it('handlePaste should do nothing if the grid is currently in editing mode', () => {
        jest.spyOn(grid.selectors, 'selectIsEditing').mockReturnValue(true)
        const { result } = renderHook(
            () => useRangePaste(mockOnBulkCellChange, mockContainer),
            {
                wrapper: ({ children }) => (
                    <GridProvider {...grid}>{children}</GridProvider>
                ),
            }
        )

        const mockEvent = {
            preventDefault: jest.fn(),
            clipboardData: {
                getData: jest.fn((type) => {
                    if (type === 'text/plain') {
                        return 'newValue1\tnewValue2\nnewValue3\tnewValue4'
                    }
                    return ''
                }),
            },
        } as unknown as React.ClipboardEvent

        act(() => {
            result.current?.(mockEvent)
        })

        expect(mockEvent.preventDefault).not.toHaveBeenCalled()
        expect(mockOnBulkCellChange).not.toHaveBeenCalled()
    })

    it('handlePaste should process plain text data', () => {
        const { result } = renderHook(
            () => useRangePaste(mockOnBulkCellChange, mockContainer),
            {
                wrapper: ({ children }) => (
                    <GridProvider {...grid}>{children}</GridProvider>
                ),
            }
        )

        const mockEvent = {
            preventDefault: jest.fn(),
            clipboardData: {
                getData: jest.fn((type) => {
                    if (type === 'text/plain') {
                        return 'newValue1\tnewValue2\nnewValue3\tnewValue4'
                    }
                    return ''
                }),
            },
        } as unknown as React.ClipboardEvent

        act(() => {
            result.current?.(mockEvent)
        })

        expect(mockEvent.preventDefault).toHaveBeenCalled()
        expect(mockOnBulkCellChange).toHaveBeenCalledWith(
            new Map([
                [
                    'row1',
                    [
                        {
                            rowId: 'row1',
                            columnId: 'col1',
                            nextValue: 'newValue1',
                            previousValue: 'R1C1',
                        },
                        {
                            rowId: 'row1',
                            columnId: 'col2',
                            nextValue: 'newValue2',
                            previousValue: 'R1C2',
                        },
                    ],
                ],
                [
                    'row2',
                    [
                        {
                            rowId: 'row2',
                            columnId: 'col1',
                            nextValue: 'newValue3',
                            previousValue: 'R2C1',
                        },
                        {
                            rowId: 'row2',
                            columnId: 'col2',
                            nextValue: 'newValue4',
                            previousValue: 'R2C2',
                        },
                    ],
                ],
            ])
        )

        expect(mockContainer).toHaveAttribute(
            'data-pvds-grid-range-pasted',
            'true'
        )
    })

    it('handlePaste should process HTML table data', () => {
        const { result } = renderHook(
            () => useRangePaste(mockOnBulkCellChange, mockContainer),
            {
                wrapper: ({ children }) => (
                    <GridProvider {...grid}>{children}</GridProvider>
                ),
            }
        )

        const htmlTable = `
            <table>
                <thead>
                    <tr>
                        <th></th>
                        <th>Header 1</th>
                        <th>Header 2</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <th scope="row">Row header</th>
                        <td>htmlValue1</td>
                        <td>htmlValue2</td>
                    </tr>
                    <tr>
                        <th scope="row">Row header</th>
                        <td>htmlValue3</td>
                        <td>htmlValue4</td>
                    </tr>
                </tbody>
            </table>
        `

        const mockEvent = {
            preventDefault: jest.fn(),
            clipboardData: {
                getData: jest.fn((type) => {
                    if (type === 'text/html') {
                        return htmlTable
                    }
                    return ''
                }),
            },
        } as unknown as React.ClipboardEvent

        act(() => {
            result.current?.(mockEvent)
        })

        expect(mockEvent.preventDefault).toHaveBeenCalled()
        expect(mockOnBulkCellChange).toHaveBeenCalledWith(
            new Map([
                [
                    'row1',
                    [
                        {
                            rowId: 'row1',
                            columnId: 'col1',
                            nextValue: 'htmlValue1',
                            previousValue: 'R1C1',
                        },
                        {
                            rowId: 'row1',
                            columnId: 'col2',
                            nextValue: 'htmlValue2',
                            previousValue: 'R1C2',
                        },
                    ],
                ],
                [
                    'row2',
                    [
                        {
                            rowId: 'row2',
                            columnId: 'col1',
                            nextValue: 'htmlValue3',
                            previousValue: 'R2C1',
                        },
                        {
                            rowId: 'row2',
                            columnId: 'col2',
                            nextValue: 'htmlValue4',
                            previousValue: 'R2C2',
                        },
                    ],
                ],
            ])
        )
    })

    it('handlePaste should process custom data format', () => {
        const { result } = renderHook(
            () => useRangePaste(mockOnBulkCellChange, mockContainer),
            {
                wrapper: ({ children }) => (
                    <GridProvider {...grid}>{children}</GridProvider>
                ),
            }
        )

        const customData = JSON.stringify([
            {
                rowId: 'customRow1',
                values: {
                    col1: { label: 'Custom1', value: 'customValue1' },
                    col2: { label: 'Custom2', value: 'customValue2' },
                },
            },
            {
                rowId: 'customRow2',
                values: {
                    col1: { label: 'Custom3', value: 'customValue3' },
                    col2: { label: 'Custom4', value: 'customValue4' },
                },
            },
        ])

        const mockEvent = {
            preventDefault: jest.fn(),
            clipboardData: {
                getData: jest.fn((type) => {
                    if (type === 'application/x-pvds-grid') {
                        return customData
                    }
                    return ''
                }),
            },
        } as unknown as React.ClipboardEvent

        act(() => {
            result.current?.(mockEvent)
        })

        expect(mockEvent.preventDefault).toHaveBeenCalled()
        expect(mockOnBulkCellChange).toHaveBeenCalledWith(
            new Map([
                [
                    'row1',
                    [
                        {
                            rowId: 'row1',
                            columnId: 'col1',
                            nextValue: 'customValue1',
                            previousValue: 'R1C1',
                        },
                        {
                            rowId: 'row1',
                            columnId: 'col2',
                            nextValue: 'customValue2',
                            previousValue: 'R1C2',
                        },
                    ],
                ],
                [
                    'row2',
                    [
                        {
                            rowId: 'row2',
                            columnId: 'col1',
                            nextValue: 'customValue3',
                            previousValue: 'R2C1',
                        },
                        {
                            rowId: 'row2',
                            columnId: 'col2',
                            nextValue: 'customValue4',
                            previousValue: 'R2C2',
                        },
                    ],
                ],
            ])
        )
    })

    it('should respect if cell can be edited when processing paste data', () => {
        grid.dispatch({
            type: 'applyProps',
            payload: {
                actionsMenuPresent: false,
                columns: [
                    {
                        id: 'col1',
                        label: 'Column 1',
                        cell: {
                            editable: true,
                        },
                    },
                    {
                        id: 'col2',
                        label: 'Column 2',
                        cell: {
                            editable: false,
                        },
                    },
                ],
                rows: [
                    { id: 'row1', col1: 'R1C1', col2: 'R1C2' },
                    { id: 'row2', col1: 'R2C1', col2: 'R2C2' },
                ],
                footerEnabled: false,
                rowDrag: { enabled: false },
            },
        })

        const { result } = renderHook(
            () => useRangePaste(mockOnBulkCellChange, mockContainer),
            {
                wrapper: ({ children }) => (
                    <GridProvider {...grid}>{children}</GridProvider>
                ),
            }
        )

        const mockEvent = {
            preventDefault: jest.fn(),
            clipboardData: {
                getData: jest.fn((type) => {
                    if (type === 'text/plain') {
                        return 'newValue1\tnewValue2\nnewValue3\tnewValue4'
                    }
                    return ''
                }),
            },
        } as unknown as React.ClipboardEvent

        act(() => {
            result.current?.(mockEvent)
        })

        expect(mockOnBulkCellChange).toHaveBeenCalledWith(
            new Map([
                [
                    'row1',
                    [
                        {
                            rowId: 'row1',
                            columnId: 'col1',
                            nextValue: 'newValue1',
                            previousValue: 'R1C1',
                        },
                    ],
                ],
                [
                    'row2',
                    [
                        {
                            rowId: 'row2',
                            columnId: 'col1',
                            nextValue: 'newValue3',
                            previousValue: 'R2C1',
                        },
                    ],
                ],
            ])
        )
    })

    describe('column spanning', () => {
        describe('when the clipboard has colspan, but the target cells do not', () => {
            it('should handle colspan in pasted data', () => {
                const { result } = renderHook(
                    () => useRangePaste(mockOnBulkCellChange, mockContainer),
                    {
                        wrapper: ({ children }) => (
                            <GridProvider {...grid}>{children}</GridProvider>
                        ),
                    }
                )

                const customData = JSON.stringify([
                    {
                        rowId: 'customRow1',
                        values: {
                            col1: {
                                label: 'Custom1',
                                value: 'customValue1',
                                colSpan: 2,
                            },
                        },
                    },
                    {
                        rowId: 'customRow2',
                        values: {
                            col1: { label: 'Custom3', value: 'customValue3' },
                            col2: { label: 'Custom4', value: 'customValue4' },
                        },
                    },
                ])

                const mockEvent = {
                    preventDefault: jest.fn(),
                    clipboardData: {
                        getData: jest.fn((type) => {
                            if (type === 'application/x-pvds-grid') {
                                return customData
                            }
                            return ''
                        }),
                    },
                } as unknown as React.ClipboardEvent

                act(() => {
                    result.current?.(mockEvent)
                })

                expect(mockOnBulkCellChange).toHaveBeenCalledWith(
                    new Map([
                        [
                            'row1',
                            [
                                {
                                    rowId: 'row1',
                                    columnId: 'col1',
                                    nextValue: 'customValue1',
                                    previousValue: 'R1C1',
                                },
                                {
                                    rowId: 'row1',
                                    columnId: 'col2',
                                    nextValue: '',
                                    previousValue: 'R1C2',
                                },
                            ],
                        ],
                        [
                            'row2',
                            [
                                {
                                    rowId: 'row2',
                                    columnId: 'col1',
                                    nextValue: 'customValue3',
                                    previousValue: 'R2C1',
                                },
                                {
                                    rowId: 'row2',
                                    columnId: 'col2',
                                    nextValue: 'customValue4',
                                    previousValue: 'R2C2',
                                },
                            ],
                        ],
                    ])
                )
            })

            it('should handle colspan in HTML table data', () => {
                const { result } = renderHook(
                    () => useRangePaste(mockOnBulkCellChange, mockContainer),
                    {
                        wrapper: ({ children }) => (
                            <GridProvider {...grid}>{children}</GridProvider>
                        ),
                    }
                )

                const htmlTable = `
                    <table>
                        <tbody>
                            <tr>
                                <td colspan="2">htmlValueWithColspan</td>
                            </tr>
                            <tr>
                                <td>htmlValue3</td>
                                <td>htmlValue4</td>
                            </tr>
                        </tbody>
                    </table>
                `

                const mockEvent = {
                    preventDefault: jest.fn(),
                    clipboardData: {
                        getData: jest.fn((type) => {
                            if (type === 'text/html') {
                                return htmlTable
                            }
                            return ''
                        }),
                    },
                } as unknown as React.ClipboardEvent

                act(() => {
                    result.current?.(mockEvent)
                })

                expect(mockEvent.preventDefault).toHaveBeenCalled()
                expect(mockOnBulkCellChange).toHaveBeenCalledWith(
                    new Map([
                        [
                            'row1',
                            [
                                {
                                    rowId: 'row1',
                                    columnId: 'col1',
                                    nextValue: 'htmlValueWithColspan',
                                    previousValue: 'R1C1',
                                },
                                {
                                    rowId: 'row1',
                                    columnId: 'col2',
                                    nextValue: '',
                                    previousValue: 'R1C2',
                                },
                            ],
                        ],
                        [
                            'row2',
                            [
                                {
                                    rowId: 'row2',
                                    columnId: 'col1',
                                    nextValue: 'htmlValue3',
                                    previousValue: 'R2C1',
                                },
                                {
                                    rowId: 'row2',
                                    columnId: 'col2',
                                    nextValue: 'htmlValue4',
                                    previousValue: 'R2C2',
                                },
                            ],
                        ],
                    ])
                )
            })
        })

        describe('when the clipboard does not have colspan, but the target cells do', () => {
            it('should skip over spanned cells', () => {
                grid.dispatch({
                    type: 'applyProps',
                    payload: {
                        actionsMenuPresent: false,
                        columns: [
                            {
                                id: 'col1',
                                label: 'Column 1',
                                cell: {
                                    editable: true,
                                },
                            },
                            {
                                id: 'col2',
                                label: 'Column 2',
                                cell: {
                                    editable: true,
                                    colSpan({ row }) {
                                        return row.id === 'row1'
                                            ? ['col2', 'col3']
                                            : ['col1', 'col2']
                                    },
                                },
                            },
                            {
                                id: 'col3',
                                label: 'Column 3',
                                cell: {
                                    editable: true,
                                },
                            },
                        ],
                        rows: [
                            {
                                id: 'row1',
                                col1: 'R1C1',
                                col2: 'R1C2',
                                col3: 'R1C3',
                            },
                            {
                                id: 'row2',
                                col1: 'R2C1',
                                col2: 'R2C2',
                                col3: 'R2C3',
                            },
                        ],
                        footerEnabled: false,
                        rowDrag: { enabled: false },
                    },
                })

                const { result } = renderHook(
                    () => useRangePaste(mockOnBulkCellChange, mockContainer),
                    {
                        wrapper: ({ children }) => (
                            <GridProvider {...grid}>{children}</GridProvider>
                        ),
                    }
                )

                const htmlTable = `
                    <table>
                        <tbody>
                            <tr>
                                <td>htmlValue1</td>
                                <td>htmlValue2</td>
                                <td>htmlValue3</td>
                            </tr>
                            <tr>
                                <td>htmlValue4</td>
                                <td>htmlValue5</td>
                                <td>htmlValue6</td>
                            </tr>
                        </tbody>
                    </table>
                `

                const mockEvent = {
                    preventDefault: jest.fn(),
                    clipboardData: {
                        getData: jest.fn((type) => {
                            if (type === 'text/html') {
                                return htmlTable
                            }
                            return ''
                        }),
                    },
                } as unknown as React.ClipboardEvent

                act(() => {
                    result.current?.(mockEvent)
                })

                expect(mockEvent.preventDefault).toHaveBeenCalled()
                expect(mockOnBulkCellChange).toHaveBeenCalledWith(
                    new Map([
                        [
                            'row1',
                            [
                                {
                                    rowId: 'row1',
                                    columnId: 'col1',
                                    nextValue: 'htmlValue1',
                                    previousValue: 'R1C1',
                                },
                                {
                                    rowId: 'row1',
                                    columnId: 'col2',
                                    nextValue: 'htmlValue2',
                                    previousValue: 'R1C2',
                                },
                            ],
                        ],
                        [
                            'row2',
                            [
                                {
                                    rowId: 'row2',
                                    columnId: 'col2',
                                    nextValue: 'htmlValue4',
                                    previousValue: 'R2C2',
                                },
                                {
                                    rowId: 'row2',
                                    columnId: 'col3',
                                    nextValue: 'htmlValue6',
                                    previousValue: 'R2C3',
                                },
                            ],
                        ],
                    ])
                )
            })
        })

        describe('when both the clipboard and target cells have colspan', () => {
            it('should properly paste spanned cells', () => {
                grid.dispatch({
                    type: 'applyProps',
                    payload: {
                        actionsMenuPresent: false,
                        columns: [
                            {
                                id: 'col1',
                                label: 'Column 1',
                                cell: {
                                    editable: true,
                                },
                            },
                            {
                                id: 'col2',
                                label: 'Column 2',
                                cell: {
                                    editable: true,
                                    colSpan({ row }) {
                                        return row.id === 'row1'
                                            ? ['col2', 'col3']
                                            : ['col1', 'col2']
                                    },
                                },
                            },
                            {
                                id: 'col3',
                                label: 'Column 3',
                                cell: {
                                    editable: true,
                                },
                            },
                        ],
                        rows: [
                            {
                                id: 'row1',
                                col1: 'R1C1',
                                col2: 'R1C2',
                                col3: 'R1C3',
                            },
                            {
                                id: 'row2',
                                col1: 'R2C1',
                                col2: 'R2C2',
                                col3: 'R2C3',
                            },
                        ],
                        footerEnabled: false,
                        rowDrag: { enabled: false },
                    },
                })

                const { result } = renderHook(
                    () => useRangePaste(mockOnBulkCellChange, mockContainer),
                    {
                        wrapper: ({ children }) => (
                            <GridProvider {...grid}>{children}</GridProvider>
                        ),
                    }
                )

                const htmlTable = `
                    <table>
                        <tbody>
                            <tr>
                                <td colSpan="2">htmlValue1</td>
                                <td>htmlValue3</td>
                            </tr>
                            <tr>
                                <td colSpan="2">htmlValue4</td>
                                <td>htmlValue6</td>
                            </tr>
                        </tbody>
                    </table>
                `

                const mockEvent = {
                    preventDefault: jest.fn(),
                    clipboardData: {
                        getData: jest.fn((type) => {
                            if (type === 'text/html') {
                                return htmlTable
                            }
                            return ''
                        }),
                    },
                } as unknown as React.ClipboardEvent

                act(() => {
                    result.current?.(mockEvent)
                })

                expect(mockEvent.preventDefault).toHaveBeenCalled()
                expect(mockOnBulkCellChange).toHaveBeenCalledWith(
                    new Map([
                        [
                            'row1',
                            [
                                {
                                    rowId: 'row1',
                                    columnId: 'col1',
                                    nextValue: 'htmlValue1',
                                    previousValue: 'R1C1',
                                },
                                {
                                    rowId: 'row1',
                                    columnId: 'col2',
                                    nextValue: '',
                                    previousValue: 'R1C2',
                                },
                            ],
                        ],
                        [
                            'row2',
                            [
                                {
                                    rowId: 'row2',
                                    columnId: 'col2',
                                    nextValue: 'htmlValue4',
                                    previousValue: 'R2C2',
                                },
                                {
                                    rowId: 'row2',
                                    columnId: 'col3',
                                    nextValue: 'htmlValue6',
                                    previousValue: 'R2C3',
                                },
                            ],
                        ],
                    ])
                )
            })
        })
    })

    it('should set error status when onBulkCellChange returns false', () => {
        mockOnBulkCellChange.mockReturnValue(false)

        const { result } = renderHook(
            () => useRangePaste(mockOnBulkCellChange, mockContainer),
            {
                wrapper: ({ children }) => (
                    <GridProvider {...grid}>{children}</GridProvider>
                ),
            }
        )

        const mockEvent = {
            preventDefault: jest.fn(),
            clipboardData: {
                getData: jest.fn((type) => {
                    if (type === 'text/plain') {
                        return 'newValue1\tnewValue2\nnewValue3\tnewValue4'
                    }
                    return ''
                }),
            },
        } as unknown as React.ClipboardEvent

        act(() => {
            result.current?.(mockEvent)
        })

        expect(mockContainer).toHaveAttribute(
            'data-pvds-grid-range-pasted',
            'error'
        )
        expect(grid.api.rangeSelection.select).not.toHaveBeenCalled()
        expect(grid.api.focus.set).not.toHaveBeenCalled()
    })

    it('should update focus if current focus differs from paste target', () => {
        jest.mocked(grid.selectors.selectCurrentFocus).mockReturnValue({
            area: 'header',
            rowId: 'row2',
            columnId: 'col2',
            subFocus: 'first',
        })

        const { result } = renderHook(
            () => useRangePaste(mockOnBulkCellChange, mockContainer),
            {
                wrapper: ({ children }) => (
                    <GridProvider {...grid}>{children}</GridProvider>
                ),
            }
        )

        const mockEvent = {
            preventDefault: jest.fn(),
            clipboardData: {
                getData: jest.fn((type) => {
                    if (type === 'text/plain') {
                        return 'newValue1\tnewValue2\nnewValue3\tnewValue4'
                    }
                    return ''
                }),
            },
        } as unknown as React.ClipboardEvent

        act(() => {
            result.current?.(mockEvent)
        })

        expect(grid.api.focus.set).toHaveBeenCalledWith(
            'row1',
            'col1',
            'body',
            'first'
        )
    })

    it('should remove attribute after animation duration', () => {
        jest.useFakeTimers()

        const { result } = renderHook(
            () => useRangePaste(mockOnBulkCellChange, mockContainer),
            {
                wrapper: ({ children }) => (
                    <GridProvider {...grid}>{children}</GridProvider>
                ),
            }
        )

        const mockEvent = {
            preventDefault: jest.fn(),
            clipboardData: {
                getData: jest.fn((type) => {
                    if (type === 'text/plain') {
                        return 'newValue1\tnewValue2\nnewValue3\tnewValue4'
                    }
                    return ''
                }),
            },
        } as unknown as React.ClipboardEvent

        act(() => {
            result.current?.(mockEvent)
        })

        expect(mockContainer).toHaveAttribute(
            'data-pvds-grid-range-pasted',
            'true'
        )

        act(() => {
            jest.advanceTimersByTime(300)
        })

        expect(mockContainer).not.toHaveAttribute('data-pvds-grid-range-pasted')

        jest.useRealTimers()
    })
})
