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 * as contractQuery from 'src/apollo/queries/contract';
import { GeneralNoteForm } from 'src/components/contract-notes-form/contract-general-note-form';
import type { GetContractQuery } from 'src/apollo/queries/contract/__generated__/get-contract';

jest.mock('react-router-dom', () => ({
    ...jest.requireActual('react-router-dom'),
    useParams: jest.fn().mockReturnValue({ contractId: 123 }),
}));

describe('<GeneralNoteForm>', () => {
    const updateContract = jest.fn().mockResolvedValue({
        data: { abacusUpdateContract: contract.abacusContract },
        loading: false,
    });
    let useContractSpy: any;

    const render = () => renderInAppContext(<GeneralNoteForm />);
    afterEach(jest.restoreAllMocks);

    beforeEach(() => {
        useContractSpy = jest
            .spyOn(contractQuery, 'useContract')
            .mockReturnValue({
                data: {
                    abacusContract: contract.abacusContract,
                } as GetContractQuery,
                error: undefined,
                loading: false,
            });
        jest.spyOn(contractMutations, 'useUpdateContract').mockReturnValue(
            updateContract
        );
    });

    it('renders', () => {
        render();

        expect(useContractSpy).toHaveBeenCalled();
        expect(screen.getByText('Notes')).toBeDefined();
        expect(screen.getByText('Save')).toBeDefined();
        expect(screen.getByText('Cancel')).toBeDefined();
    });

    it('displays save button for edit mode and triggers update method', () => {
        render();
        const saveButton = screen.getByRole('button', { name: 'Save' });
        expect(saveButton).toBeDefined();
        fireEvent.click(saveButton);
        expect(updateContract).toHaveBeenCalled();
    });
});
