import React, { FC, memo, useEffect, useMemo, useRef } from 'react';
import { CallbackFunctionVariadic }                    from '@geenee/geeclient-kit/src/lib/type/type';
import { Wrapper }                                     from '../../..';
import { cn }                                          from '../../util/bem';
import { SizeType }                                    from '../../util/global-props';
import { useDropdown }                                 from './dropdown.hook';
import { DropdownItem }                                from './dropdown-item.component';
import './dropdown.component.scss';

export type DropdownPropsType = {
    className?: string;
    menu?: ((callBack: CallbackFunctionVariadic) => React.ReactNode) | React.ReactNode;
    items?: React.ReactNode;
    children: ((dropdownOpen: boolean) => React.ReactNode) | React.ReactNode ;
    disabled?: boolean;
    viewType?: 'primary' | 'secondary';
    fullWidth?: boolean;

    isChangeOutside?: boolean;
    isChanged?: (open: boolean) => void;
    isOpen?: boolean;

    margin?: SizeType;
    flex?: number | string;
    menuWidth?: string;
    position?:
        'auto-vertical-left'
        | 'auto-vertical-center'
        | 'auto-vertical-right'
        | 'bottom-left'
        | 'bottom-center'
        | 'bottom-right'
        | 'top-left'
        | 'top-center'
        | 'top-right';
    onSelect?: (e: React.SyntheticEvent, id: string) => void;
    closeOnSelect?: boolean;
    style?: React.CSSProperties;

}

const className = cn('dropdown');

export const Dropdown: FC<DropdownPropsType> = memo((props) => {
    const triggerEl  = useRef(null);
    const dropdownEl = useRef(null);

    const [ dropdownOpen, toggleDropdownOpen, autoPosition ] = useDropdown(
        dropdownEl.current,
        triggerEl.current,
        props.closeOnSelect,
        props.isOpen,
        props.isChangeOutside,
        props.position
    );
    // const [ mounted, setMounted ] = useState(false);
    const onClick = () => {
        toggleDropdownOpen();
    };

    useEffect(() => {
        if (props.isChanged) {
            props.isChanged(dropdownOpen);
        }
    }, [ dropdownOpen, dropdownOpen ]);

    const renderMenuContent = useMemo(() => (
        typeof props.menu === 'function' ? props.menu && props.menu(toggleDropdownOpen) : props.menu
    ), [ props.menu ]);

    return (
        <div
            className={
                className({
                    disabled:    props.disabled,
                    'menu-mode': !!props.menu,
                    margin:      props.margin,
                    flex:        props.flex,
                    fullWidth:   props.fullWidth
                }, null, props.className)
            }
            style={ props.style }
        >
            <div
                className={ className('trigger') }
                ref={ triggerEl }
            >
                <div onClick={ onClick }>
                    { typeof props.children === 'function' ? props.children && props.children(dropdownOpen) : props.children }
                </div>
            </div>

            <div
                className={ className(
                    'menu',
                    {
                        position: autoPosition || props.position,
                        open:     dropdownOpen,
                        type:     props.viewType
                    }
                ) }
                ref={ dropdownEl }
                style={ props.menuWidth ? { width: props.menuWidth } : { width: '200px' } }
                onClick={ (e) => {
                    e.preventDefault();
                    e.stopPropagation();
                } }
            >
                <Wrapper
                    className={ className('menu-wrapper') }
                    fullWidth
                >
                    { props.menu
                        ? renderMenuContent
                        : (
                            <Wrapper className={ className('menu-wrapper') }>
                                {
                                    React.Children.map(props.items, (child, i) => (
                                        React.isValidElement(child)
                                            ? (
                                            // @ts-ignore
                                                <DropdownItem
                                                    id={ i }
                                                    onSelect={ (
                                                        // @ts-ignore
                                                        e,
                                                        // @ts-ignore
                                                        id
                                                    ) => {
                                                        if (!props.disabled) {
                                                            // @ts-ignore
                                                            props.onSelect(e, id);
                                                        }
                                                        if (props.closeOnSelect) {
                                                            toggleDropdownOpen();
                                                        }
                                                    } }
                                                >
                                                    { React.cloneElement(child) }
                                                </DropdownItem>
                                            ) : null))
                                }
                            </Wrapper>
                        ) }
                </Wrapper>
            </div>

        </div>
    );
});

Dropdown.defaultProps = {
    disabled:      false,
    closeOnSelect: false,
    position:      'bottom-left',
    viewType:      'primary'
};
