import React from 'react';
import { render, screen } from '@testing-library/react';
import { ModalContainer, CLASSNAME } from '../modalContainer';
import ReactModal from 'react-modal';
import { usePageContext } from '../../../pageContext';
import { DEFAULT_MODAL_CLOSE_TIMEOUT_MS } from '../../../../constants/closeTimeout';

vi.mock('../../../pageContext');

vi.mock('react-modal', () => ({
    default: vi.fn(({ children }) => <div data-testid="ReactModal">{children}</div>),
}));

describe('<ModalContainer>', () => {
    const onRequestClose = vi.fn();

    beforeAll(() => {
        vi.mocked(usePageContext).mockReturnValue({ className: 'PageClass' });
    });

    afterEach(() => {
        vi.clearAllMocks();
    });

    test('renders <ReactModal> with correct default props', () => {
        render(
            <ModalContainer isOpen onRequestClose={onRequestClose}>
                Content
            </ModalContainer>
        );

        expect(ReactModal).toHaveBeenCalledTimes(1);
        expect(screen.getByTestId('ReactModal')).toBeInTheDocument();
        expect(ReactModal).toHaveBeenCalledWith(
            expect.objectContaining({
                contentLabel: 'Modal',
                ariaHideApp: false,
                bodyOpenClassName: 'ReactModal-body-open',
                closeTimeoutMS: DEFAULT_MODAL_CLOSE_TIMEOUT_MS,
                testId: CLASSNAME,
                onRequestClose: onRequestClose,
                className: 'Modal ReactModal',
            }),
            expect.any(Object)
        );
    });

    test('applies variant and custom className', () => {
        render(
            <ModalContainer
                isOpen
                onRequestClose={onRequestClose}
                className="CustomClass"
                variant="Modal"
            >
                Content
            </ModalContainer>
        );

        expect(ReactModal).toHaveBeenCalledWith(
            expect.objectContaining({
                className: 'CustomClass Modal ReactModal',
            }),
            expect.any(Object)
        );
    });

    test('sets portalClassName using page context and variant', () => {
        render(
            <ModalContainer isOpen onRequestClose={onRequestClose} variant="Modal">
                Content
            </ModalContainer>
        );

        expect(ReactModal).toHaveBeenCalledWith(
            expect.objectContaining({
                portalClassName: 'PageClass ReactModalPortal ReactModalPortal-Modal',
            }),
            expect.any(Object)
        );
    });

    test('merges custom portalClassName', () => {
        render(
            <ModalContainer isOpen onRequestClose={onRequestClose} portalClassName="CustomPortal">
                Content
            </ModalContainer>
        );

        expect(ReactModal).toHaveBeenCalledWith(
            expect.objectContaining({
                portalClassName: 'PageClass ReactModalPortal ReactModalPortal-Modal CustomPortal',
            }),
            expect.any(Object)
        );
    });

    test('passes correct overlay and content styles', () => {
        render(
            <ModalContainer
                isOpen
                onRequestClose={onRequestClose}
                zIndex={2000}
                contentStyle={{ padding: 20 }}
            >
                Content
            </ModalContainer>
        );

        expect(ReactModal).toHaveBeenCalledWith(
            expect.objectContaining({
                style: expect.objectContaining({
                    overlay: {
                        backgroundColor: 'rgba(0, 0, 0, 0.5)',
                        zIndex: 2000,
                    },
                    content: { padding: 20 },
                }),
            }),
            expect.any(Object)
        );
    });

    test('allows overriding closeTimeoutMS and testId', () => {
        render(
            <ModalContainer
                isOpen
                onRequestClose={onRequestClose}
                closeTimeoutMS={300}
                testId="CustomTestId"
            >
                Content
            </ModalContainer>
        );

        expect(ReactModal).toHaveBeenCalledWith(
            expect.objectContaining({
                closeTimeoutMS: 300,
                testId: 'CustomTestId',
            }),
            expect.any(Object)
        );
    });

    test('renders children inside <ReactModal>', () => {
        const { getByText } = render(
            <ModalContainer isOpen onRequestClose={onRequestClose}>
                <div>Inner Content</div>
            </ModalContainer>
        );

        expect(getByText('Inner Content')).toBeInTheDocument();
    });
});
