import { isUndefined, noop } from "lodash";
import React from "react";
import classNames from "classnames";

type DropdownContentsProps = {
    /** Label for the dropdown contents for screen readers */
    ariaLabel?: string;
    /** Whether contents can scroll */
    canScroll?: boolean;
    /** Children of the element. */
    children?: any;
    /** CSS class names. */
    className?: string;
    /** Direction of contents */
    direction?: "left" | "right" | "up";
    /* Defines Maximum container height */
    maxHeight?: string | number;
    /** Whether or not the dropdown is in a loading state. */
    isLoading?: boolean;
    /** Whether to wrap contents or not */
    isNoWrap?: boolean;
    /** Minimum width of contents */
    minWidth?: string | number;
    /** Optional render function to display a header before the list. */
    renderHeader?: (...args: any[]) => any;
    /** Test section for element */
    testSection?: string;
};

export const DropdownContents: React.SFC<DropdownContentsProps> = React.forwardRef(
    ({
        ariaLabel,
        canScroll,
        children,
        className,
        direction,
        maxHeight,
        isLoading,
        isNoWrap,
        minWidth,
        renderHeader = noop,
        testSection,
        ...props
    }: DropdownContentsProps, ref?: React.Ref<HTMLDivElement>) => {
        const styleProps: React.CSSProperties = {};
        if (!isUndefined(isLoading)) {
            // Supports loading spinner over <ul> contents
            styleProps.position = "relative";
        }
        if (minWidth) {
            styleProps.minWidth = minWidth;
        }
        if (canScroll) {
            styleProps.overflowY = "visible";
            styleProps.maxHeight = "none";
        }
        const wrapperClasses = classNames({
            nowrap: isNoWrap,
            "oui-dropdown": true,
            "oui-dropdown--right": direction === "left",
            "oui-dropdown--up": direction === "up",
        }, className);
        const listClasses = classNames({ "min-height--100": isLoading });

        const wrapperStyles: React.CSSProperties = {};

        if (maxHeight) {
            wrapperStyles.maxHeight = maxHeight;
        }

        return (
            <div ref={ref} className={wrapperClasses} style={wrapperStyles} {...props}>
                {renderHeader()}
                <ul
                    className={listClasses}
                    role="listbox"
                    aria-label={ariaLabel}
                    style={styleProps}
                    {...(testSection ? { "data-test-section": testSection } : {})}
                >
                    {children}
                </ul>
            </div>
        );
    }
);

DropdownContents.displayName = "DropdownContents";

DropdownContents.defaultProps = {
    canScroll: false,
    direction: "left",
    isLoading: undefined,
    isNoWrap: false,
    testSection: "",
};

export default DropdownContents;
