import React from 'react';
import { fireEvent, screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import { contractDetails as contract } from 'src/__fixtures__/graphql/contract-details';
import * as contractMutations from 'src/apollo/mutations/contract';
import {
    addContractSummaryNotesMessage,
    updateContractSummaryNotesMessage,
} from 'src/apollo/type-constants/contract';
import {
    ContractSummaryNotesForm,
    ContractSummaryNotesFormPropsTypes,
} from 'src/components/contract-summary-notes-form/contract-summary-notes-form';

describe('<ContractSummaryNotesForm />', () => {
    const render = (props: ContractSummaryNotesFormPropsTypes) =>
        renderInAppContext(<ContractSummaryNotesForm {...props} />);

    const updateContract = jest.fn().mockResolvedValue({
        data: { abacusUpdateContract: contract.abacusContract },
        loading: false,
    });
    beforeEach(() =>
        jest
            .spyOn(contractMutations, 'useUpdateContract')
            .mockReturnValue(updateContract)
    );
    afterEach(jest.restoreAllMocks);

    const props: ContractSummaryNotesFormPropsTypes = {
        contractName: 'Test contract',
        isSidecarOpen: true,
        onRequestCloseSidecar: jest.fn(),
        summaryNote: null,
    };

    it('renders sidecar with contract summary notes form', () => {
        render(props);

        expect(screen.getByTestId('ContractSummaryNotesSidecar')).toBeDefined();
    });

    it('renders contract summary notes form', () => {
        render(props);

        expect(screen.getByText('Contract Summary Notes')).toBeDefined();
        expect(screen.getByTestId('contractSummaryNotesInput')).toBeDefined();
    });

    it('disables the save button if the contract summary notes input is blank string', () => {
        render(props);

        const contractSummaryInput = screen.getByTestId(
            'contractSummaryNotesInput'
        );
        fireEvent.change(contractSummaryInput, { target: { value: '' } });

        const saveButton = screen.getByRole('button', { name: 'save' });
        expect(saveButton).toHaveProperty('disabled');
    });

    it('disables the save button if the contract summary notes input contains only spaces', () => {
        render(props);

        const contractSummaryInput = screen.getByTestId(
            'contractSummaryNotesInput'
        );
        fireEvent.change(contractSummaryInput, {
            target: { value: '       ' },
        });

        const saveButton = screen.getByRole('button', { name: 'save' });
        expect(saveButton).toHaveProperty('disabled');
    });

    it('renders a success toast popup on adding summary notes successfully', async () => {
        render(props);

        const contractSummaryInput = screen.getByTestId(
            'contractSummaryNotesInput'
        );
        fireEvent.change(contractSummaryInput, {
            target: { value: 'Test Summary' },
        });

        const saveButton = screen.getByRole('button', { name: 'save' });
        fireEvent.click(saveButton);

        const toast = await screen.findByTestId('Toast-0');
        expect(toast).toBeDefined();
        expect(toast).toHaveTextContent(
            addContractSummaryNotesMessage('Test contract')
        );
    });

    it('closes sidecar when isSidecarOpen is false', () => {
        render({ ...props, isSidecarOpen: false });
        expect(screen.queryByTestId('ContractSummaryNotesSidecar')).toBeNull();
    });

    it('renders contract summary notes if already exists', () => {
        render({ ...props, summaryNote: 'Test Summary Notes' });

        const contractSummaryNotesInput = screen.getByTestId(
            'contractSummaryNotesInput'
        );
        expect(contractSummaryNotesInput).toHaveTextContent(
            'Test Summary Notes'
        );
    });

    it('renders a success toast popup on updating summary notes successfully', async () => {
        render({ ...props, summaryNote: 'Test Summary Notes' });

        const contractSummaryInput = screen.getByTestId(
            'contractSummaryNotesInput'
        );
        fireEvent.change(contractSummaryInput, {
            target: { value: 'Test Contract Summary Notes' },
        });

        const saveButton = screen.getByRole('button', { name: 'save' });
        fireEvent.click(saveButton);

        const toast = await screen.findByTestId('Toast-0');
        expect(toast).toBeDefined();
        expect(toast).toHaveTextContent(
            updateContractSummaryNotesMessage('Test contract')
        );
    });
});
