import React, { FC, memo, MouseEventHandler, useEffect, useRef } from 'react';
import { Description, Icon }                                     from '../../..';
import { cn }                                                    from '../../util/bem';
import { FormSizesType, SizeType }                               from '../../util/global-props';
import { iconMap }                                               from '../icon/icon.library';
import './radio.component.scss';

export type RadioPropsType = {
    className?: string;
    label?: React.ReactNode;
    disabled?: boolean;
    checked?: boolean;
    defaultChecked?: boolean;
    value?: string;
    iconMargin?: SizeType;

    autoFocus?: boolean;
    height?: FormSizesType;
    margin?: SizeType;
    size?: 'sm' | 'md' | 'lg';
    style?: React.CSSProperties;
    viewType?: 'block' | 'radio';
    theme?: 'primary' | 'primary-green' | 'primary-white' | 'secondary' | 'dark' | 'transparent' | 'alert';
    icon?: keyof typeof iconMap;

    flex?: number;

    onChange?: (val: string | boolean) => void;
    onClick?: MouseEventHandler<HTMLInputElement>;
    onMouseUp?: MouseEventHandler<HTMLInputElement>;

    tabIndex?: number;
    children?: React.ReactNode;
}

const classNames = cn('radio');

export const Radio: FC<RadioPropsType> = memo((props) => {
    const node = useRef<HTMLInputElement>(null);

    const getIconColor = () => {
        if (props.theme === 'primary' || props.theme === 'alert' || props.theme === 'dark') {
            return 'white';
        }
        return 'dark';
    };

    useEffect(() => {
        if (node.current && props.autoFocus && !props.disabled) {
            node.current.focus();
        }
    }, [ props.autoFocus, props.disabled ]);

    const handleClick = () => {
        if (props.disabled || props.defaultChecked) {
            return;
        }
        if (props.value && props.onChange) {
            props.onChange(props.value);
            return;
        }
        if (props.onChange) {
            props.onChange(!props.checked);
        }
    };

    const isChecked = props.checked || props.defaultChecked;
    return (
        <div
            className={ classNames({
                checked:  isChecked,
                disabled: props.disabled,
                height:   props.height,
                margin:   props.margin,
                label:    !!props.label,
                size:     props.size,
                block:    props.viewType === 'block',
                theme:    props.theme
            }, null, props.className) }
            onClick={ handleClick }
            ref={ node }
            style={ props.style }
        >
            <input
                type="radio"
                value={ props.value || undefined }
                aria-checked={ isChecked }
                tabIndex={ props.tabIndex }
                disabled={ props.disabled }

            />
            <span className={
                classNames(
                    'element',
                    { checked: isChecked }
                )
            }
            >
                { props.viewType === 'block'
                && (
                    <>
                        { props.icon
                        && <Icon margin={ props.iconMargin } name={ props.icon } color={ getIconColor() } /> }
                        { props.children }
                    </>
                ) }
            </span>
            { props.label && props.viewType === 'radio'
                ? (
                    <Description>
                        { props.label }
                    </Description>
                )
                : null }
        </div>
    );
});

Radio.defaultProps = {
    defaultChecked: false,
    disabled:       false,
    iconMargin:     'xs',
    autoFocus:      false,
    size:           'sm',
    viewType:       'radio',
    theme:          'primary'
};
