import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import { testComponent } from 'lib/test-utils/common';
import { Stepper, StepperProps } from '../stepper';

describe('<Stepper>', () => {
    const actionClickMock = vitest.fn();

    afterEach(() => {
        vitest.resetAllMocks();
    });

    const defaultProps: StepperProps = {
        steps: [
            {
                icon: {
                    number: 1,
                    variant: 'neutral',
                },
                title: 'SimpleStep',
            },
            {
                icon: {
                    glyphIcon: 'close',
                    variant: 'danger',
                },
                title: 'ComplexStepTitle',
                titleAction: {
                    label: 'Header Action',
                    size: 'sm',
                    variant: 'secondary',
                    onClick: actionClickMock,
                },
                description: <div>ComplexStepDescription</div>,
                body: <div>ComplexStepBody</div>,
                action: {
                    label: 'Step Action',
                    variant: 'tertiary',
                    onClick: actionClickMock,
                },
            },
        ],
    };

    const renderComponent = (customProps?: Partial<StepperProps>) => {
        const props = { ...defaultProps, ...customProps };

        return render(<Stepper {...props} />);
    };

    testComponent(Stepper, defaultProps);

    test('applies style', () => {
        const { getByTestId } = renderComponent({ style: { marginTop: 10 } });
        expect(getByTestId('Stepper')).toHaveStyle({ marginTop: '10px' });
    });

    test('renders each step horizontally by default', () => {
        const { getByTestId, getAllByTestId } = renderComponent();

        const stepper = getByTestId('Stepper');
        const steps = getAllByTestId('Stepper-Step');

        expect(stepper).toHaveClass('layout-horizontal');
        expect(steps).toHaveLength(2);
        expect(steps[0]).toHaveClass('horizontal');
    });

    test('renders each step vertically when applied prop', () => {
        const { getByTestId, getAllByTestId } = renderComponent({ layout: 'vertical' });

        const stepper = getByTestId('Stepper');
        const steps = getAllByTestId('Stepper-Step');
        const stepHeader = steps[0].querySelector('.Stepper-Step-header');

        expect(stepper).toHaveClass('layout-vertical');
        expect(steps).toHaveLength(2);
        expect(steps[0]).toHaveClass('vertical');
        expect(stepHeader).toHaveClass('vertical');
    });

    describe('Step', () => {
        test('renders step icon with number', () => {
            const { getAllByTestId } = renderComponent();

            const step = getAllByTestId('Stepper-Step').at(0)!;
            const icon = step.querySelector('.Stepper-Step-icon');

            expect(icon).toHaveClass('variant-neutral');
            expect(icon).toHaveTextContent('1');
        });

        test('renders step icon with glyph', () => {
            const { getByTestId, getAllByTestId } = renderComponent();

            const step = getAllByTestId('Stepper-Step').at(1)!;
            const icon = step.querySelector('.Stepper-Step-icon');
            const glyphIcon = getByTestId('CloseGlyphIcon');

            expect(icon).toHaveClass('variant-danger');
            expect(glyphIcon).toBeInTheDocument();
        });

        test('renders title', () => {
            const { getAllByTestId } = renderComponent();

            const step = getAllByTestId('Stepper-Step').at(0)!;
            const title = step.querySelector('.Stepper-Step-title-row .title');

            expect(title).toHaveTextContent('SimpleStep');
        });

        test('renders clickable title action', () => {
            const { getAllByTestId } = renderComponent();

            const step = getAllByTestId('Stepper-Step').at(1)!;
            const titleAction = step.querySelector('.Stepper-Step-title-row .title-action button');

            expect(titleAction).toHaveTextContent('Header Action');
        });

        test('renders description', () => {
            const { getAllByTestId } = renderComponent();

            const step = getAllByTestId('Stepper-Step').at(1)!;
            const description = step.querySelector('.Stepper-Step-description');

            expect(description).toHaveTextContent('ComplexStepDescription');
        });

        test('renders step body', () => {
            const { getAllByTestId } = renderComponent();

            const step = getAllByTestId('Stepper-Step').at(1)!;
            const body = step.querySelector('.Stepper-Step-body');

            expect(body).toHaveTextContent('ComplexStepBody');
        });

        test('renders clickable step action', () => {
            const { getAllByTestId } = renderComponent();

            const step = getAllByTestId('Stepper-Step').at(1)!;
            const actionBtn = step.querySelector('.Stepper-Step-action button');

            expect(actionBtn).toHaveTextContent('Step Action');

            fireEvent.click(actionBtn!);

            expect(actionClickMock).toHaveBeenCalled();
        });
    });
});
