import { act, fireEvent, render, screen, waitFor, within } from '@testing-library/react';
import { createRef, type FocusEvent as ReactFocusEvent, useState } from 'react';
import { describe, expect, it, vi } from 'vitest';
import { DatePicker } from '../../src/components/DatePicker';

type ControlledProps = {
    type: 'date' | 'time' | 'date-time';
    initialValue: string;
    format?: string;
    min?: string;
    max?: string;
    onValueChange?: (value: string) => void;
    onBlur?: (event: ReactFocusEvent<HTMLInputElement>) => void;
    disabled?: boolean;
};

function ControlledDatePicker({
    type,
    initialValue,
    format,
    min,
    max,
    onValueChange,
    onBlur,
    disabled = false,
}: Readonly<ControlledProps>) {
    const [value, setValue] = useState(initialValue);

    return (
        <DatePicker
            label="Schedule"
            type={type}
            value={value}
            format={format}
            min={min}
            max={max}
            disabled={disabled}
            onBlur={onBlur}
            onChange={(event) => {
                setValue(event.target.value);
                onValueChange?.(event.target.value);
            }}
        />
    );
}

function pickCurrentMonthDay(label: string): void {
    const dayButtons = Array.from(document.querySelectorAll('.datepicker-day')) as HTMLButtonElement[];
    const targetButton = dayButtons.find(
        (button) => button.textContent === label && !button.classList.contains('is-outside-month'),
    );

    expect(targetButton).toBeDefined();
    fireEvent.click(targetButton as HTMLButtonElement);
}

function getCurrentMonthDayButton(label: string): HTMLButtonElement {
    const dayButtons = Array.from(document.querySelectorAll('.datepicker-day')) as HTMLButtonElement[];
    const targetButton = dayButtons.find(
        (button) => button.textContent === label && !button.classList.contains('is-outside-month'),
    );

    if (!targetButton) {
        throw new Error(`Could not find day button for ${label}`);
    }

    return targetButton;
}

function createPasteEvent(text: string): Event {
    const event = new Event('paste', { bubbles: true, cancelable: true });
    Object.defineProperty(event, 'clipboardData', {
        value: {
            getData: () => text,
        },
    });
    return event;
}

function createRect(left: number, top: number, width: number, height: number): DOMRect {
    return {
        x: left,
        y: top,
        left,
        top,
        width,
        height,
        right: left + width,
        bottom: top + height,
        toJSON: () => ({}),
    } as DOMRect;
}

describe('DatePicker', () => {
    it('opens popup from icon button and closes with Escape', () => {
        render(<DatePicker label="Schedule" type="date-time" value="2031/05/20 14:30" onChange={() => {}} />);

        const input = screen.getByLabelText('Schedule') as HTMLInputElement;
        expect(input.type).toBe('text');

        fireEvent.click(screen.getByRole('button', { name: 'Open date picker' }));
        expect(
            screen.getByRole('dialog', { name: 'Date and time picker popup' }),
        ).toBeInTheDocument();

        fireEvent.keyDown(document, { key: 'Escape' });
        expect(
            screen.queryByRole('dialog', { name: 'Date and time picker popup' }),
        ).not.toBeInTheDocument();

        fireEvent.click(screen.getByRole('button', { name: 'Open date picker' }));
        fireEvent.click(screen.getByRole('button', { name: 'Close date picker' }));
        expect(
            screen.queryByRole('dialog', { name: 'Date and time picker popup' }),
        ).not.toBeInTheDocument();
    });

    it('supports segment-by-segment editing with custom format and auto-advance', async () => {
        const onValueChange = vi.fn();
        render(
            <ControlledDatePicker
                type="date-time"
                format="dd/mm/yyyy HH:mm"
                initialValue="22/02/2026 14:30"
                onValueChange={onValueChange}
            />, 
        );

        const input = screen.getByLabelText('Schedule') as HTMLInputElement;
        fireEvent.focus(input);

        await waitFor(() => {
            expect(input.selectionStart).toBe(0);
            expect(input.selectionEnd).toBe(2);
        });

        fireEvent.keyDown(input, { key: '1' });
        await waitFor(() => {
            expect(input.value).toBe('01/02/2026 14:30');
            expect(input.selectionStart).toBe(0);
            expect(input.selectionEnd).toBe(2);
        });
        fireEvent.keyDown(input, { key: '1' });
        await waitFor(() => {
            expect(input.value).toBe('11/02/2026 14:30');
            expect(input.selectionStart).toBe(3);
            expect(input.selectionEnd).toBe(5);
        });

        fireEvent.keyDown(input, { key: '0' });
        fireEvent.keyDown(input, { key: '3' });
        await waitFor(() => {
            expect(input.value).toBe('11/03/2026 14:30');
            expect(input.selectionStart).toBe(6);
            expect(input.selectionEnd).toBe(10);
        });

        fireEvent.keyDown(input, { key: '2' });
        fireEvent.keyDown(input, { key: '0' });
        fireEvent.keyDown(input, { key: '2' });
        fireEvent.keyDown(input, { key: '7' });
        await waitFor(() => {
            expect(input.value).toBe('11/03/2027 14:30');
            expect(input.selectionStart).toBe(11);
            expect(input.selectionEnd).toBe(13);
        });

        fireEvent.keyDown(input, { key: '1' });
        fireEvent.keyDown(input, { key: '6' });
        await waitFor(() => {
            expect(input.value).toBe('11/03/2027 16:30');
            expect(input.selectionStart).toBe(14);
            expect(input.selectionEnd).toBe(16);
        });

        fireEvent.keyDown(input, { key: '4' });
        fireEvent.keyDown(input, { key: '5' });
        await waitFor(() => {
            expect(input.value).toBe('11/03/2027 16:45');
        });

        expect(onValueChange).toHaveBeenCalled();
    });

    it('preserves year 0000 while editing and does not coerce to 19xx', async () => {
        render(
            <ControlledDatePicker
                type="date-time"
                format="dd/mm/yyyy HH:mm"
                initialValue="22/02/2026 14:30"
            />,
        );

        const input = screen.getByLabelText('Schedule') as HTMLInputElement;
        fireEvent.focus(input);

        await waitFor(() => {
            expect(input.selectionStart).toBe(0);
            expect(input.selectionEnd).toBe(2);
        });

        fireEvent.keyDown(input, { key: '/' });
        await waitFor(() => {
            expect(input.selectionStart).toBe(3);
            expect(input.selectionEnd).toBe(5);
        });

        fireEvent.keyDown(input, { key: '/' });
        await waitFor(() => {
            expect(input.selectionStart).toBe(6);
            expect(input.selectionEnd).toBe(10);
        });

        fireEvent.keyDown(input, { key: '0' });
        await waitFor(() => {
            expect(input.value).toBe('22/02/0000 14:30');
            expect(input.selectionStart).toBe(6);
            expect(input.selectionEnd).toBe(10);
        });

        fireEvent.keyDown(input, { key: '0' });
        fireEvent.keyDown(input, { key: '0' });
        fireEvent.keyDown(input, { key: '0' });
        await waitFor(() => {
            expect(input.value).toBe('22/02/0000 14:30');
            expect(input.selectionStart).toBe(11);
            expect(input.selectionEnd).toBe(13);
        });
    });

    it('uses separator keys to move between editable segments', async () => {
        render(
            <ControlledDatePicker
                type="date-time"
                format="dd/mm/yyyy HH:mm"
                initialValue="22/02/2026 14:30"
            />,
        );

        const input = screen.getByLabelText('Schedule') as HTMLInputElement;
        fireEvent.focus(input);

        await waitFor(() => {
            expect(input.selectionStart).toBe(0);
            expect(input.selectionEnd).toBe(2);
        });

        fireEvent.keyDown(input, { key: '/' });
        await waitFor(() => {
            expect(input.selectionStart).toBe(3);
            expect(input.selectionEnd).toBe(5);
        });

        fireEvent.keyDown(input, { key: '/' });
        await waitFor(() => {
            expect(input.selectionStart).toBe(6);
            expect(input.selectionEnd).toBe(10);
        });

        fireEvent.keyDown(input, { key: ' ' });
        await waitFor(() => {
            expect(input.selectionStart).toBe(11);
            expect(input.selectionEnd).toBe(13);
        });

        fireEvent.keyDown(input, { key: ':' });
        await waitFor(() => {
            expect(input.selectionStart).toBe(14);
            expect(input.selectionEnd).toBe(16);
        });
    });

    it('applies min/max constraints to calendar and time options', () => {
        render(
            <ControlledDatePicker
                type="date-time"
                initialValue="2026/03/10 10:00"
                min="2026/03/10 09:30"
                max="2026/03/10 10:15"
            />,
        );

        fireEvent.click(screen.getByRole('button', { name: 'Open date picker' }));

        expect(getCurrentMonthDayButton('9')).toBeDisabled();
        expect(getCurrentMonthDayButton('10')).toBeEnabled();
        expect(getCurrentMonthDayButton('11')).toBeDisabled();

        const hoursList = screen.getByRole('listbox', { name: 'Hours' });
        expect(within(hoursList).getByRole('button', { name: '08' })).toBeDisabled();
        expect(within(hoursList).getByRole('button', { name: '09' })).toBeEnabled();
        expect(within(hoursList).getByRole('button', { name: '10' })).toBeEnabled();
        expect(within(hoursList).getByRole('button', { name: '11' })).toBeDisabled();

        const minutesList = screen.getByRole('listbox', { name: 'Minutes' });
        expect(within(minutesList).getByRole('button', { name: '15' })).toBeEnabled();
        expect(within(minutesList).getByRole('button', { name: '20' })).toBeDisabled();
    });

    it('renders date mode calendar only and auto-closes after day selection', () => {
        const onValueChange = vi.fn();
        render(
            <ControlledDatePicker
                type="date"
                initialValue="2031/05/20"
                onValueChange={onValueChange}
            />,
        );

        fireEvent.click(screen.getByRole('button', { name: 'Open date picker' }));

        expect(screen.getByRole('dialog', { name: 'Date picker popup' })).toBeInTheDocument();
        expect(screen.queryByText('Hours')).not.toBeInTheDocument();
        expect(screen.queryByText('Minutes')).not.toBeInTheDocument();

        pickCurrentMonthDay('15');

        const input = screen.getByLabelText('Schedule') as HTMLInputElement;
        expect(input.value).toMatch(/^\d{4}\/\d{2}\/15$/);
        expect(onValueChange).toHaveBeenCalled();
        expect(screen.queryByRole('dialog', { name: 'Date picker popup' })).not.toBeInTheDocument();
    });

    it('commits calendar date changes in date-time mode without closing the popup', () => {
        const onValueChange = vi.fn();
        render(
            <ControlledDatePicker
                type="date-time"
                initialValue="2031/05/20 14:30"
                onValueChange={onValueChange}
            />,
        );

        fireEvent.click(screen.getByRole('button', { name: 'Open date picker' }));
        pickCurrentMonthDay('15');

        const input = screen.getByLabelText('Schedule') as HTMLInputElement;
        expect(input.value).toMatch(/^\d{4}\/\d{2}\/15 14:30$/);
        expect(onValueChange).toHaveBeenCalled();
        expect(screen.getByRole('dialog', { name: 'Date and time picker popup' })).toBeInTheDocument();
    });

    it('renders time mode selectors only and keeps popup open after selection', () => {
        const onValueChange = vi.fn();
        render(<ControlledDatePicker type="time" initialValue="09:00" onValueChange={onValueChange} />);

        fireEvent.click(screen.getByRole('button', { name: 'Open date picker' }));

        expect(screen.getByRole('dialog', { name: 'Time picker popup' })).toBeInTheDocument();
        expect(screen.queryByRole('grid')).not.toBeInTheDocument();

        const hoursList = screen.getByRole('listbox', { name: 'Hours' });
        const minutesList = screen.getByRole('listbox', { name: 'Minutes' });

        fireEvent.click(within(hoursList).getByRole('button', { name: '13' }));
        fireEvent.click(within(minutesList).getByRole('button', { name: '45' }));

        const input = screen.getByLabelText('Schedule') as HTMLInputElement;
        expect(input.value).toBe('13:45');
        expect(onValueChange).toHaveBeenCalledTimes(2);
        expect(screen.getByRole('dialog', { name: 'Time picker popup' })).toBeInTheDocument();
    });

    it('blocks popup interactions while disabled', () => {
        render(<ControlledDatePicker type="date" initialValue="2031/05/20" disabled />);

        const input = screen.getByLabelText('Schedule') as HTMLInputElement;
        const iconButton = screen.getByRole('button', { name: 'Open date picker' });

        expect(input).toBeDisabled();
        expect(iconButton).toBeDisabled();

        fireEvent.click(iconButton);

        expect(screen.queryByRole('dialog', { name: 'Date picker popup' })).not.toBeInTheDocument();
    });

    it('renders right icon and error message', () => {
        const { container } = render(
            <DatePicker
                label="Schedule"
                type="date-time"
                value="2031/05/20 14:30"
                onChange={() => {}}
                rightIcon={<span data-testid="right-icon">R</span>}
                error="Invalid date"
                inputClassName="custom-input"
            />,
        );

        const input = container.querySelector('input');
        expect(input).toBeInstanceOf(HTMLInputElement);
        expect(screen.getByTestId('right-icon')).toBeInTheDocument();
        expect(input).toHaveClass('pr-10');
        expect(input).toHaveClass('custom-input');
        expect(screen.getByText('Invalid date')).toBeInTheDocument();
    });

    it('forwards inputRef for callback and object refs', () => {
        const callbackRef = vi.fn();
        const objectRef = createRef<HTMLInputElement>();

        const { rerender } = render(
            <DatePicker
                label="Schedule"
                type="date-time"
                value="2031/05/20 14:30"
                onChange={() => {}}
                inputRef={callbackRef}
            />,
        );

        expect(callbackRef).toHaveBeenCalled();
        const callbackNode = callbackRef.mock.calls.find(([node]) => node instanceof HTMLInputElement)?.[0];
        expect(callbackNode).toBeInstanceOf(HTMLInputElement);

        rerender(
            <DatePicker
                label="Schedule"
                type="date-time"
                value="2031/05/20 14:30"
                onChange={() => {}}
                inputRef={objectRef}
            />,
        );

        expect(objectRef.current).toBeInstanceOf(HTMLInputElement);
    });

    it('supports inline layout', () => {
        const { container } = render(
            <DatePicker label="Start time" type="time" value="09:00" onChange={() => {}} layout="inline" />,
        );

        expect(container.querySelector('label')).toHaveClass('inline-flex');
        expect(container.querySelector('label > div')).not.toHaveClass('mt-1');
    });

    it('handles outside vs inside pointer interactions for popup close behavior', () => {
        render(<DatePicker label="Schedule" type="date-time" value="2031/05/20 14:30" onChange={() => {}} />);

        fireEvent.click(screen.getByRole('button', { name: 'Open date picker' }));
        const dialog = screen.getByRole('dialog', { name: 'Date and time picker popup' });

        fireEvent.mouseDown(dialog);
        expect(screen.getByRole('dialog', { name: 'Date and time picker popup' })).toBeInTheDocument();

        fireEvent.mouseDown(document.body);
        expect(
            screen.queryByRole('dialog', { name: 'Date and time picker popup' }),
        ).not.toBeInTheDocument();
    });

    it('supports month/year chooser interactions and month navigation buttons', async () => {
        render(<DatePicker label="Schedule" type="date" value="2031/05/20" onChange={() => {}} />);

        fireEvent.click(screen.getByRole('button', { name: 'Open date picker' }));

        fireEvent.click(screen.getByRole('button', { name: 'Previous month' }));
        fireEvent.click(screen.getByRole('button', { name: 'Next month' }));

        const chooserButtons = document.querySelectorAll('.datepicker-chooser-btn');
        const monthChooserButton = chooserButtons[0] as HTMLButtonElement;
        const yearChooserButton = chooserButtons[1] as HTMLButtonElement;

        const initialMonthText = monthChooserButton.textContent;
        fireEvent.click(monthChooserButton);
        const monthList = screen.getByRole('listbox', { name: 'Choose month' });
        const monthOptions = within(monthList).getAllByRole('button');
        const nextMonth = monthOptions.find((option) => option.textContent !== initialMonthText) ?? monthOptions[0];
        fireEvent.click(nextMonth);

        await waitFor(() => {
            expect(screen.queryByRole('listbox', { name: 'Choose month' })).not.toBeInTheDocument();
        });
        expect((document.querySelectorAll('.datepicker-chooser-btn')[0] as HTMLButtonElement).textContent).toBe(
            nextMonth.textContent,
        );

        const initialYearText = yearChooserButton.textContent;
        fireEvent.click(yearChooserButton);
        const yearList = screen.getByRole('listbox', { name: 'Choose year' });
        const yearOptions = within(yearList).getAllByRole('button');
        const nextYear = yearOptions.find((option) => option.textContent !== initialYearText) ?? yearOptions[0];
        fireEvent.click(nextYear);

        await waitFor(() => {
            expect(screen.queryByRole('listbox', { name: 'Choose year' })).not.toBeInTheDocument();
        });
        expect((document.querySelectorAll('.datepicker-chooser-btn')[1] as HTMLButtonElement).textContent).toBe(
            nextYear.textContent,
        );
    });

    it('guards month navigation at absolute calendar boundaries', () => {
        const first = render(
            <DatePicker label="Schedule" type="date" value="0000/01/15" onChange={() => {}} />,
        );

        fireEvent.click(screen.getByRole('button', { name: 'Open date picker' }));
        fireEvent.click(screen.getByRole('button', { name: 'Previous month' }));
        const lowerYearButton = document.querySelectorAll('.datepicker-chooser-btn')[1] as HTMLButtonElement;
        expect(lowerYearButton.textContent).toBe('0');

        first.unmount();

        render(<DatePicker label="Schedule" type="date" value="9999/12/15" onChange={() => {}} />);
        fireEvent.click(screen.getByRole('button', { name: 'Open date picker' }));
        fireEvent.click(screen.getByRole('button', { name: 'Next month' }));
        const upperYearButton = document.querySelectorAll('.datepicker-chooser-btn')[1] as HTMLButtonElement;
        expect(upperYearButton.textContent).toBe('9999');
    });

    it('supports keyboard navigation commands and segment reset shortcuts', async () => {
        const onBlur = vi.fn();
        render(
            <ControlledDatePicker
                type="date-time"
                format="dd/mm/yyyy HH:mm"
                initialValue="22/02/2026 14:30"
                onBlur={onBlur}
            />,
        );

        const input = screen.getByLabelText('Schedule') as HTMLInputElement;
        fireEvent.focus(input);

        await waitFor(() => {
            expect(input.selectionStart).toBe(0);
            expect(input.selectionEnd).toBe(2);
        });

        fireEvent.keyDown(input, { key: '1' });
        fireEvent.keyDown(input, { key: 'ArrowRight' });
        await waitFor(() => {
            expect(input.value.startsWith('01/')).toBe(true);
            expect(input.selectionStart).toBe(3);
        });

        fireEvent.mouseUp(input);
        fireEvent.click(input);

        fireEvent.keyDown(input, { key: 'ArrowDown' });
        expect(screen.getByRole('dialog', { name: 'Date and time picker popup' })).toBeInTheDocument();

        fireEvent.keyDown(input, { key: 'ArrowRight' });
        await waitFor(() => expect(input.selectionStart).toBe(3));

        fireEvent.keyDown(input, { key: 'ArrowLeft' });
        await waitFor(() => expect((input.selectionStart ?? 0) <= 3).toBe(true));

        fireEvent.keyDown(input, { key: 'Tab' });
        await waitFor(() => expect((input.selectionStart ?? 0) >= 0).toBe(true));

        fireEvent.keyDown(input, { key: 'Tab', shiftKey: true });
        await waitFor(() => expect((input.selectionStart ?? 0) >= 0).toBe(true));

        fireEvent.keyDown(input, { key: 'Backspace' });
        await waitFor(() => {
            expect(input.value.startsWith('01/')).toBe(true);
        });

        fireEvent.keyDown(input, { key: '/' });
        await waitFor(() => expect(input.selectionStart).toBe(3));
        fireEvent.keyDown(input, { key: 'Delete' });
        await waitFor(() => {
            expect(input.value.slice(3, 5)).toBe('01');
        });

        fireEvent.keyDown(input, { key: '/' });
        await waitFor(() => expect(input.selectionStart).toBe(6));
        fireEvent.keyDown(input, { key: 'Delete' });

        fireEvent.keyDown(input, { key: ' ' });
        fireEvent.keyDown(input, { key: 'Delete' });
        await waitFor(() => {
            expect(/\s00:|:00$/.test(input.value)).toBe(true);
        });

        fireEvent.keyDown(input, { key: 'Enter' });
        fireEvent.keyDown(input, { key: 'x' });
        fireEvent.blur(input);
        expect(onBlur).toHaveBeenCalledTimes(1);
    });

    it('handles paste validation and value commits', async () => {
        render(
            <ControlledDatePicker
                type="date-time"
                format="dd/mm/yyyy HH:mm"
                initialValue="22/02/2026 14:30"
            />,
        );

        const input = screen.getByLabelText('Schedule') as HTMLInputElement;

        await act(async () => {
            input.dispatchEvent(createPasteEvent('invalid value'));
        });
        expect(input.value).toBe('22/02/2026 14:30');

        await act(async () => {
            input.dispatchEvent(createPasteEvent('11/03/2027 16:45'));
        });
        expect(input.value).toBe('11/03/2027 16:45');
    });

    it('returns early from interaction handlers when disabled', () => {
        render(
            <DatePicker
                label="Schedule"
                type="date-time"
                format="dd/mm/yyyy HH:mm"
                value="22/02/2026 14:30"
                disabled
                onChange={() => {}}
            />,
        );

        const input = screen.getByLabelText('Schedule') as HTMLInputElement;

        fireEvent.focus(input);
        fireEvent.mouseUp(input);
        fireEvent.click(input);
        fireEvent.keyDown(input, { key: 'ArrowDown' });

        const disabledPaste = createPasteEvent('11/03/2027 16:45');
        input.dispatchEvent(disabledPaste);
        expect(disabledPaste.defaultPrevented).toBe(false);
        expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
    });

    it('falls back to direct assignment and synthetic onChange when native dispatch is stubbed', async () => {
        const onChange = vi.fn();
        const originalGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;

        render(
            <DatePicker
                label="Schedule"
                type="date-time"
                format="dd/mm/yyyy HH:mm"
                value="22/02/2026 14:30"
                onChange={onChange}
            />,
        );

        const input = screen.getByLabelText('Schedule') as HTMLInputElement;
        const nativeDispatchEvent = input.dispatchEvent.bind(input);
        vi.spyOn(input, 'dispatchEvent').mockImplementation((event: Event) => {
            if (event.type === 'change') {
                return true;
            }

            return nativeDispatchEvent(event);
        });
        vi.spyOn(Object, 'getOwnPropertyDescriptor').mockImplementation((target, property) => {
            if (target === HTMLInputElement.prototype && property === 'value') {
                return {
                    configurable: true,
                    enumerable: true,
                    get: originalGetOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.get,
                };
            }

            return originalGetOwnPropertyDescriptor(target, property);
        });

        fireEvent.focus(input);
        input.setSelectionRange(0, 2);
        fireEvent.keyDown(input, { key: '1' });

        await waitFor(() => {
            expect(onChange).toHaveBeenCalled();
        });
    });

    it('safely handles pending segment selection during unmount', () => {
        vi.useFakeTimers();

        const { unmount } = render(
            <DatePicker
                label="Schedule"
                type="date-time"
                format="dd/mm/yyyy HH:mm"
                value="22/02/2026 14:30"
                onChange={() => {}}
            />,
        );

        const input = screen.getByLabelText('Schedule') as HTMLInputElement;
        fireEvent.focus(input);
        unmount();

        expect(() => {
            vi.runAllTimers();
        }).not.toThrow();
    });

    it('recalculates popup position on window resize and scroll', async () => {
        const originalInnerWidth = Object.getOwnPropertyDescriptor(window, 'innerWidth');
        const originalInnerHeight = Object.getOwnPropertyDescriptor(window, 'innerHeight');
        const rectSpy = vi
            .spyOn(HTMLElement.prototype, 'getBoundingClientRect')
            .mockImplementation(function mockRect(this: HTMLElement) {
                if (this.classList.contains('datepicker-popup')) {
                    return createRect(0, 0, 300, 200);
                }
                if (this.classList.contains('relative') && this.querySelector('input')) {
                    return createRect(500, 80, 120, 40);
                }
                return createRect(0, 0, 100, 30);
            });

        Object.defineProperty(window, 'innerWidth', { configurable: true, value: 600 });
        Object.defineProperty(window, 'innerHeight', { configurable: true, value: 480 });

        render(<DatePicker label="Schedule" type="date-time" value="2031/05/20 14:30" onChange={() => {}} />);

        fireEvent.click(screen.getByRole('button', { name: 'Open date picker' }));
        const dialog = screen.getByRole('dialog', { name: 'Date and time picker popup' });
        expect(dialog).toBeInTheDocument();

        await waitFor(() => {
            expect(dialog.style.left).toBe('292px');
        });

        fireEvent(window, new Event('resize'));
        fireEvent(window, new Event('scroll'));
        expect(screen.getByRole('dialog', { name: 'Date and time picker popup' })).toBeInTheDocument();
        expect(dialog.style.left).toBe('292px');

        rectSpy.mockRestore();
        if (originalInnerWidth) {
            Object.defineProperty(window, 'innerWidth', originalInnerWidth);
        }
        if (originalInnerHeight) {
            Object.defineProperty(window, 'innerHeight', originalInnerHeight);
        }
    });
});
