import React, { ReducerState, ReducerAction } from 'react';
import { fireEvent, screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import ContractTermsDistroConditionsList from 'src/components/contract-terms-distro/contract-terms-distro-conditions-list';
import { ADD_CONTRACT_TERM_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: {
    state: ReducerState<any>;
    dispatch: ReducerAction<any>;
}) => (
    <ContractTermContext.Provider value={contextValues}>
        <ContractTermsDistroConditionsList />
    </ContractTermContext.Provider>
);

describe('<ContractTermsDistroConditionsList>', () => {
    const conditionsList = [
        {
            contractTermConditionId: 100,
            conditions: {
                transactionTypes: [],
                stores: [],
                countries: [],
            },
            priority: 1,
            termRate: '15.15',
        },
    ];
    const contractTermId = 123;

    const stores = [
        { label: '121 Music', value: 1 },
        { label: 'Spotify', value: 2 },
    ];

    const transactionTypes = [
        { label: 'Ad-Disabled Video Streams', value: 'VU' },
        { label: 'Cloud Match Units', value: 'CL' },
    ];

    afterEach(jest.restoreAllMocks);

    const render = (contextValues: {
        state: ReducerState<any>;
        dispatch: ReducerAction<any>;
    }) => renderInAppContext(componentInContext(contextValues));

    it('renders rows of term condition forms with preloaded data when present', () => {
        const stateWithConditions = {
            ...initialTermState,
            conditions: conditionsList,
            stores,
            transactionTypes,
        };
        const contextValues = {
            state: stateWithConditions,
            dispatch: jest.fn(),
        };
        render(contextValues);
        expect(
            screen.getByDisplayValue(conditionsList[0].termRate)
        ).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 Condition" is clicked', () => {
        const dispatch = jest.fn();
        const stateWithConditions = {
            ...initialTermState,
            conditions: conditionsList,
            contractTermId,
            stores,
            transactionTypes,
        };
        const contextValues = { state: stateWithConditions, dispatch };
        render(contextValues);

        const addTermLineBtn = screen.getByRole('button', {
            name: '+ New Condition',
        });
        fireEvent.click(addTermLineBtn);

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

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

    it('renders the "Copy Conditions From..." link button', () => {
        const contextValues = { state: initialTermState, dispatch: jest.fn() };
        render(contextValues);
        const copyConditionsBtn = screen.getByText('Copy Conditions From...');
        expect(copyConditionsBtn).toBeDefined();
    });

    it('opens the "Copy Conditions From..." popup when link button is clicked', () => {
        const contextValues = { state: initialTermState, dispatch: jest.fn() };
        render(contextValues);
        const copyConditionsBtn = screen.getByText('Copy Conditions From...');

        fireEvent.click(copyConditionsBtn);

        const popupHeader = screen.getByRole('heading', { level: 3 });
        const copyButton = screen.getByText('Copy');
        expect(popupHeader.textContent).toEqual('Copy Conditions From...');
        expect(copyButton).toBeDefined();
    });
});
