import React from "react";
import PropTypes from "prop-types";
import classNames from "classnames";

class Item extends React.Component {
    constructor(props) {
        super(props);
        this._handleOnKeyDown = this._handleOnKeyDown.bind(this);
    }

    ref = React.createRef();

    componentDidUpdate() {
        if (this.props.hasFauxFocus) {
            this.ref.current.scrollIntoView({
                behavior: "smooth",
                block: "center",
            });
        }
    }

    _handleOnKeyDown(event) {
        if (event && event.keyCode === 32 && event.target === this._itemWithOnClick) {
            // Space key was pressed on the item, not a child of the item.
            // Run the `onClick` and prevent the page from scrolling.
            event.preventDefault();
            this.props.onClick();
        }
    }

    render() {
        let item;

        const {
            children,
            className,
            gutters,
            hasFauxFocus,
            href,
            hrefTarget,
            hrefTitle,
            isDisabled,
            onClick,
            onMouseDown,
            testSection,
            ...props
        } = this.props;

        const commonClasses = classNames({
            "oui-block-list__item": true,
            "oui-block-list__item--has-focus": hasFauxFocus,
            "hard--sides": gutters === "tight",
        });

        if (isDisabled) {
            item = (
                <div className={`${commonClasses} pointer-events--none background--faint muted`}>
                    {children}
                </div>
            );
        } else if (onClick) {
            // The element is rendered as a `div` instead of a `button` because the
            // user may want to pass in a `button` within `children`.
            // `tabIndex`, `role`, and `onKeyDown` are provided to make the `div`
            // behave like a button: https://mzl.la/1mRMvQj
            item = (
                <div
                    className={`${commonClasses} link oui-block-list__link`}
                    onClick={onClick}
                    onKeyDown={this._handleOnKeyDown}
                    tabIndex="0"
                    role="button"
                    ref={el => {
                        this._itemWithOnClick = el;
                    }}
                >
                    {children}
                </div>
            );
        } else if (href) {
            item = (
                <a
                    href={href}
                    className={`${commonClasses} oui-block-list__link display--block`}
                    target={hrefTarget}
                    title={hrefTitle}
                    rel={hrefTarget === "_blank" && "noopener noreferrer"}
                >
                    {children}
                </a>
            );
        } else {
            item = (
                <div
                    className={commonClasses}
                    onMouseDown={onMouseDown}
                    {...(testSection && { "data-test-section": testSection + "-item" })}

                >
                    {children}
                </div>
            );
        }

        return (
            <li ref={this.ref} style={{ wordBreak: "break-word" }} className={className} data-test-section={testSection} {...props}>
                {item}
            </li>
        );
    }
}

Item.propTypes = {
    /** String or JSX that appears within the component */
    children: PropTypes.node.isRequired,
    /** CSS class names. */
    className: PropTypes.string,
    /** Determines level of padding of item */
    gutters: PropTypes.oneOf(["loose", "tight"]),
    /** Boolean to set faux focus of a list item */
    hasFauxFocus: PropTypes.bool,
    /** URL to navigate to when clicking on the item */
    href: PropTypes.string,
    /** Target that the link, if provided, should open in */
    hrefTarget: PropTypes.oneOf(["_self", "_blank"]),
    /** Sets the `title` attribute on an `href` */
    hrefTitle: PropTypes.string,
    /** Disable the item */
    isDisabled: PropTypes.bool,
    /** Function that is run when clicking on the item */
    onClick: PropTypes.func,
    /** Function that is run when mouse-down event is fired on the item */
    onMouseDown: PropTypes.func,
    /** Hook for automated JavaScript tests */
    testSection: PropTypes.string,
};

Item.defaultProps = {
    gutters: "loose",
};

Item.displayName = "BlockList.Item";

export default Item;
