import get from 'lodash/get';
import flow from 'lodash/flow';
import find from 'lodash/find';
import difference from 'lodash/difference';
import keys from 'lodash/keys';
import values from 'lodash/values';
import createSelector from '../../../Utils/Function/createSelector';
import { getSelectedConfigurationMode } from '../ConfigurationMode/Selectors';

export const getConfigurator = rootState => rootState.configurator;
export const getConfiguration = configuratorState => get(configuratorState, 'configuration');
export const getCalculation = configuratorState => get(configuratorState, 'calculation');
export const getSelectedVariantIdentifier = configuratorState =>
    get(configuratorState, 'selectedVariantIdentifier');
export const getClient = configuratorState => get(configuratorState, 'client');

export const getItem = createSelector(getConfiguration, configuration => get(configuration, 'item'));
export const getUserSelectedCalculation = createSelector(getConfiguration, configuration =>
    get(configuration, 'customdata.userSelectedCalculation')
);
export const getSelectedAmounts = createSelector(getConfiguration, configuration =>
    get(configuration, 'customdata.selectedAmounts')
);
export const getBulkNames = createSelector(
    getConfiguration,
    configuration => get(configuration, 'customdata.bulkNames') || []
);
export const getShareUrl = createSelector(
    getConfiguration,
    configuration => get(configuration, 'shareUrl', '') || ''
);

export const getChildren = createSelector(getItem, item => get(item, 'itemGroup.children') || []);
export const getItemSettings = createSelector(getItem, item => get(item, 'settings', {}));
export const getVisualizationSettings = createSelector(getItemSettings, settings => ({
    creator: get(settings, 'visualizationCreator'),
    designer: get(settings, 'visualizationDesigner'),
}));

export const findMaxChildrenCount = item => {
    const children = get(item, 'itemGroup.children') || [];
    return Math.max(children.length, children.length && findMaxChildrenCount(children[0]));
};

export const getCurrentVisualizationSettings = createSelector(
    flow(getConfigurator, getVisualizationSettings),
    getSelectedConfigurationMode,
    (visualizationSettings, configurationMode) => {
        return visualizationSettings[configurationMode] || 'default';
    }
);

export const visualizationModeCheck = flow(getCurrentVisualizationSettings, mode => ({
    is2D: () =>
        mode === '2dVariant' ||
        mode === '2dVariantOverlay' ||
        mode === '2dLayer' ||
        mode === '2d' ||
        mode === 'layer',
    is3D: () => mode === '3dVariant' || mode === '3dScene' || mode === '3d',
    is2DOverlay: () => mode === '2dVariantOverlay',
    isDefault: () => mode === 'default',
}));

export const isSelectedAmountsUpdated = configuratorState => {
    return get(configuratorState, 'selectedAmountsUpdated');
};

export const hasMultipleVariantsSelected = state => {
    const item = state.configuration.item;
    const selectedAmounts = getSelectedAmounts(state);
    const selectedVariantKeys = keys(selectedAmounts);
    // get the firstSelectedAmountVariant and compare remaining to firstSelectedAmountVariant identifiers
    if (selectedVariantKeys.length > 1) {
        const firstSelectedVariant = find(get(item, 'itemGroup.children'), {
            identifier: selectedVariantKeys[0],
        });
        if (!firstSelectedVariant) {
            return false;
        }
        if (!get(firstSelectedVariant, 'itemGroup.children')) {
            return true;
        }
        const multipleVariants = difference(
            keys(selectedAmounts),
            values(getDeepestChildIdentifiers(firstSelectedVariant))
        );
        if (multipleVariants.length > 0) {
            return true;
        }
    }
    return false;
};

export const getDeepestChildIdentifiers = item => {
    if (!item.itemGroup || !item.itemGroup.children) {
        return { [item.itemgroupentryIdentifier]: item.identifier };
    }

    let result = {};

    for (const child of item.itemGroup.children) {
        Object.assign(result, getDeepestChildIdentifiers(child));
    }

    return result;
};

export const getClientHighlightColor = state =>
    get(getClient(getConfigurator(state)), 'theme.highlightColor');

export const getClientTexts = configuratorState => get(getClient(configuratorState), 'texts') || {};

export const isCalculationAutoResolveEnabled = ({ calculationAutoResolve }) =>
    calculationAutoResolve === true;

export const isDesignerProductPreviewMode = (pathname = window.location.pathname) =>
    /\/designer-preview-widget\/?/.test(pathname);

export const getConfigurationSettings = createSelector(getConfiguration, configuration =>
    get(configuration, 'information.settings', {})
);
export const showItemIdentifier = createSelector(getConfigurationSettings, settings =>
    get(settings, 'show_item_identifier', false)
);

export const getCallToAction = createSelector(getItem, item => get(item, 'callToAction', 'addToBasket'));

export const showCallToAction = createSelector(getCallToAction, callToAction => callToAction !== 'none');

export const showReceiveOfferForm = createSelector(
    getCallToAction,
    callToAction => callToAction === 'requestOffer'
);

export const isFallbackVisualizationMode = state => 'fallback' === getCurrentVisualizationSettings(state);
