import React, { useEffect } from 'react';
import PropTypes from 'prop-types';

import ReactComponentType from 'Shared/PropTypes/ReactComponent';

import DefaultLayout from './Layouts/DefaultLayout';
import Header from 'App/Shared/Containers/Header';
import { CreatorAlignTarget } from '../Visualization/CreatorAlignTarget';
import { Services } from 'App/ServiceLocator';
import * as configuratorActions from 'App/Reducers/Configurator/Actions';

import AmountPriceContainer from './Containers/AmountPrice';
import ConfigurationVariantSelectionContainer from './Containers/ConfigurationvariantSelection';
import CustomTitleEditorContainer from './Containers/CustomTitleEditor';
import IncompatibilityContainer from './Containers/Incompatibility';
import ErrorContainer from 'App/Shared/Containers/Error';
import FastConfigurationContainer from './Containers/FastConfiguration';
import OptionDetailContainer from './Containers/Optiondetail';
import OptionsListContainer from './Containers/OptionsList';
import ProductPartsListContainer from './Containers/ProductPartsList';
import InvalidConfigurationNotice from 'App/Shared/Containers/InvalidConfigurationNotice';
import FullScreenView from './Components/FullScreenView/FullScreenView';

import Option from './Components/Option';

export function CreatorScreen(props) {
    const {
        imageOnly,
        fallbackMode,
        isPortraitMode,
        showAddToCartButton,
        showConfigurationVariantSelection,
        vertical,
        fullScreenViewProps,

        configuration,

        _renderAmountPrice,
        _onToggleOptionList,

        renderConfigurationVariantSelection,
        renderCustomScreenComponents,
        renderCustomTitleEditorContainer,
        renderErrorContainer,
        renderFastConfigurationContainer,
        renderHeader,
        renderIncompatibilityDialog,
        renderInspirationsList,
        renderLoadConfiguration,
        renderLoader,
        renderOptionDetailContainer,
        renderOptionsList,
        renderPdfDownload,
        renderProductParts,
        renderSaveConfiguration,
        renderSendEmail,
        renderVisualization,
        renderLicenseNotice,
        renderInvalidConfigurationNotice,

        dispatchAction,
        onOptionClassificationSelect,
        onToggleOptionList,
        resolveConflicts,
        selectOption,
        selectOptionClassification,
        setVisible,
        viewOptionDetails,

        Layout,
        OptionsListContainer,
    } = props;

    useEffect(() => {
        setVisible('optionclassificationList', true);
        setVisible('addToCartButton', configuration.showAddToCartButton);

        if (!configuration.showInitialOptionClassification && configuration.showStartHere) {
            setVisible('startHere', true);
        }
    }, [
        configuration.showAddToCartButton,
        configuration.showInitialOptionClassification,
        configuration.showStartHere,
        setVisible,
    ]);

    return (
        <Layout
            imageOnly={imageOnly}
            displayVerticalList={vertical}
            fallbackMode={fallbackMode}
            isPortraitMode={isPortraitMode}
            renderHeader={renderHeader}
            renderInForeground={() => renderConfigurationVariantSelection(showConfigurationVariantSelection)}
            renderLoader={renderLoader}
            renderMain={() => (
                <>
                    {!fallbackMode && <CreatorAlignTarget />}
                    {renderSaveConfiguration()}
                    {renderSendEmail()}
                    {renderPdfDownload()}
                    {renderLoadConfiguration()}

                    {configuration.editCustomTitle ? renderCustomTitleEditorContainer() : null}

                    {renderCustomScreenComponents()}
                    {renderErrorContainer()}
                    {renderFastConfigurationContainer(
                        dispatchAction,
                        onOptionClassificationSelect,
                        selectOption,
                        selectOptionClassification
                    )}
                    {renderInspirationsList()}

                    {renderOptionsList(
                        selectOption,
                        dispatchAction,
                        viewOptionDetails,
                        _onToggleOptionList,
                        onToggleOptionList,
                        OptionsListContainer
                    )}
                    {renderOptionDetailContainer(selectOption, dispatchAction, viewOptionDetails)}
                    {renderIncompatibilityDialog(viewOptionDetails, resolveConflicts, dispatchAction)}
                </>
            )}
            renderProductsList={() =>
                renderProductParts(dispatchAction, onOptionClassificationSelect, selectOptionClassification)
            }
            renderShoppingCart={() => (showAddToCartButton ? _renderAmountPrice(props) : null)}
            renderVisualization={() =>
                renderVisualization({
                    fullScreenViewProps: {
                        showPreviewButton: !!fullScreenViewProps.showPreviewButton,
                        Component: FullScreenView,
                    },
                })
            }
            renderLicenseNotice={renderLicenseNotice}
            renderInvalidConfigurationNotice={renderInvalidConfigurationNotice}
        />
    );
}

CreatorScreen.propTypes = {
    fallbackMode: PropTypes.bool,
    isPortraitMode: PropTypes.bool,
    showAddToCartButton: PropTypes.bool,
    showConfigurationVariantSelection: PropTypes.bool,
    vertical: PropTypes.bool,

    configuration: PropTypes.object,

    _renderAmountPrice: PropTypes.func,
    _onToggleOptionList: PropTypes.func,

    renderVisualizationContainer: PropTypes.func,
    renderAmountPrice: PropTypes.func,
    renderConfigurationVariantSelection: PropTypes.func,
    renderCustomScreenComponents: PropTypes.func,
    renderCustomTitleEditorContainer: PropTypes.func,
    renderErrorContainer: PropTypes.func,
    renderFastConfigurationContainer: PropTypes.func,
    renderHeader: PropTypes.func,
    renderIncompatibilityDialog: PropTypes.func,
    renderInspirationsList: PropTypes.func,
    renderLoadConfiguration: PropTypes.func,
    renderLoader: PropTypes.func,
    renderOptionDetailContainer: PropTypes.func,
    renderOptionsList: PropTypes.func,
    renderPdfDownload: PropTypes.func,
    renderProductParts: PropTypes.func,
    renderSaveConfiguration: PropTypes.func,
    renderSendEmail: PropTypes.func,
    renderVisualization: PropTypes.func,
    renderLicenseNotice: PropTypes.func,
    renderInvalidConfigurationNotice: PropTypes.func,

    dispatchAction: PropTypes.func,
    onOptionClassificationSelect: PropTypes.func,
    onToggleOptionList: PropTypes.func,
    resolveConflicts: PropTypes.func,
    selectOption: PropTypes.func,
    selectOptionClassification: PropTypes.func,
    setVisible: PropTypes.func,
    viewOptionDetails: PropTypes.func,
    fullScreenViewProps: PropTypes.object,

    Layout: ReactComponentType.isRequired,
    OptionsListContainer: ReactComponentType,
    imageOnly: PropTypes.bool,
};

CreatorScreen.defaultProps = {
    fullScreenViewProps: { showPreviewButton: true },
    _renderAmountPrice: ({ renderAmountPrice, ...props }) =>
        renderAmountPrice({ AmountPriceContainer, ...props }),
    _onToggleOptionList: onToggleOptionList =>
        onToggleOptionList(Services.configurator.state.selectedoptionclassification),

    renderConfigurationVariantSelection: showConfigurationVariantSelection => {
        if (showConfigurationVariantSelection) {
            return <ConfigurationVariantSelectionContainer />;
        }

        return null;
    },
    renderCustomScreenComponents: () => null,
    renderCustomTitleEditorContainer: () => <CustomTitleEditorContainer />,
    renderErrorContainer: () => <ErrorContainer />,
    renderFastConfigurationContainer: (
        dispatchAction,
        onOptionClassificationSelect,
        selectOption,
        selectOptionClassification
    ) => (
        <FastConfigurationContainer
            onOptionclassificationSelect={(optionClassification, showOptionList) =>
                onOptionClassificationSelect(
                    dispatchAction,
                    optionClassification,
                    selectOptionClassification,
                    showOptionList
                )
            }
            onOptionSelect={option => selectOption(dispatchAction, option)}
        />
    ),
    renderHeader: () => <Header />,
    renderIncompatibilityDialog: (viewOptionDetails, resolveConflicts, dispatchAction) => (
        <IncompatibilityContainer
            ruleComponentProps={{
                Optionlistitem: Option,
                viewDetails: viewOptionDetails,
            }}
            resolveConflicts={() => resolveConflicts(dispatchAction)}
        />
    ),
    renderInspirationsList: () => null,
    renderOptionDetailContainer: (selectOption, dispatchAction, viewOptionDetails) => (
        <OptionDetailContainer
            onSelect={option => selectOption(dispatchAction, option)}
            viewDetails={option => viewOptionDetails(dispatchAction, option)}
        />
    ),
    renderOptionsList: (
        selectOption,
        dispatchAction,
        viewOptionDetails,
        onToggle,
        onToggleOptionList,
        OptionsListContainer
    ) => (
        <OptionsListContainer
            onSelect={option => selectOption(dispatchAction, option)}
            viewDetails={option => viewOptionDetails(dispatchAction, option)}
            onToggle={() => onToggle(onToggleOptionList)}
        />
    ),
    renderProductParts: (dispatchAction, onOptionClassificationSelect, selectOptionClassification) => (
        <ProductPartsListContainer
            onSelect={optionClassification =>
                onOptionClassificationSelect(dispatchAction, optionClassification, selectOptionClassification)
            }
        />
    ),
    renderInvalidConfigurationNotice: () => <InvalidConfigurationNotice />,

    onOptionClassificationSelect: (
        dispatchAction,
        optionClassification,
        selectOptionClassification,
        showOptionList = true
    ) => selectOptionClassification(dispatchAction, optionClassification, true, showOptionList),
    resolveConflicts: dispatchAction => dispatchAction(configuratorActions.resolveConflicts()),
    selectOption: (
        dispatchAction,
        option,
        refreshOptionList = true,
        showOptionDetails = false,
        optionClassification = false
    ) =>
        dispatchAction(
            configuratorActions.selectOption(
                option,
                refreshOptionList,
                showOptionDetails,
                optionClassification
            )
        ),
    selectOptionClassification: (
        dispatchAction,
        optionClassification = {},
        triggerFetchOptions = false,
        showOptionList = false
    ) =>
        dispatchAction(
            configuratorActions.selectOptionclassification(
                optionClassification,
                triggerFetchOptions,
                showOptionList
            )
        ),
    onToggleOptionList: () => {},
    viewOptionDetails: (dispatchAction, option) =>
        dispatchAction(configuratorActions.viewOptionDetails(option)),

    Layout: DefaultLayout,
    OptionsListContainer,
};
