import React from 'react';
import PropTypes from 'prop-types';
import { Scrollbars } from 'react-custom-scrollbars';
import isFunction from 'lodash/isFunction';
import get from 'lodash/get';
import { withStyles } from '@material-ui/core/styles';
import Icon from '@material-ui/core/Icon';
import { withResizeDetectWrapper } from 'Shared/HOCs/ResizeDetect/ResizeDetect';
import Typography from '@material-ui/core/Typography';
import withWidth, { isWidthDown } from '@material-ui/core/withWidth';
import AccessibleButton from '../../../../Shared/Components/AccessibleButton/AccessibleButton';

export const styles = theme => ({
    thumbnailCarouselWrapper: {
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        paddingBottom: 16,
        [theme.breakpoints.down('xs')]: {
            paddingBottom: '0',
        },
        [theme.breakpoints.between('sm', 'md')]: {
            maxWidth: 300,
            margin: '0 auto',
        },
    },
    fullSizeCarouselWrapper: {
        width: '100%',
        minWidth: 90,
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
    },
    arrowScrollIcon: {
        '&:hover': {
            cursor: 'pointer',
            fontWeight: 'bold',
        },
    },
    designerThumbnail: {
        width: '100%',
        display: 'flex',
        alignItems: 'center',

        '& img': {
            boxSizing: 'border-box',
            height: 70,
            maxWidth: 70,
            cursor: 'pointer',
            objectFit: 'cover',

            '&:hover': {
                cursor: 'pointer',
            },
        },
    },
    activeThumbnail: {
        border: '2px solid ' + theme.palette.primary.main,
        borderRadius: '4px',
    },
    inactiveThumbnail: {
        border: '1px solid #C4C4C4',
        borderRadius: '4px',
    },
    dots: {
        position: 'inherit',
        textAlign: 'center',
        display: 'flex',
        justifyContent: 'center',
        maxHeight: 70,
        minHeight: 70,
        flexWrap: 'wrap',
        overflow: 'auto',

        [theme.breakpoints.down('sm')]: {
            textAlign: 'initial',
        },
        [theme.breakpoints.down('xs')]: {
            maxHeight: 50,
            minHeight: 50,
            bottom: '0',
            textAlign: 'center',
            alignItems: 'center',
        },
    },
    thumbnailImageContainer: {
        height: 75,
        width: 75,
        paddingRight: 6,
        boxSizing: 'border-box',
        borderRadius: '4px',
    },
    dotContainer: {
        height: 40,
        width: 40,
        marginRight: '8px',
        '&.wrap-container': {
            marginRight: 0,
            height: 32,
            width: 32,
            marginTop: 8,
            [theme.breakpoints.down('sm')]: {
                height: 20,
                width: 28,
                marginTop: 5,
            },
            '& > div': {
                margin: 0,
            },
        },
        '& > div': {
            textIndent: 1,
            color: '#FFFFFF',
            fontSize: '12px',
            lineHeight: '20px',
            textAlign: 'center',
            margin: '10px',
            cursor: 'pointer',
            height: 20,
            width: 20,
            borderRadius: '50%',
            display: 'inline-block',
            transition: 'background-color 0.6s ease',
        },
        '&:last-child': {
            marginRight: 0,
        },
    },
    inactiveDotMode: {
        backgroundColor: '#D8D8D8',
    },
    activeDotMode: {
        backgroundColor: '#757575',
    },
});

class Thumbnail extends React.Component {
    static propTypes = {
        thumbnails: PropTypes.object,
        size: PropTypes.object,
        thumbnailChange: PropTypes.func,
        selectedDesignViewIdentifier: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
        classes: PropTypes.object,
        onThumbnailClick: PropTypes.func,
        previewOpen: PropTypes.bool,
        width: PropTypes.string,
        scrollbarHeight: PropTypes.number,
    };

    state = {
        isScrollingAvailable: true,
        availableWidth: 0,
    };
    scrollbars = React.createRef();
    thumbnailCarouselWrapperRef = React.createRef();

    componentDidMount() {
        this.updateScrollingAvailable();
        this.calculateAvailableWidth();
    }

    componentDidUpdate(prevProps) {
        this.updateScrollingAvailable();
        const { size } = this.props;
        if (size !== prevProps.size) {
            this.calculateAvailableWidth();
        }
    }

    onThumbnailClick = (thumbnails, thumbnail) => () => {
        if (isFunction(this.props.thumbnailChange)) {
            this.props.thumbnailChange(thumbnails, thumbnail.thumbnailImage, !thumbnail.active);
        }
    };

    calculateAvailableWidth() {
        if (this.scrollbars && this.scrollbars.current !== null) {
            const childWidth = get(this.scrollbars.current, 'view.children[0].children[0].clientWidth');

            const availableWidth = this.thumbnailCarouselWrapperRef.current.clientWidth - 40;
            const containerElements = Math.floor(availableWidth / childWidth);
            this.setState({ availableWidth: Math.ceil(containerElements * childWidth) });
        }
    }

    updateScrollingAvailable = () => {
        if (this.scrollbars && this.scrollbars.current !== null) {
            const { scrollWidth, clientWidth } = this.scrollbars.current.getValues();
            const { isScrollingAvailable } = this.state;
            const nextIsScrollingAvailable = scrollWidth - clientWidth > 0;
            if (nextIsScrollingAvailable !== isScrollingAvailable) {
                this.setState({ isScrollingAvailable: nextIsScrollingAvailable });
            }
        }
    };

    handleClickLeftArrow() {
        this.scrollbars.current.scrollLeft(
            this.scrollbars.current.getScrollLeft() -
                this.scrollbars.current.view.children[0].children[0].clientWidth
        );
    }

    handleClickRightArrow() {
        this.scrollbars.current.scrollLeft(
            this.scrollbars.current.getScrollLeft() +
                this.scrollbars.current.view.children[0].children[0].clientWidth
        );
    }

    onScrollStop = () => {
        if (this.scrollbars && this.scrollbars.current !== null) {
            const scrollLeftValue = this.scrollbars.current.getScrollLeft();
            const scrollWidth = this.scrollbars.current.getScrollWidth();
            const childWidth = get(this.scrollbars.current, 'view.children[0].children[0].clientWidth');
            const scrolledElements = Math.round(scrollLeftValue / childWidth);
            const scrollToValue = Math.ceil(scrolledElements * childWidth);
            if (scrollWidth - scrollLeftValue <= childWidth) {
                this.scrollbars.current.scrollLeft(scrollWidth);
            } else {
                this.scrollbars.current.scrollLeft(scrollToValue);
            }
        }
    };

    render() {
        const {
            thumbnails,
            selectedDesignViewIdentifier,
            classes,
            onThumbnailClick,
            previewOpen,
            scrollbarHeight,
            width,
        } = this.props;

        const { isScrollingAvailable, availableWidth } = this.state;

        const { items, dotMode } = thumbnails;
        const isSmallScreen = isWidthDown('md', width);

        if (items && items.length <= 1) {
            return null;
        }

        if (dotMode || isSmallScreen) {
            return (
                <div className={classes.dots}>
                    {items &&
                        items.map((thumbnail, index) => (
                            <AccessibleButton
                                component="div"
                                className={`${classes.dotContainer} ${isSmallScreen ? 'wrap-container' : ''}`}
                                key={thumbnail.identifier}
                                onClick={() => onThumbnailClick(thumbnail.identifier)}
                            >
                                <Typography
                                    component="div"
                                    className={
                                        selectedDesignViewIdentifier === thumbnail.identifier
                                            ? classes.activeDotMode
                                            : classes.inactiveDotMode
                                    }
                                >
                                    {index + 1}
                                </Typography>
                            </AccessibleButton>
                        ))}
                </div>
            );
        }

        return (
            <div
                className={previewOpen ? classes.fullSizeCarouselWrapper : classes.thumbnailCarouselWrapper}
                ref={this.thumbnailCarouselWrapperRef}
            >
                {isScrollingAvailable && (
                    <Icon onClick={this.handleClickLeftArrow.bind(this)} className={classes.arrowScrollIcon}>
                        keyboard_arrow_left
                    </Icon>
                )}
                <Scrollbars
                    style={{
                        height: scrollbarHeight || 84,
                        width: availableWidth,
                    }}
                    autoHide
                    ref={this.scrollbars}
                    onScrollStop={this.onScrollStop}
                >
                    <div
                        className={classes.designerThumbnail}
                        style={{ justifyContent: !isScrollingAvailable ? 'center' : 'initial' }}
                    >
                        {items &&
                            items.map(thumbnail => (
                                <AccessibleButton
                                    component="div"
                                    className={classes.thumbnailImageContainer}
                                    key={thumbnail.identifier}
                                    onClick={() => onThumbnailClick(thumbnail.identifier)}
                                    value={thumbnail.identifier}
                                >
                                    <img
                                        src={thumbnail.thumbnailImage}
                                        alt={thumbnail.identifier}
                                        key={thumbnail.identifier}
                                        className={
                                            selectedDesignViewIdentifier === thumbnail.identifier
                                                ? classes.activeThumbnail
                                                : classes.inactiveThumbnail
                                        }
                                    />
                                </AccessibleButton>
                            ))}
                    </div>
                </Scrollbars>
                {isScrollingAvailable && (
                    <Icon onClick={this.handleClickRightArrow.bind(this)} className={classes.arrowScrollIcon}>
                        keyboard_arrow_right
                    </Icon>
                )}
            </div>
        );
    }
}

const VariantCarouselWithResizeDetectWrapper = withResizeDetectWrapper(
    withWidth({ initialWidth: 'lg' })(Thumbnail)
);

export default withStyles(styles, { name: 'Thumbnail' })(props => (
    <VariantCarouselWithResizeDetectWrapper wrapperClassName={props.classes.resizeDetectWrapper} {...props} />
));
