import { fireEvent, render } from '@testing-library/react';
import OAPanel from '../oa-panel';
import type { OAPanelProps } from '../oa-panel';

describe('<OAPanel>', () => {
    const childrenTestId = 'children';
    const footerTestId = 'footer';

    const title = 'Orchard Admin';
    const children = <div data-testid={childrenTestId}>children!</div>;
    const footer = <div data-testid={footerTestId}>footer!</div>;

    const editable = true;

    const defaultProps: OAPanelProps = {
        title,
        children,
        editable,
        footer,
    };

    const renderWrapper = (props: Partial<OAPanelProps> = {}) =>
        render(<OAPanel {...defaultProps} {...props} />);

    describe('title', () => {
        test('renders value from title prop', () => {
            const { container } = renderWrapper();
            const [titleEl] = container.getElementsByClassName('OAPanel-title');
            expect(titleEl).toHaveTextContent(title);
        });
    });

    describe('loading true', () => {
        describe('children', () => {
            test('do not render', () => {
                const { queryByTestId } = renderWrapper({ loading: true });
                expect(queryByTestId(childrenTestId)).toBeNull();
            });
        });

        describe('footer', () => {
            test('does not render', () => {
                const { queryByTestId } = renderWrapper({ loading: true });
                expect(queryByTestId(footerTestId)).toBeNull();
            });
        });

        describe('<LoadingIndicator>', () => {
            test('visible', () => {
                const { container } = renderWrapper({ loading: true });
                const [loadingIndicator] =
                    container.getElementsByClassName('LoadingIndicator');
                expect(loadingIndicator).toBeVisible();
            });
        });
    });

    describe('error true', () => {
        describe('children', () => {
            test('do not render', () => {
                const { queryByTestId } = renderWrapper({ error: true });
                expect(queryByTestId(childrenTestId)).toBeNull();
            });
        });

        describe('footer', () => {
            test('does not render', () => {
                const { queryByTestId } = renderWrapper({ error: true });
                expect(queryByTestId(footerTestId)).toBeNull();
            });
        });

        describe('<ErrorMessage>', () => {
            test('visible', () => {
                const { container } = renderWrapper({ error: true });
                const [errorMessage] =
                    container.getElementsByClassName('ErrorMessage');
                expect(errorMessage).toBeVisible();
            });
        });
    });

    describe('not loading, no error', () => {
        describe('children', () => {
            test('render', () => {
                const { queryByTestId } = renderWrapper({
                    loading: false,
                    error: false,
                });
                expect(queryByTestId(childrenTestId)).toBeVisible();
            });
        });

        describe('footer', () => {
            test('renders', () => {
                const { queryByTestId } = renderWrapper({
                    loading: false,
                    error: false,
                });
                expect(queryByTestId(footerTestId)).toBeVisible();
            });
        });
    });

    describe('editable', () => {
        describe('true', () => {
            describe('<Button>', () => {
                test('does not render', () => {
                    const { container } = renderWrapper({ editable: true });
                    const [button] = container.getElementsByClassName('btn');
                    expect(button).toBeUndefined();
                });
            });
        });

        describe('false', () => {
            describe('<Button>', () => {
                test('renders', () => {
                    const { container } = renderWrapper({ editable: false });
                    const [button] = container.getElementsByClassName('btn');
                    expect(button).toBeVisible();
                });

                describe('clicked', () => {
                    test('calls onEdit callback', () => {
                        const onEdit = jest.fn();
                        const { container } = renderWrapper({
                            editable: false,
                            onEdit,
                        });
                        const [button] =
                            container.getElementsByClassName('btn');
                        fireEvent.click(button);
                        expect(onEdit).toHaveBeenCalled();
                    });
                });
            });
        });
    });
});
