import React from 'react';
import { render, screen } from '@testing-library/react';
import { ModalCustom, CLASSNAME } from '../modalCustom';
import { ModalContainer } from '../modalContainer';
import { ModalContent } from '../modalContent';
import { DEFAULT_MODAL_CLOSE_TIMEOUT_MS } from '../../../constants/closeTimeout';

vi.mock('../modalContainer', () => ({
    ModalContainer: vi.fn(({ children }) => <div data-testid="ModalContainer">{children}</div>),
}));

vi.mock('../modalContent', () => ({
    ModalContent: vi.fn(({ children }) => <div data-testid="ModalContent">{children}</div>),
}));

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

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

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

        expect(ModalContainer).toHaveBeenCalledTimes(1);
        expect(screen.getByTestId('ModalContainer')).toBeInTheDocument();
        expect(ModalContainer).toHaveBeenCalledWith(
            expect.objectContaining({
                testId: CLASSNAME,
                closeTimeoutMS: DEFAULT_MODAL_CLOSE_TIMEOUT_MS,
                zIndex: 1000,
                variant: 'Modal',
                onRequestClose,
            }),
            expect.any(Object)
        );
    });

    test('passes provided container props to <ModalContainer>', () => {
        const onRequestClose = vi.fn();

        render(
            <ModalCustom
                isOpen
                testId="CustomTestId"
                closeTimeoutMS={300}
                zIndex={2000}
                variant="Modal"
                onRequestClose={onRequestClose}
                className="CustomClass"
                portalClassName="CustomPortalClass"
                contentStyle={{ background: 'transparent' }}
            >
                Content
            </ModalCustom>
        );

        expect(ModalContainer).toHaveBeenCalledWith(
            expect.objectContaining({
                testId: 'CustomTestId',
                closeTimeoutMS: 300,
                zIndex: 2000,
                variant: 'Modal',
                onRequestClose,
                className: 'CustomClass',
                portalClassName: 'CustomPortalClass',
                contentStyle: { background: 'transparent' },
            }),
            expect.any(Object)
        );
    });

    test('renders <ModalContent> with correct props', () => {
        const onRequestClose = vi.fn();
        const onConfirm = vi.fn();

        render(
            <ModalCustom
                isOpen
                onRequestClose={onRequestClose}
                onConfirm={onConfirm}
                confirmTitle="Confirm"
                cancelTitle="Cancel"
                confirmDisabled
                confirmVariant="primary"
                header="Header"
                title="Title"
                subtitle="Subtitle"
                hideCancelButton
                confirmButtonProps={{ testId: 'confirm-btn' }}
                cancelButtonProps={{ testId: 'cancel-btn' }}
            >
                Content
            </ModalCustom>
        );

        expect(ModalContent).toHaveBeenCalledTimes(1);
        expect(screen.getByTestId('ModalContent')).toBeInTheDocument();
        expect(ModalContent).toHaveBeenCalledWith(
            expect.objectContaining({
                onRequestClose,
                onConfirm,
                confirmTitle: 'Confirm',
                cancelTitle: 'Cancel',
                confirmDisabled: true,
                confirmVariant: 'primary',
                header: 'Header',
                title: 'Title',
                subtitle: 'Subtitle',
                hideCancelButton: true,
                confirmButtonProps: { testId: 'confirm-btn' },
                cancelButtonProps: { testId: 'cancel-btn' },
            }),
            expect.any(Object)
        );
    });

    test('passes customHeader and customFooter to <ModalContent>', () => {
        const customHeader = <div>Custom Header</div>;
        const customFooter = <div>Custom Footer</div>;

        render(
            <ModalCustom
                isOpen
                customHeader={customHeader}
                customFooter={customFooter}
                onRequestClose={onRequestClose}
            >
                Content
            </ModalCustom>
        );

        expect(ModalContent).toHaveBeenCalledWith(
            expect.objectContaining({
                customHeader: customHeader,
                customFooter: customFooter,
            }),
            expect.any(Object)
        );
    });

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

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