import CalculationWidgetContainer from '../CalculationWidget';

import {
    calculationResponse,
    clientResponse,
    configurationModesResponse,
    configurationResponse,
} from '../__mocks__/CalculationWidgetInitialState';

import configuratorReducer from 'App/Reducers/Configurator/Reducer';
import {
    RECEIVE_CALCULATION,
    RECEIVE_CLIENT_DATA,
    RECEIVE_CONFIGURATION,
    RECEIVE_DESIGNER_DATA,
} from 'App/Reducers/Configurator/Actions';
import designAreaReducer from 'App/Reducers/DesignArea/Reducer';
import uiReducer from 'App/Reducers/UI/Reducer';
import ServiceLocator from 'App/ServiceLocator';
import mountWithState from 'Utils/Test/mountWithState';
import { actionTypes as designAreaActionTypes } from 'App/Reducers/DesignArea/Actions';
import Switch from '@material-ui/core/Switch';
import Select from '@material-ui/core/Select';
import Button from '@material-ui/core/Button';

import configurationModeReducer from 'App/Reducers/ConfigurationMode/Reducer';

const createInitialState = () => ({
    configurator: configuratorReducer(),
    configurationMode: configurationModeReducer(),
    designArea: designAreaReducer(),
    ui: uiReducer(),
});

const fillData = state => {
    let configurator = configuratorReducer(state.configurator, {
        type: RECEIVE_CONFIGURATION,
        data: configurationResponse,
    });
    configurator = configuratorReducer(configurator, {
        type: RECEIVE_CLIENT_DATA,
        data: clientResponse,
    });
    configurator = configuratorReducer(configurator, {
        type: RECEIVE_CALCULATION,
        data: calculationResponse,
    });
    let designArea = designAreaReducer(state.designArea, {
        type: RECEIVE_DESIGNER_DATA,
        data: configurationModesResponse,
        globalState: state,
    });
    designArea = designAreaReducer(designArea, {
        type: designAreaActionTypes.SELECT_DESIGN_AREA,
        designAreaIdentifier: 'c_1',
    });
    return {
        ...state,
        configurator,
        designArea,
    };
};

describe('Screens/Configurator/Containers/CalculationWidget integration tests', () => {
    let designDataSrvc;
    let analyticsSrvc;
    let interactionSrvc;
    let configuratorSrvc;
    let mockSampleCanvasEditor;
    beforeEach(() => {
        configuratorSrvc = new (class {
            static serviceName = 'ConfiguratorService';
            setSelectedAmount = jest.fn();
            setSelectedCalculation = jest.fn();
            skipNextCalculationAutoResolve = jest.fn();
        })();
        const storeSrvc = new (class {
            static serviceName = 'StoreService';
            observeStore() {}

            get state() {
                return {
                    designArea: {
                        filteredDesignArea: [
                            {
                                identifier: 'design_area1',
                                designProductionMethods: [
                                    {
                                        identifier: 'production1',
                                    },
                                ],
                            },
                        ],
                    },
                };
            }
        })();
        mockSampleCanvasEditor = {
            setColorAmount: jest.fn(),
            toggleSampleText: jest.fn(),
        };
        designDataSrvc = new (class {
            static serviceName = 'DesignDataService';
            selectDesignArea = jest.fn();
            setDesignProductionMethod = jest.fn();
            getSampleCanvasEditorForDesignArea = jest.fn(() => mockSampleCanvasEditor);
        })();
        analyticsSrvc = new (class {
            static serviceName = 'AnalyticsService';
            triggerEvent = jest.fn();
        })();
        interactionSrvc = new (class {
            static serviceName = 'InteractionService';
            saveWidgetConfigurationAndOpenConfigurator = jest.fn();
            saveWidgetConfigurationAndOpenPdf = jest.fn();
            saveConfiguration = jest.fn();
        })();
        ServiceLocator.provide(storeSrvc);
        ServiceLocator.provide(configuratorSrvc);
        ServiceLocator.provide(designDataSrvc);
        ServiceLocator.provide(interactionSrvc);
        ServiceLocator.provide(analyticsSrvc);
    });
    test('onMount useEffect calls ToggleDesignArea if state has defaultDesignArea', () => {
        const defaultState = {
            configurator: {
                configuration: {
                    item: {
                        identifier: 'demo_pen',
                        configurationModes: [
                            {
                                identifier: 'creator',
                                itemStatus: { identifier: 'not_available', item_available: false },
                            },
                            {
                                identifier: 'designer',
                                itemStatus: { identifier: 'available', item_available: true },
                            },
                        ],
                        title: 'Demo Kugelschreiber',
                        abstract: '',
                        description: '',
                        attributes: [],
                        price: null,
                        netPrice: null,
                        stock: [],
                        itemGroup: {
                            identifier: 'color',
                            title: 'Farbe',
                            children: [
                                {
                                    identifier: 'S-012192103920',
                                    title: 'Demo Kugelschreiber Durchsichtig',
                                    children: null,
                                    itemgroupentryIdentifier: 'clear',
                                    itemgroupentryTitle: 'Durchsichtig',
                                },
                            ],
                        },
                        itemclassifications: [],
                    },
                    optionclassifications: [],
                    visualizationData: [],
                    designdata: {
                        a_1: {
                            canvasData: null,
                        },
                    },
                },
            },
            configurationMode: {
                selectedMode: null,
                availableModes: {},
            },
            designArea: {
                filteredDesignAreas: [
                    {
                        identifier: 'a_1',
                        designProductionMethods: [
                            {
                                identifier: 'dummy_method',
                                isDefault: true,
                            },
                            {
                                identifier: 'engraving_method',
                                isDefault: false,
                            },
                        ],
                    },
                    {
                        identifier: 'a_2',
                        designProductionMethods: [
                            {
                                identifier: 'dummy_method',
                                isDefault: false,
                            },
                            {
                                identifier: 'engraving_method',
                                isDefault: false,
                            },
                        ],
                    },
                ],
                selectedDesignArea: {},
            },
            ui: {
                backgroundWorkMap: {},
            },
        };
        const toggleDesignArea = jest.fn();
        mountWithState(CalculationWidgetContainer, defaultState, { toggleDesignArea });
        expect(toggleDesignArea).toHaveBeenCalledWith('a_1', true);
    });
    test('the widget renders the proper data', () => {
        const state = fillData(createInitialState());

        const { wrapper } = mountWithState(CalculationWidgetContainer, state);
        const switches = wrapper.find(Switch);
        expect(switches.get(0).props.checked).toBe(true);
        expect(switches.get(1).props.checked).toBe(true);
        expect(switches.get(2).props.checked).toBe(false);
        expect(switches.get(3).props.checked).toBe(false);
        expect(switches.get(4).props.checked).toBe(false);

        const c1ColorAmountSelect = wrapper.find(Select).get(5);
        expect(c1ColorAmountSelect.props.value).toBe(3);

        const c2Switch = switches.get(3);
        c2Switch.props.onChange({ target: { checked: true } });
        expect(designDataSrvc.getSampleCanvasEditorForDesignArea).toHaveBeenCalledWith('c_2');
        expect(mockSampleCanvasEditor.toggleSampleText).toHaveBeenCalledWith(true);

        const c2ColorAmountSelect = wrapper.find(Select).get(7);
        c2ColorAmountSelect.props.onChange({ target: { value: 2 } });
        expect(mockSampleCanvasEditor.setColorAmount).toHaveBeenCalledWith(2);

        const amountInput = wrapper.find('AmountInput').get(0);
        amountInput.props.onChange(9999);
        // if the calculation error is caused by changing the amount, the error has to be shown,
        // so the skipNextCalculationAutoResolve has to be called to disable auto resolving
        expect(configuratorSrvc.skipNextCalculationAutoResolve).toHaveBeenCalled();
        expect(configuratorSrvc.setSelectedAmount).toHaveBeenCalledWith(false, 9999);

        const priceListInput = wrapper.find('PriceList').get(0);
        priceListInput.props.onSelectableChanged('global_professional_filecheck', true);
        expect(configuratorSrvc.setSelectedCalculation).toHaveBeenCalledWith(
            'global_professional_filecheck',
            true
        );

        const printButton = wrapper.find(Button).get(0);
        printButton.props.onClick();
        expect(interactionSrvc.saveWidgetConfigurationAndOpenPdf).toHaveBeenCalled();

        const openButton = wrapper.find(Button).get(1);
        openButton.props.onClick();
        expect(interactionSrvc.saveWidgetConfigurationAndOpenConfigurator).toHaveBeenCalled();
    });
});
