import PropTypes from "prop-types";
import React from "react";
import Icon from "react-oui-icons";
import classNames from "classnames";
import { FILL_COLOR_MAP } from "../../utils/accessibility";

export interface ButtonIconProps {
    /** React ref to the underlying button component */
    buttonRef?: any;
    /** CSS class names. */
    className?: string;
    /** Color to use for the fill of the icon */
    iconFill?: "aqua" | "yellow" | "default" | "green" | "orange" | "pink" | "red" | "magenta" | "grey" | "purple" | "black";
    /** Name of the icon to use */
    iconName: string;
    /** Prevent users from interacting with the button */
    isDisabled?: boolean;
    /** Function to perform when the close button is clicked. */
    onClick?: (evt) => void;
    /** Size of the button, medium by default */
    size?: "small" | "medium" | "large";
    /** Various style options */
    style?: "highlight" | "danger" | "danger-outline" | "outline" | "plain" | "unstyled";
    /** Hook for automated JavaScript tests */
    testSection?: string;
    /** Title of the button used on hover and for screen readers */
    title: string;
}

const ButtonIcon = ({ // eslint-disable-line @typescript-eslint/explicit-function-return-type
    buttonRef,
    className,
    iconFill,
    iconName,
    isDisabled,
    onClick,
    size,
    style,
    testSection,
    title,
    ...props
}: ButtonIconProps) => {
    // ensure valid fillColor name (in the case that propType errors are ignored)
    const fillColor = iconFill && Object.keys(FILL_COLOR_MAP).includes(iconFill) ? FILL_COLOR_MAP[iconFill] : null;

    function handleOnClick(event): void {
        if (isDisabled) {
            return;
        }
        onClick && onClick(event);
    }

    return (
        <button
            className={classNames(`oui-button oui-button-icon oui-button-icon__${size} oui-button--${style}`, className)}
            data-oui-component={true}
            data-test-section={testSection}
            disabled={isDisabled}
            onClick={handleOnClick}
            ref={buttonRef}
            title={title}
            type="button"
            {...props}
        >
            <div className="flex flex--dead-center ">
                <Icon fill={fillColor} name={iconName} size={size} title={title} />
            </div>
        </button>
    );
};

ButtonIcon.propTypes = {
    /** React ref to the underlying button component */
    buttonRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({ current: PropTypes.instanceOf(Element) })]),
    /** CSS class names. */
    className: PropTypes.string,
    /**
     *  Color to use for the fill of the icon
     */
    iconFill: PropTypes.oneOf(Object.keys(FILL_COLOR_MAP)),
    /**
     *  Name of the icon to use
     */
    iconName: PropTypes.string.isRequired,
    /**
     * Prevent users from interacting with the button
     */
    isDisabled: PropTypes.bool,
    /**
     *  Function to perform when the close button is clicked.
     */
    onClick: PropTypes.func,
    /**
     *  Size of the button, medium by default
     */
    size: PropTypes.oneOf(["small", "medium", "large"]),
    /**
     *  Various style options
     */
    style: PropTypes.oneOf(["highlight", "danger", "danger-outline", "outline", "plain", "unstyled"]),
    /**
     * Hook for automated JavaScript tests
     */
    testSection: PropTypes.string,
    /**
     *  Title of the button used on hover and for screen readers
     */
    title: PropTypes.string.isRequired,
};

ButtonIcon.defaultProps = {
    iconName: "add",
    onClick: () => null,
    size: "medium",
    title: "",
};

export default React.memo(ButtonIcon);
