import React, { FC, memo, useCallback, useState } from 'react';
import { cn }                                     from '../../util/bem';
import { SizeType }                               from '../../util/global-props';
import { FormValidationError }                    from '../form-validation-error/form-validation-error.component';
import { Title }                                  from '../title/title.component';
import { Wrapper }                                from '../wrapper/wrapper.component';
import './form-item.component.scss';

type FormItemPropsType = {
    children: React.ReactNode;
    errorComponent?: React.ComponentType<{ error?: string | React.ReactNode }>;
    label?: React.ReactNode;
    weight?: 'bold' | 'regular';
    error?: string | React.ReactNode;
    focused?: boolean;
    className?: string;
    margin?: SizeType;
    autoFocusDetect?: boolean;
}

const className = cn('form-item');

export const FormItem: FC<FormItemPropsType> = memo((props) => {
    const [ focused, setFocused ] = useState(false);
    const onFocus = useCallback(() => {
        setFocused(true);
    }, []);
    const onBlur = useCallback(() => {
        setFocused(false);
    }, []);

    const { errorComponent: ErrorComponent } = props;
    return (
        <div className={ className({
            focused:  props.autoFocusDetect ? focused : props.focused,
            hasError: !!props.error,
            margin:   props.margin
        }, null, props.className) }
        >
            { props.label && (
                <div className={ className('label') }>
                    <Title weight={ props.weight }>{ props.label }</Title>
                </div>
            ) }
            <Wrapper className={ className('content') }>
                { props.autoFocusDetect
                    ? React.cloneElement(props.children as React.ReactElement, {
                        onFocus,
                        onBlur
                    })
                    : props.children }

                { props.error && ErrorComponent && (
                    <div className={ className('error') }>
                        { /* @ts-ignore */ }
                        <ErrorComponent error={ props.error } />
                    </div>
                ) }
            </Wrapper>
        </div>
    );
});

FormItem.defaultProps = {
    errorComponent: FormValidationError,
    margin:         'md'
};
