import React from 'react';
import PropTypes from 'prop-types';
import { lowerFirst } from '../../tools/stringTools';
import { summaryPropTypes } from '../../constants/prop-types/application/summary';
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 { PRODUCT_CARD_MAX_MERCHANDISING_BADGES } from '../../constants/components/product-card';
import { renderBadge } from '../../tools/rendering/merchandisingBadges';
import Icon from '../icon/Icon';
import Image from '../image/Image';
import Rating from '../rating/Rating';
import './styles/ProductCard.scss';

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

const n = createNamespace('ProductCard');

const ProductCard = ({
    cardData: { title, details, size, logoSrcset = {}, logoAlt, merchandisingBadges = [],
        hasRequiredProduct, i18n },
    reviewData: { details: reviewDetails },
    settings
}) => {
    const i18nSummaryWithDefaults = { ...ProductCard.defaultProps.cardData.i18n, ...i18n };
    const { productNameSize, descTextSize, showRatings } = settings;
    const {
        reviews: { rating, numRatings, caption: ratingCaption, title: ratingTitle },
        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 ? (
        <ul {...n('merchandisingBadges').withTestId().props} aria-label={i18nSummaryWithDefaults.merchandisingBadges}>
            {merchandisingBadges.slice(0, PRODUCT_CARD_MAX_MERCHANDISING_BADGES).map(badge => (
                <li {...n('badgeItem').props} key={badge.uuid}>
                    {renderBadge(badge)}
                </li>
            ))}
        </ul>
    ) : null;

    const shouldRenderVendor = !!vendorTitle;

    const get2xProfileLogoImage = (logoSrcset && logoSrcset['2x']) || ProductCard.defaultProps.cardData.logoSrc;

    return (
        <div {...n('container').withTestId().props}>
            <div {...n('imageWrapper', size).props}>
                <Image
                    {...n('image').withTestId().withE2EId().props}
                    alt={logoAlt}
                    src={get2xProfileLogoImage}
                />
            </div>
            <div {...n('content').props}>
                <div {...n('contentText').props}>
                    <h2 {...n('title', lowerFirst(productNameSize)).withTestId().withE2EId().props}>{title}</h2>
                    {details && (
                        <h3 {...n('caption', lowerFirst(descTextSize)).withTestId().withE2EId().props}>{details}</h3>
                    )}
                    {hasRequiredProduct && (
                        <div {...n('hasRequiredProduct').props}>
                            <Icon {...n('tooltipIcon').props} type="tooltip" />
                            <span {...n('text').props}>{i18nSummaryWithDefaults.hasRequiredProduct}</span>
                        </div>
                    )}
                </div>
                {merchandisingBadgesBlock}
                {(shouldRenderRating || shouldRenderVendor) && (
                    <div {...n('ratingWrapper').props}>
                        {shouldRenderRating && (
                            <div {...n('starsWrapper').props}>
                                <Rating
                                    rating={rating}
                                    numRatings={numRatings}
                                    caption={ratingCaption}
                                    title={ratingTitle}
                                    displayRatingNumber={false}
                                />
                            </div>
                        )}
                        {shouldRenderVendor && (
                            <div {...n('details').props}>
                                <span {...n('vendorTitle').withTestId().withE2EId().props}>{`${vendorTitle}:`}</span>
                                {items.map(renderVendorLabel)}
                            </div>
                        )}
                    </div>
                )}
            </div>
        </div>
    );
};

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

ProductCard.propTypes = {
    cardData: PropTypes.shape(summaryPropTypes),
    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,
        logoSrcset: null,
        logoAlt: 'Product\'s logo',
        size: LARGE.value,
        hasRequiredProduct: false,
        i18n: {
            merchandisingBadges: 'Merchandising Badges',
            hasRequiredProduct: 'This product may require additional purchases'
        }
    },
    reviewData: {
        details: {
            reviews: {},
            vendor: {}
        }
    },
    settings: {
        showRatings: false,
        productNameSize: MEDIUM.value,
        descTextSize: MEDIUM.value
    }
};

export default ProductCard;
