import React from 'react';
import { fireEvent, screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import { referenceFlowthroughCalculation } from 'src/__fixtures__/graphql/reference-flowthrough-calculation';
import { referenceFlowthroughCalculations } from 'src/__fixtures__/graphql/reference-flowthrough-calculations';
import * as getReferenceFlowthroughCalculationQuery from 'src/apollo/queries/reference-flowthrough-calculation';
import { ContractFlowthroughCalculation } from '../contract-flowthrough-calculation';

describe('<ContractFlowthroughCalculation />', () => {
    const defaultProps = {
        abacusContractFlowthroughCalculationId: undefined as string | undefined,
        errors: {},
        handleFormChange: jest.fn(),
        setServerErrors: jest.fn(),
        serverErrors: {},
    };
    const render = (props = defaultProps) =>
        renderInAppContext(<ContractFlowthroughCalculation {...props} />);

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

        expect(screen.getByText('Calculation')).toBeInTheDocument();
    });

    it('renders with placeholder text when no calculation exists on the flowthrough configuration', () => {
        render();
        expect(screen.getByText('Select Calculation')).toBeInTheDocument();
    });

    it('renders calculation select field', () => {
        render();

        expect(
            screen.getByTestId('contractFlowthroughCalculation')
        ).toBeInTheDocument();
    });

    it('renders the calculation options from the reference flowthrough calculations', () => {
        jest.spyOn(
            getReferenceFlowthroughCalculationQuery,
            'useGetReferenceFlowthroughCalculations'
        ).mockReturnValue({
            data: {
                abacusReferenceFlowthroughCalculations: {
                    __typename: 'AbacusReferenceFlowthroughCalculationList',
                    totalCount:
                        referenceFlowthroughCalculations
                            ?.abacusReferenceFlowthroughCalculation
                            ?.totalCount || 0,
                    items: referenceFlowthroughCalculations.abacusReferenceFlowthroughCalculation.items.map(
                        item => ({
                            ...item,
                            __typename: 'AbacusReferenceFlowthroughCalculation',
                        })
                    ),
                },
            },
            loading: false,
            error: undefined,
        });
        render();
        const calculationSelect = screen.getByTestId('SuiteSelectInputValue');
        fireEvent.click(calculationSelect);
        expect(screen.getByText('Gross Revenue * FT%')).toBeInTheDocument();
        expect(screen.getByText('Net Revenue * FT%')).toBeInTheDocument();
        expect(
            screen.getByText('(Net Revenue - Expenses) * FT%')
        ).toBeInTheDocument();
        expect(
            screen.getByText('(Net Revenue * FT%) - Expenses')
        ).toBeInTheDocument();
    });

    it('renders calculation if one already exists on the flowthrough configuration', () => {
        jest.spyOn(
            getReferenceFlowthroughCalculationQuery,
            'useGetReferenceFlowthroughCalculations'
        ).mockReturnValue({
            data: {
                abacusReferenceFlowthroughCalculations: {
                    __typename: 'AbacusReferenceFlowthroughCalculationList',
                    totalCount:
                        referenceFlowthroughCalculations
                            ?.abacusReferenceFlowthroughCalculation
                            ?.totalCount || 0,
                    items: referenceFlowthroughCalculations.abacusReferenceFlowthroughCalculation.items.map(
                        item => ({
                            ...item,
                            __typename: 'AbacusReferenceFlowthroughCalculation',
                        })
                    ),
                },
            },
            loading: false,
            error: undefined,
        });
        render({
            ...defaultProps,
            abacusContractFlowthroughCalculationId:
                referenceFlowthroughCalculation
                    .abacusReferenceFlowthroughCalculation
                    .referenceFlowthroughCalculationId,
        });
        expect(
            screen.getByText(
                referenceFlowthroughCalculation
                    .abacusReferenceFlowthroughCalculation
                    .flowthroughCalculation
            )
        ).toBeInTheDocument();
    });

    it('renders the example and summary text when a calculation is selected', () => {
        jest.spyOn(
            getReferenceFlowthroughCalculationQuery,
            'useGetReferenceFlowthroughCalculations'
        ).mockReturnValue({
            data: {
                abacusReferenceFlowthroughCalculations: {
                    __typename: 'AbacusReferenceFlowthroughCalculationList',
                    totalCount:
                        referenceFlowthroughCalculations
                            ?.abacusReferenceFlowthroughCalculation
                            ?.totalCount || 0,
                    items: referenceFlowthroughCalculations.abacusReferenceFlowthroughCalculation.items.map(
                        item => ({
                            ...item,
                            __typename: 'AbacusReferenceFlowthroughCalculation',
                        })
                    ),
                },
            },
            loading: false,
            error: undefined,
        });
        render({
            ...defaultProps,
            abacusContractFlowthroughCalculationId:
                referenceFlowthroughCalculation
                    .abacusReferenceFlowthroughCalculation
                    .referenceFlowthroughCalculationId,
        });
        expect(
            screen.getByText(
                referenceFlowthroughCalculation
                    .abacusReferenceFlowthroughCalculation
                    .flowthroughCalculationExample
            )
        ).toBeInTheDocument();
        expect(
            screen.getByText(
                referenceFlowthroughCalculation
                    .abacusReferenceFlowthroughCalculation
                    .flowthroughCalculationExampleSummary
            )
        ).toBeInTheDocument();
    });

    it('renders error message when error prop is passed', () => {
        const errorMessage = 'Calculation is required';
        render({
            ...defaultProps,
            errors: { referenceFlowthroughCalculation: errorMessage },
        });

        expect(screen.getByText(errorMessage)).toBeInTheDocument();
    });
});
