import { act, fireEvent, render } from '@testing-library/react';
import React from 'react';
import MarketingSectionOAPanel from '../marketing-section-oa-panel';
import type { MarketingSectionOAPanelProps } from '../marketing-section-oa-panel';

const graphqlState = {
    product: {
        marketingPriority: { internalNote: '', priorities: [] },
        marketingProgramInfos: [],
    },
    project: {
        productCount: 2,
        marketingPriority: { internalNote: '', priorities: [] },
        marketingProgramInfos: [],
        marketingHighlights: [],
    },
    territories: [],
};
const defaultProps: MarketingSectionOAPanelProps = {
    productId: '123',
    graphqlState,
    updateProductInternalNote: jest.fn(),
    updateProductMarketingPriorities: jest.fn(),
    updateProductMarketingProgramInfo: jest.fn(),
    updateProjectMarketingPriorities: jest.fn(),
    updateProjectMarketingHighlights: jest.fn(),
    toast: jest.fn(),
    loading: false,
    error: false,
    editable: true,
    onEdit: jest.fn(),
};

describe('<MarketingSectionOAPanel editable=true>', () => {
    const props: Partial<MarketingSectionOAPanelProps> = { editable: true };

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

    describe('Renders component', () => {
        test('Matches snapshot', () => {
            const { container } = renderWrapper(props);
            expect(container).toMatchSnapshot();
        });
    });
});

describe('<MarketingSectionOAPanel editable=false>', () => {
    const props: Partial<MarketingSectionOAPanelProps> = { editable: false };

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

    describe('Renders component', () => {
        test('Matches snapshot', () => {
            const { container } = renderWrapper(props);
            expect(container).toMatchSnapshot();
        });
    });
});

describe('Submit button', () => {
    describe('When clicked', () => {
        const updateProductInternalNote = jest.fn();
        const updateProductMarketingPriorities = jest.fn();
        const updateProductMarketingProgramInfo = jest.fn();
        const updateProjectMarketingPriorities = jest.fn();
        const updateProjectMarketingHighlights = jest.fn();

        const props: Partial<MarketingSectionOAPanelProps> = {
            editable: true,
            updateProductInternalNote,
            updateProductMarketingPriorities,
            updateProductMarketingProgramInfo,
            updateProjectMarketingPriorities,
            updateProjectMarketingHighlights,
        };

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

        test('Without changes does nothing', async () => {
            const { getByTestId } = renderWrapper(props);
            const button = getByTestId('submit-button');

            await act(async () => {
                await fireEvent.click(button);
            });

            expect(updateProductInternalNote).not.toHaveBeenCalled();
            expect(updateProductMarketingPriorities).not.toHaveBeenCalled();
            expect(updateProductMarketingProgramInfo).not.toHaveBeenCalled();
            expect(updateProjectMarketingPriorities).not.toHaveBeenCalled();
            expect(updateProjectMarketingHighlights).not.toHaveBeenCalled();
        });

        test('With changes makes the expected GraphQL calls', async () => {
            const updateProductInternalNote = jest.fn();
            const updateProjectMarketingHighlights = jest.fn();
            const updateProjectMarketingPriorities = jest
                .fn()
                .mockResolvedValue({
                    data: { updateProjectMarketingPriorities: [] },
                });

            const props: Partial<MarketingSectionOAPanelProps> = {
                editable: true,
                updateProductInternalNote,
                updateProjectMarketingPriorities,
                updateProjectMarketingHighlights,
            };

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

            const { getByTestId } = renderWrapper(props);
            const highlightsTextArea = getByTestId(
                'global-marketing-highlights-text-area'
            );
            const projectLevelRadioButon = getByTestId(
                'project-level-radio-button'
            );
            const internalNotesTextArea = getByTestId(
                'internal-notes-text-area'
            );
            const submitButton = getByTestId('submit-button');

            await act(async () => {
                await fireEvent.click(projectLevelRadioButon);
                await fireEvent.change(highlightsTextArea, {
                    target: { value: 'A' },
                });
                await fireEvent.change(internalNotesTextArea, {
                    target: { value: 'B' },
                });
                await fireEvent.click(submitButton);
            });

            expect(updateProductInternalNote).toHaveBeenCalled();
            expect(updateProjectMarketingPriorities).toHaveBeenCalled();
            expect(updateProjectMarketingHighlights).toHaveBeenCalled();
        });
    });
});
