import React from 'react';
import { withFocusable } from '../common/Focusable';
import { st, classes } from './FacesRatingBar.st.css.js';
import { dataHooks, facesData } from './constants';
import Box from '../Box/Box';
import Tooltip from '../Tooltip/Tooltip';
import { FaceDisapointed, FaceFrowning, FaceNeutral, FaceSmiling, FaceGrining, } from './icons/FaceIcons';
const faceIconsMap = {
    5: {
        1: FaceDisapointed,
        2: FaceFrowning,
        3: FaceNeutral,
        4: FaceSmiling,
        5: FaceGrining,
    },
    4: {
        1: FaceDisapointed,
        2: FaceFrowning,
        3: FaceSmiling,
        4: FaceGrining,
    },
    3: {
        1: FaceDisapointed,
        2: FaceNeutral,
        3: FaceSmiling,
    },
    2: {
        1: FaceDisapointed,
        2: FaceSmiling,
    },
};
/** A rating component that will enable the user to rate on a 1-5 scale. */
class FacesRatingBar extends React.PureComponent {
    constructor() {
        super(...arguments);
        this.state = {
            faceHoveredIndex: 0,
        };
        this._onFaceClick = index => {
            this.props.onChange(index);
        };
        this._onFaceMouseEnter = index => {
            this.setState({ faceHoveredIndex: index });
        };
        this._onFaceMouseLeave = () => {
            this.setState({ faceHoveredIndex: 0 });
        };
        this._onFaceFocus = (faceIndex, focusableProps) => {
            // We would like to change the faces color on focus / hover
            this.setState({ faceHoveredIndex: faceIndex });
            focusableProps.focusableOnFocus();
        };
        this._onFaceBlur = focusableProps => {
            // We would like to change the faces color on focus / hover
            this.setState({ faceHoveredIndex: 0 });
            focusableProps.focusableOnBlur();
        };
        this._shouldShowDescriptionValues = () => {
            const { readOnly, descriptionValues, maxValue } = this.props;
            let shouldShowDescriptionValues = false;
            // Adding description values is not available in read only mode and it must be an array of strings at size of at least 2.
            if (!readOnly && descriptionValues) {
                shouldShowDescriptionValues =
                    Array.isArray(descriptionValues) &&
                        descriptionValues.length === maxValue;
            }
            return shouldShowDescriptionValues;
        };
    }
    componentDidMount() {
        const { readOnly, value } = this.props;
        if (readOnly && value === 0) {
            throw new Error('In readOnly mode the value couldn’t be 0. Please enter a value between 1 to 5.');
        }
    }
    render() {
        const { dataHook, readOnly, value, descriptionValues, maxValue } = this.props;
        const { faceHoveredIndex } = this.state;
        const showDescriptionValues = this._shouldShowDescriptionValues();
        return (React.createElement(Box, { className: st(classes.root, {}, this.props), dataHook: dataHook },
            React.createElement(Faces, { readOnly: readOnly, maxValue: maxValue, selectedIndex: value, hoveredIndex: faceHoveredIndex, showDescriptionValues: showDescriptionValues, descriptionValues: descriptionValues, onClick: this._onFaceClick, onMouseEnter: this._onFaceMouseEnter, onMouseLeave: this._onFaceMouseLeave, handleFocus: this._onFaceFocus, handleBlur: this._onFaceBlur })));
    }
}
const Faces = ({ readOnly, selectedIndex, hoveredIndex, showDescriptionValues, descriptionValues, onClick, onMouseEnter, onMouseLeave, handleFocus, handleBlur, maxValue, }) => {
    const facesArr = [];
    for (let i = 1; i <= maxValue; i++) {
        const isSelected = selectedIndex === i;
        const isHovered = hoveredIndex === i;
        const iconType = facesData[i].name;
        const commonProps = {
            key: i,
            faceIndex: i,
            isSelected,
            iconType,
            maxValue,
        };
        const face = readOnly ? (React.createElement(ReadOnlyModeFace, { ...commonProps })) : (React.createElement(FocusableInteractiveModeFace, { ...commonProps, isHovered: isHovered, showDescriptionValues: showDescriptionValues, descriptionValues: descriptionValues, onClick: onClick, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, handleFocus: handleFocus, handleBlur: handleBlur }));
        facesArr.push(face);
    }
    return facesArr;
};
const InteractiveModeFace = ({ faceIndex, isSelected, iconType, isHovered, showDescriptionValues, descriptionValues, onClick, onMouseEnter, onMouseLeave, handleFocus, handleBlur, maxValue, ...focusableProps }) => {
    const IconTagName = faceIconsMap[maxValue][faceIndex];
    const tooltipContent = showDescriptionValues
        ? descriptionValues[faceIndex - 1]
        : '';
    return (React.createElement("button", { "data-hook": dataHooks.face, "data-index": faceIndex, "data-selected": isSelected, className: st(classes.buttonWrapper), onClick: () => onClick(faceIndex), onMouseEnter: () => onMouseEnter(faceIndex), onMouseLeave: onMouseLeave, onFocus: () => handleFocus(faceIndex, focusableProps), onBlur: () => handleBlur(focusableProps) },
        React.createElement("div", { "data-hook": dataHooks.face, "data-selected": isSelected, className: st(classes.faceContainer, {
                type: 'interactive',
                hovered: isHovered,
                selected: isSelected,
                iconType,
            }) },
            React.createElement(Tooltip, { dataHook: facesData[faceIndex].tooltipDataHook, content: tooltipContent, disabled: !showDescriptionValues },
                React.createElement(IconTagName, { width: 22, height: 22 })))));
};
const FocusableInteractiveModeFace = withFocusable(InteractiveModeFace);
const ReadOnlyModeFace = ({ faceIndex, isSelected, iconType, maxValue }) => {
    const IconTagName = faceIconsMap[maxValue][faceIndex];
    return (React.createElement("div", { "data-hook": dataHooks.face, "data-selected": isSelected, className: st(classes.faceContainer, {
            type: 'readOnly',
            selected: isSelected,
            iconType,
        }) },
        React.createElement(IconTagName, null)));
};
FacesRatingBar.displayName = 'FacesRatingBar';
FacesRatingBar.defaultProps = {
    readOnly: false,
    onChange: () => { },
    maxValue: 5,
};
export default FacesRatingBar;
//# sourceMappingURL=FacesRatingBar.js.map