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

import { createNamespace } from '../../tools/namingTools';
import { newlineToBr } from '../../tools/stringTools';
import { navigateTo } from '../../tools/urlTools';
import { NAMESPACES } from '../../constants/namespaces';
import withListener from '../withListener';

import { COLORPICKER, DROPDOWN, INPUT, TEXTAREA, PRODUCT,
    SLIDER, TOGGLE_CHECK, RADIO, IMAGE_UPLOADER, GROUP_HEADER } from '../../constants/schemaComponentTypes';
import { SMALL, MEDIUM, LARGE } from '../../constants/sizes';
import { LEFT, RIGHT, CENTER, TOP_LEFT, MIDDLE_LEFT, BOTTOM_LEFT,
    TOP_CENTER, MIDDLE_CENTER, BOTTOM_CENTER } from '../../constants/alignment';
import { SIZE_DEFAULT } from '../../constants/buttons';

import { PRIMARY, SECONDARY, EMPHASIS } from '../../constants/components/schemas/button-types';
import { SCALE_TO_FILL, SCALE_TO_FIT } from '../../constants/components/schemas/image-sizes';
import { NO_MASK, INSET_SQUARE_MASK, CIRCLE_MASK, INSET_CIRCLE_MASK } from '../../constants/components/schemas/image-masks';
import { useResponsive } from '../../tools/widths/useResponsive';
import { isMoreThanAllowedWidth } from '../../tools/widths/overflow';
import getImageMask from '../../tools/mask';
import Image from '../../atoms/image/Image';
import Button from '../../atoms/button/Button';
import Pricing from '../../atoms/pricing/Pricing';
import Icon from '../../atoms/icon/Icon';

import './styles/FeaturedProduct.scss';

const n = createNamespace('FeaturedProduct');

const FeaturedProduct = ({
    data,
    settings
}) => {
    const {
        product,
        size,
        tabTitle,
        tabBorderRadius,
        tabBackgroundColor,
        tabTextColor,
        tabPosition,
        productTextAlignment,
        productTitleColor,
        productDescriptionColor,
        productPricingColor,
        productBackgroundColor,
        cardBorderColor,
        cardShadowColor,
        cardBorderRadius,
        isShadowVisible,
        isPriceVisible,
        isButtonVisible,
        customProductTitle,
        customProductDescription,
        buttonLabel,
        buttonType,
        imagePosition,
        imageBackgroundColor,
        imageSize,
        imageMask,
        customImage,
        containerBackgroundColor
    } = settings;

    const [maskValue, setMaskValue] = useState('');
    const { i18n } = data;
    const containerRef = useRef();
    const tabRef = useRef();
    const [isTabFullWidthMobile, setTabFullWidthMobile] = useState(false);

    const imageRef = useRef();
    const imageUrl = customImage?.url || product?.overviewImageUrl;
    const imageAlt = customImage?.alt || product?.name || '';

    // causes re-render on screen resizing which is used by getImageMask
    const { mediumDown: isMobile } = useResponsive();

    useEffect(() => {
        setMaskValue(getImageMask(imageMask, imageRef));
    }, [imageMask, size, imageSize, isMobile]);

    useEffect(() => {
        const isMobileTabOverflow = !!(isMobile && isMoreThanAllowedWidth(tabRef.current, 3));
        setTabFullWidthMobile(isMobileTabOverflow);
    }, [tabTitle, isMobile]);

    const componentVariables = {
        'product-title-color': productTitleColor,
        'product-description-color': productDescriptionColor,
        'product-pricing-color': productPricingColor,
        'product-background-color': productBackgroundColor,
        'card-border-color': cardBorderColor,
        'card-shadow-color': cardShadowColor,
        'card-border-radius': `${cardBorderRadius}px`,
        'tab-border-radius': `${tabBorderRadius}px`,
        'tab-background-color': tabBackgroundColor,
        'tab-text-color': tabTextColor,
        'image-background-color': imageBackgroundColor,
        'container-background-color': containerBackgroundColor,
        'image-mask': maskValue
    };

    const wrapperModifiers = [
        size && `size-${size}`
    ];
    const tabModifiers = [
        tabPosition && `tab-${tabPosition}`,
        imagePosition && `image-${imagePosition}`,
        isTabFullWidthMobile && 'tab-full-width-mobile'
    ];
    const contentModifiers = [
        isShadowVisible && 'with-shadow',
        imagePosition && `image-${imagePosition}`
    ];
    const detailsModifiers = [
        productTextAlignment && `align-${productTextAlignment}`
    ];
    const imageModifiers = [
        imageSize && `image-${imageSize}`
    ];

    const handleButtonClick = () => product?.url && navigateTo(product?.url);

    const productTitle = customProductTitle || product?.name || i18n.defaultTitlePlaceholder;
    const productDescription = customProductDescription || product?.description || i18n.defaultDescriptionPlaceholder;
    const buttonSize = size === SMALL.value ? SMALL.value : SIZE_DEFAULT;

    return (
        <div {...n('wrapper', wrapperModifiers).withTestId().withVariables(componentVariables).props} ref={containerRef}>
            <div {...n('tabContainer').props}>
                <div {...n('tab', tabModifiers).withTestId().props} ref={tabRef}>
                    {tabTitle || i18n.featuredProduct}
                </div>
            </div>

            <div {...n('content', contentModifiers).withTestId().props}>
                <div {...n('details', detailsModifiers).props}>
                    {productTitle && (
                        <div {...n('title').withTestId().props}>
                            {newlineToBr(productTitle)}
                        </div>
                    )}
                    {productDescription && (
                        <div {...n('description').withTestId().props}>
                            {newlineToBr(productDescription)}
                        </div>
                    )}
                    {
                        isPriceVisible && (
                            <div {...n('pricing').withTestId().props}>
                                <Pricing
                                    isEmphasis
                                    isMultipleLine
                                    formattedPrice={product?.startingPrice?.formattedPrice}
                                    caption={product?.startingPrice?.priceCaption}
                                    frequency={product?.startingPrice?.frequency?.label}
                                />
                            </div>
                        )
                    }
                    {isButtonVisible && (
                        <div {...n('button').withTestId().props}>
                            <Button
                                size={buttonSize}
                                type={buttonType}
                                onClick={handleButtonClick}
                                tabIndex={0}
                            >
                                {buttonLabel || i18n.shopNow}
                            </Button>
                        </div>
                    )}
                </div>
                <div ref={imageRef} {...n('image', imageModifiers).withTestId().props}>
                    {
                        imageUrl ? (
                            <Image src={imageUrl} alt={imageAlt || productTitle} />
                        ) : (
                            <Icon {...n('defaultImage', imageModifiers).withTestId().props} type="image" width="64px" />
                        )
                    }
                </div>
            </div>
        </div>
    );
};

const SIZES_OPTIONS = [SMALL, MEDIUM, LARGE];
const ALIGN_OPTIONS = [LEFT, CENTER, RIGHT];
const IMAGE_ALIGN_OPTIONS = [LEFT, RIGHT];
const TEXT_ALIGN_OPTIONS = [
    TOP_LEFT, MIDDLE_LEFT, BOTTOM_LEFT,
    TOP_CENTER, MIDDLE_CENTER, BOTTOM_CENTER
];
const BUTTON_TYPES = [PRIMARY, SECONDARY, EMPHASIS];
const IMAGE_SIZE_TYPES = [SCALE_TO_FIT, SCALE_TO_FILL];
const IMAGE_MASK_TYPES = [NO_MASK, INSET_SQUARE_MASK, CIRCLE_MASK, INSET_CIRCLE_MASK];

FeaturedProduct.schema = () => ({
    name: 'FeaturedProduct',
    title: 'uieditor.sfbComponent.featuredProduct.title',
    iconName: 'productTile',
    componentTitleKey: 'tabTitle',
    orderableSection: [
        NAMESPACES.home
    ],
    form: {
        product: {
            type: PRODUCT
        },
        size: {
            title: 'uieditor.sfbComponent.featuredProduct.size.title',
            type: RADIO,
            defaultValue: SIZES_OPTIONS[2].value,
            options: SIZES_OPTIONS
        },
        tabHeading: {
            type: GROUP_HEADER,
            title: 'uieditor.sfbComponent.featuredProduct.tabHeading.title',
            symbol: 'style'
        },
        tabTitle: {
            title: 'uieditor.sfbComponent.featuredProduct.tabTitle.title',
            type: INPUT,
            defaultValue: 'uieditor.sfbComponent.featuredProduct.tabTitle.defaultValue'
        },
        tabBorderRadius: {
            title: 'uieditor.sfbComponent.featuredProduct.tabRadius.title',
            type: SLIDER,
            defaultValue: 8,
            options: {
                range: true,
                min: 0,
                max: 35,
                step: 1
            }
        },
        tabBackgroundColor: {
            title: 'uieditor.sfbComponent.featuredProduct.tabBackgroundColor.title',
            defaultValue: '#474747',
            type: COLORPICKER
        },
        tabTextColor: {
            title: 'uieditor.sfbComponent.featuredProduct.tabTextColor.title',
            defaultValue: '#FFFFFF',
            type: COLORPICKER
        },
        tabPosition: {
            title: 'uieditor.sfbComponent.featuredProduct.tabPosition.title',
            type: DROPDOWN,
            defaultValue: ALIGN_OPTIONS[1].value,
            options: ALIGN_OPTIONS
        },
        productHeading: {
            type: GROUP_HEADER,
            title: 'uieditor.sfbComponent.featuredProduct.productHeading.title',
            symbol: 'style'
        },
        productTextAlignment: {
            title: 'uieditor.sfbComponent.featuredProduct.productTextAlignment.title',
            type: DROPDOWN,
            defaultValue: TEXT_ALIGN_OPTIONS[0].value,
            options: TEXT_ALIGN_OPTIONS
        },
        productTitleColor: {
            title: 'uieditor.sfbComponent.featuredProduct.productTitleColor.title',
            defaultValue: '#474747',
            type: COLORPICKER
        },
        productDescriptionColor: {
            title: 'uieditor.sfbComponent.featuredProduct.productDescriptionColor.title',
            defaultValue: '#474747',
            type: COLORPICKER
        },
        productPricingColor: {
            title: 'uieditor.sfbComponent.featuredProduct.productPricingColor.title',
            defaultValue: '#474747',
            type: COLORPICKER
        },
        productBackgroundColor: {
            title: 'uieditor.sfbComponent.featuredProduct.productBackgroundColor.title',
            defaultValue: '#F5F5F5',
            type: COLORPICKER
        },
        cardBorderColor: {
            title: 'uieditor.sfbComponent.featuredProduct.cardBorderColor.title',
            defaultValue: '#FFFFFF',
            type: COLORPICKER
        },
        cardShadowColor: {
            title: 'uieditor.sfbComponent.featuredProduct.cardShadowColor.title',
            defaultValue: 'rgba(0,1,0,0.2)',
            type: COLORPICKER
        },
        cardBorderRadius: {
            title: 'uieditor.sfbComponent.featuredProduct.cardBorderRadius.title',
            type: SLIDER,
            defaultValue: 8,
            options: {
                range: true,
                min: 0,
                max: 35,
                step: 1
            }
        },
        isShadowVisible: {
            label: 'uieditor.sfbComponent.featuredProduct.isShadowVisible.label',
            defaultValue: true,
            type: TOGGLE_CHECK,
            marginSize: 10
        },
        isPriceVisible: {
            label: 'uieditor.sfbComponent.featuredProduct.isPriceVisible.label',
            defaultValue: true,
            type: TOGGLE_CHECK,
            marginSize: 10
        },
        isButtonVisible: {
            label: 'uieditor.sfbComponent.featuredProduct.isButtonVisible.label',
            defaultValue: true,
            type: TOGGLE_CHECK,
            marginSize: 10
        },
        customProductTitle: {
            title: 'uieditor.sfbComponent.featuredProduct.customProductTitle.title',
            placeholder: 'uieditor.sfbComponent.featuredProduct.customProductTitle.placeholder',
            type: TEXTAREA
        },
        customProductDescription: {
            title: 'uieditor.sfbComponent.featuredProduct.customProductDescription.title',
            placeholder: 'uieditor.sfbComponent.featuredProduct.customProductDescription.placeholder',
            type: TEXTAREA
        },
        buttonLabel: {
            title: 'uieditor.sfbComponent.featuredProduct.buttonLabel.title',
            type: INPUT,
            defaultValue: 'uieditor.sfbComponent.featuredProduct.buttonLabel.defaultValue'
        },
        buttonType: {
            title: 'uieditor.sfbComponent.featuredProduct.buttonType.title',
            type: RADIO,
            defaultValue: BUTTON_TYPES[0].value,
            options: BUTTON_TYPES
        },
        imageHeading: {
            type: GROUP_HEADER,
            title: 'uieditor.sfbComponent.featuredProduct.imageHeading.title',
            symbol: 'style'
        },
        imagePosition: {
            title: 'uieditor.sfbComponent.featuredProduct.imagePosition.title',
            type: RADIO,
            defaultValue: IMAGE_ALIGN_OPTIONS[1].value,
            options: IMAGE_ALIGN_OPTIONS
        },
        imageBackgroundColor: {
            title: 'uieditor.sfbComponent.featuredProduct.imageBackgroundColor.title',
            type: COLORPICKER,
            defaultValue: '#EAEAEA'
        },
        imageSize: {
            title: 'uieditor.sfbComponent.featuredProduct.imageSize.title',
            type: RADIO,
            defaultValue: IMAGE_SIZE_TYPES[0].value,
            options: IMAGE_SIZE_TYPES
        },
        imageMask: {
            title: 'uieditor.sfbComponent.featuredProduct.imageMask.title',
            type: RADIO,
            defaultValue: IMAGE_MASK_TYPES[0].value,
            options: IMAGE_MASK_TYPES
        },
        customImage: {
            title: 'uieditor.sfbComponent.featuredProduct.customImage.title',
            caption: 'uieditor.sfbComponent.featuredProduct.customImage.caption',
            placeholder: 'uieditor.sfbComponent.featuredProduct.customImage.placeholder',
            defaultValue: {
                filename: '',
                type: 'IMAGE_UPLOADER',
                url: '',
                alt: ''
            },
            type: IMAGE_UPLOADER,
            required: false,
            isAltVisible: true
        },
        containerBackgroundColor: {
            title: 'uieditor.sfbComponent.featuredProduct.containerBackgroundColor.title',
            type: COLORPICKER,
            defaultValue: '#EAEAEA'
        }
    },
    marketplaceData: {
        i18n: 'i18n'
    }
});

FeaturedProduct.propTypes = {
    data: PropTypes.object,
    settings: PropTypes.object
};

FeaturedProduct.defaultProps = {
    data: {
        i18n: {
            defaultPricePlaceholder: 'Product name',
            defaultDescriptionPlaceholder: 'Product description',
            shopNow: 'Shop now',
            featuredProduct: 'Featured Product'
        }
    },
    settings: {}
};

export default withListener(FeaturedProduct);
