import React, { useRef } from 'react';
import PropTypes from 'prop-types';
import { createNamespace } from '../../tools/namingTools';
import { useCarouselA11yVisible } from '../../tools/a11y/useCarouselA11yVisible';
import { COLORPICKER, DROPDOWN, INPUT, TEXTAREA } from '../../constants/schemaComponentTypes';
import { SMALL, MEDIUM, LARGE } from '../../constants/sizes';
import { LEFT, RIGHT, CENTER } from '../../constants/alignment';
import { newlineToBr } from '../../tools/stringTools';
import { navigateTo } from '../../tools/urlTools';
import Image from '../image/Image';
import Button from '../button/Button';
import './styles/CarouselSlideText.scss';

const n = createNamespace('CarouselSlideText');

export const TEXT_SLIDE_TYPE = 'IMAGE_WITH_TEXT';
export const PRODUCT_TYPE = 'PRODUCT';

const CarouselSlideText = ({
    data: {
        title,
        text,
        image,
        titleColor,
        textColor,
        textSize,
        textAlignment,
        backgroundColor,
        imagePosition,
        slideLink,
        buttonLabel
    },
    i18n: {
        learnMore
    },
    settings
}) => {
    const containerRef = useRef();
    const [, tabIndex] = useCarouselA11yVisible(containerRef);
    const imageUrl = image ? image.url : '';
    const imageAlt = image ? image.alt : '';

    const componentVariables = {
        height: settings.height ? `${settings.height}px` : null,
        'mobile-height': settings.mobileHeight ? `${settings.mobileHeight}px` : null,
        'text-color': textColor,
        'title-color': titleColor,
        'background-color': backgroundColor,
        'text-alignment': textAlignment
    };

    const wrapperModifiers = [
        imagePosition && `image-${imagePosition}`,
        textSize && `text-size-${textSize}`,
        backgroundColor && 'has-background'
    ];
    const handleButtonClick = () => navigateTo(slideLink);

    const ConditionalAnchorWrapper = ({ isClickable, anchorWrapper, children }) => (
        isClickable ? anchorWrapper(children) : children
    );

    // if slide is type image, the whole slide becomes the link instead of having a button
    let callToAction = null;
    if (slideLink) {
        callToAction = (
            <div {...n('button').props}>
                <Button
                    type="emphasisAlt"
                    onClick={handleButtonClick}
                    tabIndex={tabIndex}
                >
                    {buttonLabel || learnMore}
                </Button>
            </div>
        );
    }

    const shouldRenderContentText = title || text;

    return (
        <div {...n('wrapper', wrapperModifiers).withTestId().withVariables(componentVariables).props} ref={containerRef}>
            <div {...n('content').props}>
                {shouldRenderContentText && (
                    <div {...n('text').props}>
                        {title && (
                            <div {...n('title').withTestId().props}>
                                {newlineToBr(title)}
                            </div>
                        )}
                        {text && (
                            <div {...n('description').withTestId().props}>
                                {newlineToBr(text)}
                            </div>
                        )}
                        {callToAction}
                    </div>
                )}
                {imageUrl ? (
                    <div {...n('image').props}>
                        <ConditionalAnchorWrapper
                            anchorWrapper={children => (
                                <a {...n().withTestId('contentImage').props} href={slideLink} tabIndex={tabIndex}>
                                    {children}
                                </a>
                            )}
                        >
                            <Image src={imageUrl} alt={imageAlt || title} />
                        </ConditionalAnchorWrapper>
                    </div>
                ) : ''}
            </div>
        </div>
    );
};

const TEXT_SIZES_OPTIONS = [SMALL, MEDIUM, LARGE];
const TEXT_ALIGN_OPTIONS = [LEFT, RIGHT, CENTER];
const IMAGE_ALIGN_OPTIONS = [LEFT, RIGHT];

CarouselSlideText.schema = () => ({
    name: 'Carousel Slide Text',
    iconName: 'carousel',
    form: {
        title: {
            title: 'uieditor.sfbComponent.carouselSlideText.title.title',
            type: INPUT,
            defaultValue: 'uieditor.sfbComponent.carouselSlideText.title.defaultValue'
        },
        text: {
            title: 'uieditor.sfbComponent.carouselSlideText.blurb.title',
            type: TEXTAREA,
            defaultValue: 'uieditor.sfbComponent.carouselSlideText.blurb.defaultValue'
        },
        textSize: {
            title: 'uieditor.sfbComponent.carouselSlideText.textSize.title',
            type: DROPDOWN,
            defaultValue: TEXT_SIZES_OPTIONS[0].value,
            options: TEXT_SIZES_OPTIONS
        },
        titleColor: {
            title: 'uieditor.sfbComponent.carouselSlideText.titleColor.title',
            defaultValue: '#474747',
            type: COLORPICKER
        },
        textColor: {
            title: 'uieditor.sfbComponent.carouselSlideText.textColor.title',
            defaultValue: '#474747',
            type: COLORPICKER
        },
        textAlignment: {
            title: 'uieditor.sfbComponent.carouselSlideText.textAlignment.title',
            type: DROPDOWN,
            defaultValue: TEXT_ALIGN_OPTIONS[0].value,
            options: TEXT_ALIGN_OPTIONS
        },
        imageUrl: {
            title: 'uieditor.sfbComponent.carouselSlideText.imageUrl.title',
            type: INPUT,
            defaultValue: ''
        },
        imageAlt: {
            title: 'uieditor.sfbComponent.carouselSlideText.imageAlt.title',
            type: INPUT,
            caption: 'uieditor.sfbComponent.carouselSlideText.imageAlt.caption',
            defaultValue: ''
        },
        imagePosition: {
            title: 'uieditor.sfbComponent.carouselSlideText.imagePosition.title',
            type: DROPDOWN,
            defaultValue: IMAGE_ALIGN_OPTIONS[0].value,
            options: IMAGE_ALIGN_OPTIONS
        },
        slideLink: {
            title: 'uieditor.sfbComponent.carouselSlideText.url.title',
            type: INPUT,
            defaultValue: ''
        },
        buttonLabel: {
            title: 'uieditor.sfbComponent.carouselSlideText.buttonLabel.title',
            type: INPUT,
            defaultValue: 'Input link label here'
        },
        backgroundColor: {
            title: 'uieditor.sfbComponent.carouselSlideText.backgroundColor.title',
            defaultValue: '#eee',
            type: COLORPICKER
        }
    }
});

CarouselSlideText.propTypes = {
    settings: PropTypes.shape({
        height: PropTypes.string,
        mobileHeight: PropTypes.number
    }),
    data: PropTypes.shape({
        layout: PropTypes.string,
        title: PropTypes.string,
        text: PropTypes.string,
        image: PropTypes.shape({
            url: PropTypes.string,
            alt: PropTypes.string
        }),
        titleColor: PropTypes.string,
        textColor: PropTypes.string,
        textSize: PropTypes.oneOf(TEXT_SIZES_OPTIONS.map(({ value }) => value)),
        textAlignment: PropTypes.oneOf(TEXT_ALIGN_OPTIONS.map(({ value }) => value)),
        backgroundColor: PropTypes.string,
        imagePosition: PropTypes.oneOf(IMAGE_ALIGN_OPTIONS.map(({ value }) => value)),
        slideLink: PropTypes.string,
        buttonLabel: PropTypes.string
    }),
    i18n: PropTypes.shape({
        learnMore: PropTypes.string
    }),
    isPreviewMode: PropTypes.bool
};

CarouselSlideText.defaultProps = {
    settings: {
    },
    data: {
        title: '',
        text: '',
        image: null,
        titleColor: null,
        textColor: null,
        textSize: null,
        textAlignment: null,
        backgroundColor: null,
        imagePosition: null,
        slideLink: null,
        buttonLabel: null
    },
    i18n: {
        learnMore: 'Learn More'
    },
    isPreviewMode: false
};

export default CarouselSlideText;
