import React from 'react';
import { fireEvent, screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import NrContractTermsConditionsList from 'src/components/contract-terms-form-nr/nr-contract-terms-conditions-list';
import {
    ADD_CONTRACT_TERM_CONDITION,
    SET_DEFAULT_CONDITION,
} from 'src/constants';
import { ContractTermContext } from 'src/contexts/contract-term-context';
import { initialTermState } from 'src/reducers/contract-term/contract-term-reducer';

const componentInContext = (contextValues: any) => (
    <ContractTermContext.Provider value={contextValues}>
        <NrContractTermsConditionsList />
    </ContractTermContext.Provider>
);

describe('<NrContractTermsConditionsList>', () => {
    const conditionsList = [
        {
            contractTermConditionName: 'Test Condition Name',
            conditions: {
                transactionTypes: [],
                stores: [],
                countries: [],
            },
            priority: 1,
            commission: '15.15',
        },
    ];
    const contractTermId = 123;

    afterEach(jest.restoreAllMocks);

    const render = (contextValues: any) =>
        renderInAppContext(componentInContext(contextValues));

    it('Adds a term condition upon adding the first schedule', () => {
        const dispatch = jest.fn();
        const stateWithConditions = {
            ...initialTermState,
            scheduleIds: [1],
            conditions: [],
        };
        const contextValues = { state: stateWithConditions, dispatch };
        render(contextValues);
        expect(dispatch).toHaveBeenCalledWith({ type: SET_DEFAULT_CONDITION });
    });

    it('renders rows of term condition forms with preloaded data when present', () => {
        const stateWithConditions = {
            ...initialTermState,
            conditions: conditionsList,
        };
        const contextValues = {
            state: stateWithConditions,
            dispatch: jest.fn(),
        };
        render(contextValues);
        expect(
            screen.getByDisplayValue(conditionsList[0].commission)
        ).toBeDefined();
    });

    it('renders draggable rows of term condition when there is more than one condition', () => {
        const secondCondition = { ...conditionsList[0], priority: 2 };
        const conditions = [...conditionsList, secondCondition];
        const stateWithConditions = { ...initialTermState, conditions };
        const contextValues = {
            state: stateWithConditions,
            dispatch: jest.fn(),
        };
        render(contextValues);
        expect(
            screen.getAllByTestId('contractTermConditionRow').length
        ).toEqual(conditions.length);
    });

    it('adds an empty contract term condition form when "+ NEW TERM LINE" is clicked', () => {
        const dispatch = jest.fn();
        const stateWithConditions = {
            ...initialTermState,
            conditions: conditionsList,
            contractTermId,
        };
        const contextValues = { state: stateWithConditions, dispatch };
        render(contextValues);

        const addTermLineBtn = screen.getByRole('button', {
            name: '+ NEW TERM LINE',
        });
        fireEvent.click(addTermLineBtn);

        const newCondition = {
            contractTermId,
            priority: conditionsList.length + 1,
        };

        expect(dispatch).toHaveBeenCalledWith({
            type: ADD_CONTRACT_TERM_CONDITION,
            condition: newCondition,
        });
    });
});
