import { vi } from 'vitest';
import React from 'react';
import { ColumnResize, ColumnResizeConsumer, } from './index';
import { act, render } from '../../utils/test-utils/react';
describe('ColumnResize', () => {
    let _columnResizeContext = null;
    const defaultColumns = [
        {
            title: 'col1',
            render: () => React.createElement(React.Fragment, null),
            resizeProps: { id: 'col1' },
            width: '100px',
        },
        {
            title: 'col2',
            render: () => React.createElement(React.Fragment, null),
            resizeProps: { id: 'col2' },
            width: 150,
        },
        {
            title: 'col3',
            render: () => React.createElement(React.Fragment, null),
            resizeProps: { id: 'col3' },
            width: '200px',
        },
    ];
    const renderColumnResize = (props) => {
        return render(React.createElement(ColumnResize, { ...props },
            React.createElement(ColumnResizeConsumer, null, columnResizeContext => {
                _columnResizeContext = columnResizeContext;
                return React.createElement("div", null);
            })));
    };
    afterEach(() => {
        _columnResizeContext = null;
    });
    describe('getEffectiveColumnWidth', () => {
        it('should return original width when table is not resizable', () => {
            renderColumnResize({
                columns: defaultColumns,
                isTableResizable: false,
            });
            const result = _columnResizeContext?.getEffectiveColumnWidth(defaultColumns[0]);
            expect(result).toBe('100px');
        });
        it('should return resized width when table is resizable and column has been resized', async () => {
            renderColumnResize({
                columns: defaultColumns,
                isTableResizable: true,
            });
            await act(async () => {
                _columnResizeContext?.resizeColumn('col1', 150);
            });
            const result = _columnResizeContext?.getEffectiveColumnWidth(defaultColumns[0]);
            expect(result).toBe(150);
        });
        it('should return parseFloat of original width for columns without stored width', () => {
            const column = {
                title: 'new-col',
                render: () => React.createElement(React.Fragment, null),
                width: '175px',
                resizeProps: { id: 'new-col' },
            };
            renderColumnResize({
                columns: defaultColumns,
                isTableResizable: true,
            });
            const result = _columnResizeContext?.getEffectiveColumnWidth(column);
            expect(result).toBe(175);
        });
    });
    describe('Column Width Clamping', () => {
        let onColumnResizeMock;
        beforeEach(() => {
            onColumnResizeMock = vi.fn();
        });
        afterEach(() => {
            vi.clearAllMocks();
        });
        it('should clamp width to minimum value', async () => {
            renderColumnResize({
                columns: defaultColumns,
                isTableResizable: true,
                minColumnWidth: 80,
                onColumnResize: onColumnResizeMock,
            });
            await act(async () => {
                _columnResizeContext?.resizeColumn('col1', 50);
            });
            expect(_columnResizeContext?.columnWidths?.col1).toBe(80);
            expect(onColumnResizeMock).toHaveBeenCalledWith('col1', 80);
        });
        it('should clamp width to maximum value', async () => {
            renderColumnResize({
                columns: defaultColumns,
                isTableResizable: true,
                maxColumnWidth: 300,
                onColumnResize: onColumnResizeMock,
            });
            await act(async () => {
                _columnResizeContext?.resizeColumn('col1', 400);
            });
            expect(_columnResizeContext?.columnWidths?.col1).toBe(300);
            expect(onColumnResizeMock).toHaveBeenCalledWith('col1', 300);
        });
        it('should allow width within min-max range', async () => {
            renderColumnResize({
                columns: defaultColumns,
                isTableResizable: true,
                minColumnWidth: 50,
                maxColumnWidth: 300,
                onColumnResize: onColumnResizeMock,
            });
            await act(async () => {
                _columnResizeContext?.resizeColumn('col1', 150);
            });
            expect(_columnResizeContext?.columnWidths?.col1).toBe(150);
            expect(onColumnResizeMock).toHaveBeenCalledWith('col1', 150);
        });
        it('should handle only minimum constraint', async () => {
            renderColumnResize({
                columns: defaultColumns,
                isTableResizable: true,
                minColumnWidth: 75,
                onColumnResize: onColumnResizeMock,
            });
            await act(async () => {
                _columnResizeContext?.resizeColumn('col1', 60);
            });
            await act(async () => {
                _columnResizeContext?.resizeColumn('col2', 500);
            });
            expect(_columnResizeContext?.columnWidths?.col1).toBe(75);
            expect(_columnResizeContext?.columnWidths?.col2).toBe(500);
        });
    });
    describe('onColumnResize callback', () => {
        let onColumnResizeMock;
        beforeEach(() => {
            onColumnResizeMock = vi.fn();
        });
        afterEach(() => {
            vi.clearAllMocks();
        });
        it('should call onColumnResize with correct parameters', async () => {
            renderColumnResize({
                columns: defaultColumns,
                isTableResizable: true,
                onColumnResize: onColumnResizeMock,
            });
            await act(async () => {
                _columnResizeContext?.resizeColumn('col1', 175);
            });
            expect(onColumnResizeMock).toHaveBeenCalledWith('col1', 175);
            expect(onColumnResizeMock).toHaveBeenCalledTimes(1);
        });
        it('should not call onColumnResize when table is not resizable', async () => {
            renderColumnResize({
                columns: defaultColumns,
                isTableResizable: false,
                onColumnResize: onColumnResizeMock,
            });
            await act(async () => {
                _columnResizeContext?.resizeColumn('col1', 175);
            });
            expect(onColumnResizeMock).not.toHaveBeenCalled();
        });
    });
    describe('onColumnResizeStart callback', () => {
        let onColumnResizeStartMock;
        beforeEach(() => {
            onColumnResizeStartMock = vi.fn();
        });
        afterEach(() => {
            vi.clearAllMocks();
        });
        it('should call onColumnResizeStart with correct parameters', async () => {
            renderColumnResize({
                columns: defaultColumns,
                isTableResizable: true,
                onColumnResizeStart: onColumnResizeStartMock,
            });
            await act(async () => {
                _columnResizeContext?.resizeColumn('col1', 150);
            });
            const mockEvent = new MouseEvent('mousedown');
            await act(async () => {
                _columnResizeContext?.startColumnResize('col1', mockEvent);
            });
            expect(onColumnResizeStartMock).toHaveBeenCalledWith('col1', 150, mockEvent);
            expect(onColumnResizeStartMock).toHaveBeenCalledTimes(1);
        });
        it('should not call onColumnResizeStart when no callback provided', async () => {
            renderColumnResize({
                columns: defaultColumns,
                isTableResizable: true,
            });
            await act(async () => {
                _columnResizeContext?.resizeColumn('col1', 150);
            });
            const mockEvent = new MouseEvent('mousedown');
            await act(async () => {
                _columnResizeContext?.startColumnResize('col1', mockEvent);
            });
            expect(true).toBe(true);
        });
    });
    describe('onColumnResizeEnd callback', () => {
        let onColumnResizeEndMock;
        beforeEach(() => {
            onColumnResizeEndMock = vi.fn();
        });
        afterEach(() => {
            vi.clearAllMocks();
        });
        it('should call onColumnResizeEnd with correct parameters', async () => {
            renderColumnResize({
                columns: defaultColumns,
                isTableResizable: true,
                onColumnResizeEnd: onColumnResizeEndMock,
            });
            await act(async () => {
                _columnResizeContext?.resizeColumn('col1', 200);
            });
            const mockEvent = new MouseEvent('mouseup');
            await act(async () => {
                _columnResizeContext?.endColumnResize('col1', mockEvent);
            });
            expect(onColumnResizeEndMock).toHaveBeenCalledWith('col1', 200, mockEvent);
            expect(onColumnResizeEndMock).toHaveBeenCalledTimes(1);
        });
        it('should not call onColumnResizeEnd when no callback provided', async () => {
            renderColumnResize({
                columns: defaultColumns,
                isTableResizable: true,
            });
            await act(async () => {
                _columnResizeContext?.resizeColumn('col1', 200);
            });
            const mockEvent = new MouseEvent('mouseup');
            await act(async () => {
                _columnResizeContext?.endColumnResize('col1', mockEvent);
            });
            expect(true).toBe(true);
        });
    });
    describe('Callback Integration', () => {
        let onColumnResizeMock;
        let onColumnResizeStartMock;
        let onColumnResizeEndMock;
        beforeEach(() => {
            onColumnResizeMock = vi.fn();
            onColumnResizeStartMock = vi.fn();
            onColumnResizeEndMock = vi.fn();
        });
        afterEach(() => {
            vi.clearAllMocks();
        });
        it('should call all resize callbacks in sequence', async () => {
            renderColumnResize({
                columns: defaultColumns,
                isTableResizable: true,
                onColumnResize: onColumnResizeMock,
                onColumnResizeStart: onColumnResizeStartMock,
                onColumnResizeEnd: onColumnResizeEndMock,
            });
            const mockStartEvent = new MouseEvent('mousedown');
            const mockEndEvent = new MouseEvent('mouseup');
            await act(async () => {
                _columnResizeContext?.startColumnResize('col1', mockStartEvent);
            });
            await act(async () => {
                _columnResizeContext?.resizeColumn('col1', 180);
            });
            await act(async () => {
                _columnResizeContext?.endColumnResize('col1', mockEndEvent);
            });
            expect(onColumnResizeStartMock).toHaveBeenCalledWith('col1', 100, mockStartEvent);
            expect(onColumnResizeMock).toHaveBeenCalledWith('col1', 180);
            expect(onColumnResizeEndMock).toHaveBeenCalledWith('col1', 180, mockEndEvent);
            expect(onColumnResizeStartMock).toHaveBeenCalledTimes(1);
            expect(onColumnResizeMock).toHaveBeenCalledTimes(1);
            expect(onColumnResizeEndMock).toHaveBeenCalledTimes(1);
        });
    });
});
//# sourceMappingURL=ColumnResize.spec.js.map