import React from 'react';
import PropTypes from 'prop-types';
import './styles/rating.scss';
import Icon from '../icon/Icon';
import { createNamespace } from '../../tools/namingTools';

const n = createNamespace('Rating');

const Rating = ({
    rating,
    numRatings,
    ratingScore,
    displayRatingNumber,
    displayRatingCaption,
    showLongNumRatings,
    starWidth,
    isSelected,
    i18n
}) => {
    const ratingValue = Number.parseFloat(rating) || 0;
    const i18nWithDefaults = { ...Rating.defaultProps.i18n, ...i18n };

    // don't display decimal when integer
    const ratingDisplay = Number.isInteger(ratingValue) ? ratingValue : ratingValue.toFixed(1);

    const starsArray = [...Array(ratingScore).keys()];

    const isMaxRating = rating === starsArray.length;
    const shouldDisplayCaption = displayRatingCaption && !isMaxRating;

    const componentVariables = Object.assign({
        'rating-fullstars': Math.floor(ratingValue),
        'rating-partialstar': ratingValue % 1
    }, starWidth && {
        'rating-star-width': `${starWidth}px`
    });

    const renderStars = status => (
        <div {...n('star', status).props}>
            {starsArray.map(index => (
                <Icon {...n('starItem', status).withTestId().withE2EId().props} key={`ratingStar${index}`} type="star" />
            ))}
        </div>
    );

    const renderNumRatings = () => {
        if (!numRatings) {
            return null;
        }
        let numRatingsText = `(${numRatings})`;
        if (showLongNumRatings) {
            numRatingsText = `${numRatings} ${i18nWithDefaults.reviews}`;
        }

        return <span {...n('numberOfRatings').withTestId().withE2EId().props}>{numRatingsText}</span>;
    };

    return (
        <div {...n('wrapper').withTestId().withVariables(componentVariables).withE2EId().props}>
            <div {...n('stats').withE2EId().props}>
                <div {...n('score').withE2EId().props}>
                    {renderStars('neutral')}
                    {ratingValue > 0 && (
                        <div {...n('mask').withE2EId().props}>
                            {renderStars(isSelected ? 'selected' : 'positive')}
                        </div>
                    )}
                </div>
            </div>
            { displayRatingNumber && (
                <span {...n('rating').withTestId().withE2EId().props}>{ratingDisplay}</span>
            )}
            {shouldDisplayCaption && (
                <span {...n('caption').withTestId().withE2EId().props}>{i18nWithDefaults.andUp}</span>
            )}
            {renderNumRatings()}
        </div>
    );
};

Rating.propTypes = {
    rating: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
    numRatings: PropTypes.number,
    ratingScore: PropTypes.number,
    displayRatingNumber: PropTypes.bool,
    displayRatingCaption: PropTypes.bool,
    showLongNumRatings: PropTypes.bool,
    starWidth: PropTypes.number,
    isSelected: PropTypes.bool,
    i18n: PropTypes.shape({
        reviews: PropTypes.string,
        andUp: PropTypes.string
    })
};

Rating.defaultProps = {
    rating: 0,
    numRatings: 0,
    ratingScore: 5,
    starWidth: null,
    displayRatingNumber: true,
    displayRatingCaption: false,
    showLongNumRatings: false,
    isSelected: false,
    i18n: {
        reviews: 'Reviews',
        andUp: '& up'
    }
};

export default Rating;
