import React from 'react';
import PropTypes from 'prop-types';
import DOMPurify from 'dompurify';
import './styles/FeatureDetails.scss';
import { createNamespace } from '../../tools/namingTools';
import Image from '../../atoms/image/Image';
import Icon from '../../atoms/icon/Icon';
import { DROPDOWN, TOGGLE, COLORPICKER, RADIO, SLIDER } from '../../constants/schemaComponentTypes';
import { CENTER, LEFT, RIGHT, ALTERNATING, TOP, BOTTOM } from '../../constants/alignment';
import { featuresPropTypes } from '../../constants/prop-types/application/features';
import { COL_ONE, COL_TWO } from '../../constants/columns';
import { FEATURE_BACKGROUND } from '../../constants/backgroundSettings';
import withListener from '../withListener';

const n = createNamespace('FeatureDetails');

export const BOX_SHADOW_DIMENSIONS = '0 5px 10px 5px';
const DEFAULT_BOX_SHADOW_COLOR = 'rgba(0, 0, 0, 0.1)';
const ALIGNMENT_OPTIONS = [LEFT, CENTER, RIGHT];
const IMAGE_POSITION_OPTIONS = [LEFT, RIGHT, ALTERNATING];
const IMAGE_POSITIONS_ONE_COL = [TOP, BOTTOM];
const COLUMN_COUNT = [COL_ONE, COL_TWO];

const SETTINGS = {
    columnCount: {
        title: 'uieditor.sfbComponent.featuredDetails.columnCount.title',
        type: RADIO,
        defaultValue: COLUMN_COUNT[1].value,
        options: COLUMN_COUNT
    },
    textAlignment: {
        title: 'uieditor.sfbComponent.featuredDetails.textAlignment.title',
        type: RADIO,
        defaultValue: ALIGNMENT_OPTIONS[0].value,
        options: ALIGNMENT_OPTIONS
    },
    textWidth: {
        title: 'uieditor.sfbComponent.featuredDetails.textWidth.title',
        type: SLIDER,
        defaultValue: 50,
        options: {
            range: true,
            step: 1,
            min: 33,
            max: 100
        }
    },
    isHighlightsCheckEnabled: {
        labelOn: 'uieditor.sfbComponent.featuredDetails.isHighlightsCheckEnabled.labelOn',
        labelOff: 'uieditor.sfbComponent.featuredDetails.isHighlightsCheckEnabled.labelOff',
        defaultValue: false,
        type: TOGGLE
    },
    imagePositionTwoCols: {
        title: 'uieditor.sfbComponent.featuredDetails.imagePositionTwoCols.title',
        type: DROPDOWN,
        defaultValue: IMAGE_POSITION_OPTIONS[2].value,
        options: IMAGE_POSITION_OPTIONS,
        conditionalAttributes: {
            isDisabled: {
                when: 'columnCount',
                connector: 'equals',
                value: COL_ONE.value
            }
        }
    },
    imagePositionOneCol: {
        title: 'uieditor.sfbComponent.featuredDetails.imagePositionOneCol.title',
        type: DROPDOWN,
        defaultValue: IMAGE_POSITIONS_ONE_COL[0].value,
        options: IMAGE_POSITIONS_ONE_COL,
        conditionalAttributes: {
            isDisabled: {
                when: 'columnCount',
                connector: 'equals',
                value: COL_TWO.value
            }
        }
    },
    enableImageShadow: {
        title: 'uieditor.sfbComponent.featuredDetails.enableImageShadow.title',
        type: TOGGLE,
        defaultValue: true,
        labelOn: 'uieditor.sfbComponent.featuredDetails.enableImageShadow.labelOn',
        labelOff: 'uieditor.sfbComponent.featuredDetails.enableImageShadow.labelOff'
    },
    imageShadowColor: {
        title: 'uieditor.sfbComponent.featuredDetails.imageShadowColor.title',
        type: COLORPICKER,
        defaultValue: DEFAULT_BOX_SHADOW_COLOR
    },
    alternatingBackground: {
        title: 'uieditor.sfbComponent.featuredDetails.alternatingBackground.title',
        type: COLORPICKER,
        defaultValue: FEATURE_BACKGROUND
    }
};

export const FeatureDetailsComponent = ({
    data: {
        features
    },
    settings
}) => {
    const settingsWithDefaults = { ...FeatureDetailsComponent.defaultProps.settings, ...settings };
    const { i18n = {}, items: featureItems } = features;

    if (!featureItems || !featureItems.length) {
        return null;
    }

    const i18nWithDefaults = { ...FeatureDetailsComponent.defaultProps.i18n, ...i18n };

    const {
        textAlignment,
        textWidth,
        isHighlightsCheckEnabled,
        imagePositionTwoCols,
        imagePositionOneCol,
        imageShadowColor,
        enableImageShadow,
        columnCount,
        alternatingBackground
    } = settingsWithDefaults;

    const cssVariables = {
        'text-align': textAlignment,
        'background-color': alternatingBackground
    };

    const boxShadow = `${BOX_SHADOW_DIMENSIONS} ${imageShadowColor}`;
    const getImagePosition = () => {
        if (columnCount === COL_ONE.value) {
            return imagePositionOneCol && `image-${imagePositionOneCol}`;
        }
        return imagePositionTwoCols && `image-${imagePositionTwoCols}`;
    };
    const containerModifiers = [
        getImagePosition(),
        textAlignment && `align-${textAlignment}`
    ];

    if (columnCount === COL_TWO.value) {
        containerModifiers.push('two-column');
    } else if (columnCount === COL_ONE.value) {
        containerModifiers.push('one-column');
    }

    const renderCharacteristics = characteristics => {
        if (!characteristics || !characteristics.length) {
            return null;
        }

        const getModifier = displayCheck => [displayCheck && isHighlightsCheckEnabled && 'with-icon'];

        return (
            <div {...n('characteristic').props}>
                {characteristics.map(characteristic => (
                    <div {...n('characteristicItem').props} key={characteristic.position}>
                        <h4 {...n('title').props}>{characteristic.title}</h4>
                        {characteristic.highlights.map(({ highlight, displayCheck }) => (
                            <span key={highlight} {...n('highlight_wrapper', getModifier(displayCheck)).withTestId().props}>
                                {Boolean(isHighlightsCheckEnabled && displayCheck) && <Icon type="check" {...n('icon', 'check').withTestId().props} />}
                                <div
                                    key={highlight}
                                    dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(highlight) }}
                                    {...n('description').props}
                                />
                            </span>
                        ))}
                    </div>
                ))}
            </div>
        );
    };

    const enableTextWidth = hasImage => (columnCount === COL_ONE.value || !hasImage);

    const renderFeature = ({
        id,
        label,
        description,
        imageUrl,
        aboveCharacteristics,
        belowCharacteristics
    }) => {
        const featureModifiers = [];
        const imageStyle = {};
        const featureStyles = {};

        if (imageUrl) {
            featureModifiers.push('with-image');
        }

        if (enableTextWidth(imageUrl)) {
            featureStyles['text-width'] = `${textWidth}%`;
        }

        if (enableImageShadow) {
            imageStyle.boxShadow = boxShadow;
        }

        return (
            <div {...n('container').withTestId().withE2EId().props} key={id}>
                <div {...n('content').props}>
                    <div {...n('row', featureModifiers).props}>
                        {imageUrl && (
                            <div {...n('imageContainer').withTestId().props}>
                                <Image
                                    {...n('image').withTestId().withE2EId().props}
                                    src={imageUrl}
                                    style={imageStyle}
                                    alt={label}
                                />
                            </div>
                        )}
                        <div {...n('feature', featureModifiers).withVariables(featureStyles).withTestId().props}>
                            <h3 {...n('title').withE2EId().props}>{label}</h3>
                            <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(description) }} {...n('description').withE2EId().props} />
                            {renderCharacteristics(aboveCharacteristics)}
                            {renderCharacteristics(belowCharacteristics)}
                        </div>
                    </div>
                </div>
            </div>
        );
    };

    return (
        <section {...n('wrapper', containerModifiers).withVariables(cssVariables).withTestId().props}>
            <h2 {...n('title', 'hidden').props}>{i18nWithDefaults.title}</h2>
            {featureItems.map(renderFeature)}
        </section>
    );
};

FeatureDetailsComponent.schema = () => ({
    name: 'FeatureDetails',
    title: 'uieditor.sfbComponent.featuredDetails.title',
    iconName: 'special',
    form: SETTINGS,
    marketplaceData: {
        features: 'application.features'
    },
    requiredDataFunc: ({ items }) => (items && items.length)
});

FeatureDetailsComponent.propTypes = {
    settings: PropTypes.shape({
        textWidth: PropTypes.number,
        textAlignment: PropTypes.oneOf([CENTER.value, LEFT.value, RIGHT.value]),
        isHighlightsCheckEnabled: PropTypes.bool,
        imageShadowColor: PropTypes.string,
        alternatingBackground: PropTypes.string,
        columnCount: PropTypes.oneOf([COL_ONE.value, COL_TWO.value]),
        imagePositionTwoCols: PropTypes.oneOf([LEFT.value, RIGHT.value, ALTERNATING.value]),
        imagePositionOneCol: PropTypes.oneOf(IMAGE_POSITIONS_ONE_COL.map(({ value }) => value)),
        enableImageShadow: PropTypes.bool
    }),
    data: PropTypes.shape(featuresPropTypes)
};

FeatureDetailsComponent.defaultProps = {
    settings: {
        textAlignment: SETTINGS.textAlignment.defaultValue,
        textWidth: SETTINGS.textWidth.defaultValue,
        isHighlightsCheckEnabled: SETTINGS.isHighlightsCheckEnabled.defaultValue,
        imagePositionTwoCols: SETTINGS.imagePositionTwoCols.defaultValue,
        imagePositionOneCol: SETTINGS.imagePositionOneCol.defaultValue,
        enableImageShadow: SETTINGS.enableImageShadow.defaultValue,
        imageShadowColor: SETTINGS.imageShadowColor.defaultValue,
        alternatingBackground: SETTINGS.alternatingBackground.defaultValue,
        columnCount: SETTINGS.columnCount.defaultValue
    },
    data: {
        features: {
            items: [],
            i18n: {}
        }
    }
};

export default withListener(FeatureDetailsComponent);
