import React, { FC, memo }                       from 'react';
import { cn }                                    from '../../util/bem';
import { IconColorType, RadiusSizesType, sizes } from '../../util/global-props';
import { iconMap }                               from './icon.library';
import './icon.component.scss';

export type IconPropsType = {
    className?: string;
    name: keyof typeof iconMap;
    size?: number;
    color?: IconColorType;
    frame?: 'solid' | 'opacity' | 'default' | 'none';
    solid?: boolean;
    margin?: keyof typeof sizes;
    style?: React.CSSProperties;
    rounded?: boolean;
    radius?: RadiusSizesType;
    ref?: React.Ref<HTMLDivElement>;
    onClick?: React.EventHandler<React.MouseEvent<HTMLDivElement, PointerEvent>>;
    onMouseEnter?: React.EventHandler<React.MouseEvent<HTMLDivElement, PointerEvent>>;
    onMouseLeave?: React.EventHandler<React.MouseEvent<HTMLDivElement, PointerEvent>>;
}

const classNames = cn('icon');

export const Icon: FC<IconPropsType> = memo((props) => {
    const icon: JSX.Element | { [ size: string]: JSX.Element } = iconMap[ props.name ];

    const getSize = () => {
        let size: number | null = null;

        const { size: initSize } = props;
        if (initSize) {
            Object.keys(icon).forEach((key) => {
                if (initSize >= parseInt(key, 10)) {
                    size = parseInt(key, 10);
                }
            });
        }
        return size;
    };

    const getIcon = (): React.ReactNode => {
        const size = getSize();
        return (size && icon[ size ] ? icon[ size ] : icon) as React.ReactNode;
    };

    return (
        <div
            className={
                classNames({
                    color:  props.color,
                    frame:  props.frame,
                    solid:  props.solid,
                    margin: props.margin,
                    radius: props.radius
                }, null, props.className)
            }
            style={ {
                minWidth:  `${ props.size }px`,
                minHeight: `${ props.size }px`,
                width:     `${ props.size }px`,
                height:    `${ props.size }px`,
                cursor:    props.onClick && 'pointer',
                ...props.style,
                ...props.rounded && { borderRadius: `${ props.size }px` }

            } }
            ref={ props.ref }
            onClick={ props.onClick }
            onMouseEnter={ props.onMouseEnter }
            onMouseLeave={ props.onMouseLeave }
        >
            { getIcon() }
        </div>
    );
});

Icon.defaultProps = {
    size:    16,
    color:   'dark',
    frame:   'none',
    solid:   false,
    rounded: false
};
