import * as React from 'react';
import * as _ from 'lodash';
import * as DefaultStyles from './style';
import { DropDownEmptyState } from './DropDownEmptyState';
import { DropDownItem } from './DropDownItem';

export namespace DropDownDrawer {
    export interface Props {
        /**
         * Custom component to show when no options
         */
        customEmptyStateMessage?: JSX.Element;
        /**
         * Message to show when no options
         */
        emptyStateMessage?: string;
        /**
         * Chunk to be highlighted inside the options
         */
        highlightedChunk?: string;
        /**
         * Indicates the position of the selected option, which will be highlighted
         */
        selectedOption: number;
        /**
         * Function called when the user hovers on an option is clicked. The option is passed as parameter
         */
        onHoverOption: (event, option: { toString: () => string }, position: number) => void;
        /**
         * Function called when an option is clicked. The option is passed as parameter
         */
        onSelectOption: (event, option: { toString: () => string }) => void;
        /**
         * List of options to be displayed
         */
        options: { toString: () => string }[];
        /**
         * Prop to customize styles
         */
        styles?: Styles;

        id?: string;

        name?: string;
    }

    export interface Styles {
        /**
         * Styles for the container of the entire component
         */
        Container?: any;
        /**
         * Styles for the component shown when there are no options
         */
        DropDownEmptyState?: DropDownEmptyState.Styles;
        /**
         * Styles for the component that renders each option
         */
        DropDownItem?: DropDownItem.Styles;
        /**
         * Styles for the wrapper that contains all the options
         */
        List?: any;
    }
}

/**
 * Component that displays a dropdown, with its options.
 * 
 * @version 1.0.0
 * 
 */
export class DropDownDrawer extends React.Component<DropDownDrawer.Props> {
    constructor(props: DropDownDrawer.Props) {
        super(props);
    }

    renderItemList = (Styles: DropDownDrawer.Styles) => (
        <Styles.List className='drop-down-drawer-list' id={this.props.id + '-list'}>
            {
                this.props.options.map((option, index) => (
                    <DropDownItem
                        focused={index === this.props.selectedOption}
                        highlightedChunk={this.props.highlightedChunk}
                        key={index}
                        onClick={this.props.onSelectOption}
                        onMouseEnter={this.props.onHoverOption}
                        position={index}
                        styles={Styles.DropDownItem}
                        value={option}
                        id={this.props.id && this.props.id + '-' + index.toString()}
                        name={this.props.name && this.props.name + '-' + index.toString()}
                    />
                ))
            }
        </Styles.List>
    );

    renderEmptyState = (Styles: DropDownDrawer.Styles) => (
        <DropDownEmptyState
            customMessage={this.props.customEmptyStateMessage}
            message={this.props.emptyStateMessage}
            styles={Styles.DropDownEmptyState}
            id={this.props.id}
            name={this.props.name && this.props.name}
        />
    );

    render() {
        const Styles: DropDownDrawer.Styles = _.merge(DefaultStyles, this.props.styles);
        return (
            <Styles.Container
                className={'drop-down-drawer-container'}
                id={this.props.id && this.props.id + '-container-div'}
                name={this.props.name && this.props.name + '-container-div'}
            >
                {
                    this.props.options.length > 0 ?
                        this.renderItemList(Styles)
                        :
                        this.renderEmptyState(Styles)
                }
            </Styles.Container>
        );
    }
}
