import React from 'react';
import PropTypes from 'prop-types';
import { lowerFirst } from '../../tools/stringTools';
import { getImageSrc } from '../../tools/images';
import { PRODUCT_DEFAULT_IMG } from '../../constants/images';
import { createNamespace } from '../../tools/namingTools';
import { generateUniqueID } from '../../tools/helpers';
import { XSMALL, SMALL, MEDIUM, LARGE } from '../../constants/sizes';
import Rating from '../rating/Rating';
import { PRODUCT_CARD_MAX_MERCHANDISING_BADGES } from '../../constants/components/product-card';
import { renderMerchandisingBadges } from '../../tools/rendering/merchandisingBadges';
import './styles/ProductCard.scss';

const sizeValues = [XSMALL.value, SMALL.value, MEDIUM.value, LARGE.value];

const n = createNamespace('ProductCard');

const ProductCard = ({
    cardData: { title, details, size, logoSrc, logoSrcset = {}, merchandisingBadges = [] },
    reviewData: { details: reviewDetails },
    settings
}) => {
    const { productNameSize, descTextSize, showRatings } = settings;
    const { reviews: { rating, numRatings }, vendor: { title: vendorTitle, items } } = reviewDetails;

    const shouldRenderRating = Boolean(showRatings && rating && numRatings && numRatings > 0);

    const renderVendorLabel = ({ label: vendorLabel }) => (
        <span
            key={generateUniqueID([vendorLabel])}
            {...n('vendorLabel').withTestId().withE2EId().props}
        >
            {vendorLabel}
        </span>
    );

    const merchandisingBadgesBlock = merchandisingBadges && merchandisingBadges.length ? (
        <div {...n('merchandisingBadges').withTestId().props}>
            {renderMerchandisingBadges(merchandisingBadges.slice(0, PRODUCT_CARD_MAX_MERCHANDISING_BADGES))}
        </div>
    ) : null;

    const imageUrl = getImageSrc(logoSrc, logoSrcset) || ProductCard.defaultProps.cardData.logoSrc;

    const shouldRenderVendor = !!vendorTitle;

    return (
        <section {...n('container').props}>
            {imageUrl && (
                <div {...n('imageWrapper', size).props}>
                    <img src={imageUrl} alt={title} {...n('image').withTestId().withE2EId().props} />
                </div>
            )}
            <div {...n('content').props}>
                <div {...n('contentText').props}>
                    <h1 {...n('title', lowerFirst(productNameSize)).withTestId().withE2EId().props}>{title}</h1>

                    {details && (
                        <div {...n('caption', lowerFirst(descTextSize)).withTestId().withE2EId().props}>{details}</div>
                    )}
                </div>
                {merchandisingBadgesBlock}
                {(shouldRenderRating || shouldRenderVendor) && (
                    <div {...n('ratingWrapper').props}>
                        {shouldRenderRating && (
                            <div {...n('starsWrapper').props}>
                                <Rating rating={rating} numRatings={numRatings} displayRatingNumber={false} />
                            </div>
                        )}
                        {shouldRenderVendor && (
                            <div {...n('details').props}>
                                <span {...n('vendorTitle').withTestId().withE2EId().props}>{`${vendorTitle}:`}</span>
                                {items.map(renderVendorLabel)}
                            </div>
                        )}
                    </div>
                )}
            </div>
        </section>
    );
};

ProductCard.schema = () => ({
    name: 'Product Card',
    form: {}
});

ProductCard.propTypes = {
    cardData: PropTypes.shape({
        title: PropTypes.string,
        details: PropTypes.string,
        size: PropTypes.oneOf([LARGE.value, MEDIUM.value, SMALL.value, XSMALL.value]),
        logoSrc: PropTypes.string,
        logoSrcset: PropTypes.shape({
            default: PropTypes.string,
            '1x': PropTypes.string,
            '2x': PropTypes.string
        }),
        merchandisingBadges: PropTypes.arrayOf(
            PropTypes.shape({
                uuid: PropTypes.string,
                name: PropTypes.string,
                image: PropTypes.string
            })
        )
    }),
    reviewData: PropTypes.shape({
        details: PropTypes.shape({
            reviews: PropTypes.shape({
                rating: PropTypes.number,
                numRatings: PropTypes.number
            }),
            vendor: PropTypes.shape({
                title: PropTypes.string,
                items: PropTypes.arrayOf(PropTypes.shape({
                    label: PropTypes.string
                }))
            })
        })
    }),
    settings: PropTypes.shape({
        showRatings: PropTypes.bool,
        productNameSize: PropTypes.oneOf(sizeValues),
        descTextSize: PropTypes.oneOf(sizeValues)
    })
};

ProductCard.defaultProps = {
    cardData: {
        title: '',
        details: '',
        logoSrc: PRODUCT_DEFAULT_IMG,
        size: LARGE.value
    },
    reviewData: {
        details: {
            reviews: {},
            vendor: {}
        }
    },
    settings: {
        showRatings: false,
        productNameSize: MEDIUM.value,
        descTextSize: MEDIUM.value
    }
};

export default ProductCard;
