import React, { FC, memo, useRef, useState } from 'react';
import { cn }                                from '../../util/bem';
import { FormSizesType, SizeType }           from '../../util/global-props';
import { IconPropsType }                     from '../icon/icon.component';
import { iconMap }                           from '../icon/icon.library';
import { useDynamicRows }                    from './textarea.hook';
import './textarea.component.scss';

export type TextAreaPropsType = {
    className?: string;
    value?: string;
    defaultValue?: string;
    placeholder?: string;

    icon?: keyof typeof iconMap;
    iconColor?: IconPropsType['color'];
    after?: React.ReactNode;
    before?: React.ReactNode;

    size?: FormSizesType;
    flex?: number;
    margin?: SizeType;
    style?: React.CSSProperties;

    autoSize?: boolean;
    minRows?: number;
    maxRows?: number;

    autoFocus?: boolean;
    disabled?: boolean;
    fullWidth?: boolean;
    transparent?: boolean;
    readOnly?: boolean;
    required?: boolean;

    onChange?: React.ChangeEventHandler<HTMLTextAreaElement>;
    onClick?: React.MouseEventHandler<HTMLTextAreaElement>;
    onFocus?: React.FocusEventHandler<HTMLTextAreaElement>;
    onBlur?: React.FocusEventHandler<HTMLTextAreaElement>;
    onKeyDown?: React.KeyboardEventHandler<HTMLTextAreaElement>;
    onKeyPress?: React.KeyboardEventHandler<HTMLTextAreaElement>;
    onKeyUp?: React.KeyboardEventHandler<HTMLTextAreaElement>;
}

const className = cn('text-area');

export const TextArea: FC<TextAreaPropsType> = memo((props) => {
    const ref  = useRef<HTMLTextAreaElement>(null);
    const [ focus, setFocus ] = useState(false);

    const rows = useDynamicRows(
        ref,
        {
            min:    props.minRows,
            max:    props.maxRows,
            value:  props.value,
            enable: props.autoSize
        }
    );

    const handleFocus = (event: React.FocusEvent<HTMLTextAreaElement>) => {
        setFocus(true);
        if (props.onFocus) {
            props.onFocus(event);
        }
    };
    const handleBlur = (event: React.FocusEvent<HTMLTextAreaElement>) => {
        setFocus(false);
        if (props.onBlur) {
            props.onBlur(event);
        }
    };

    return (
        <div
            className={ className({
                margin:      props.margin,
                flex:        props.flex,
                size:        props.size,
                transparent: props.transparent
            }, null, props.className) }
        >
            <div className={ className('wrapper') }>
                <textarea
                    className={ className({ focus }) }
                    rows={ rows }
                    value={ props.value }
                    defaultValue={ props.defaultValue }
                    placeholder={ props.placeholder }

                    disabled={ props.disabled }
                    readOnly={ props.readOnly }
                    required={ props.required }

                    ref={ ref }
                    autoFocus={ props.autoFocus }
                    onChange={ props.onChange }
                    onClick={ props.onClick }
                    onFocus={ handleFocus }
                    onBlur={ handleBlur }
                    onKeyDown={ props.onKeyDown }
                    onKeyPress={ props.onKeyPress }
                    onKeyUp={ props.onKeyUp }
                />
            </div>
        </div>
    );
});

TextArea.defaultProps = {
    size:    'lg',
    minRows: 3
};
