// node modules
import React, {
    useState,
    useRef,
    FocusEvent,
    ChangeEvent,
    FC,
    ReactNode,
} from 'react';

// local components
import { Typography } from "../typography";

// local files
import clearIconSvg from '../../assets/clear.svg';
import { useStyles } from './styles';
import { theming } from '../../theme';

export interface InputProps {
    labelClassName?: string;
    rootClassName?: string;
    inputClassName?: string;
    onChange?: (e: ChangeEvent<HTMLInputElement> | Event)=> void;
    value?: string | number;
    label?: string;
    disabled?: boolean;
    onFocus?: (e: FocusEvent) => void;
    onBlur?: (e: FocusEvent) => void;
    type?: string;
    error?: boolean;
    adornmentStart?: string | ReactNode;
    adornmentEnd?: string | ReactNode;
    closeIcon?: boolean;
    autoFocus?: boolean;
}

export const Input: FC<InputProps> = ({
    error= false,
    type= 'text',
    disabled = false,
    labelClassName,
    rootClassName,
    inputClassName,
    onChange,
    label,
    value,
    onFocus,
    onBlur,
    adornmentEnd,
    adornmentStart,
    closeIcon,
    autoFocus,
    ...otherProps
}) => {
    const {
        root,
        labelClass,
        active,
        input,
        unlabeled,
        disabledClass,
        errorClass,
        typeWrapper,
        clearIconClass,
        inputAdorned,
        inputAdornedActive
    } = useStyles({
        theme: theming.useTheme(),
        adornmentEnd,
        adornmentStart
    });
    const inputEl = useRef({} as HTMLInputElement);
    const [activeClass, setActiveClass] = useState(false);

    const handleFocus = (e: FocusEvent<HTMLInputElement>) => {
        if(disabled) return;

        setActiveClass(true);

        if (onFocus) {
            onFocus(e)
        }
    }
    const handleBlur = (e: FocusEvent<HTMLInputElement>) => {
        setActiveClass(!!e.target.value)

        if(onBlur) {
            onBlur(e)
        }
    }
    const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
        if (onChange) {
            onChange(e)
        }
    }
    const handleClean = () => {
        const evt = new Event('change');
        const { current } = inputEl;

        current.value = '';

        const event = {
            ...evt,
            target: current,
            currentTarget: current
        }

        if (onChange) {
            onChange(event);
        }

        current.focus();
    }

    let adornmentClass = '';

    if (adornmentStart) {
        adornmentClass = `${inputAdorned} ${!!value || activeClass ? inputAdornedActive : ''}`;
    }

    const classNameLabel = `${labelClass} ${labelClassName} ${!!value || activeClass ? active : ''} ${adornmentClass}`
    const rootClass = `${root} ${rootClassName} ${disabled ? disabledClass: ''} ${error ? errorClass : '' }`
    const inputClass = `${input} ${!label ? unlabeled : ''}`

    return (
        <div className={rootClass}>
            {adornmentStart && (
                <div className={typeWrapper}>
                    <Typography variant="body1">
                        {adornmentStart}
                    </Typography>
                </div>
            )}
            {label && <Typography variant="body2" className={classNameLabel}>{label}</Typography>}
            <input
                ref={inputEl}
                type={type}
                disabled={disabled}
                onBlur={handleBlur}
                onFocus={handleFocus}
                className={inputClass}
                value={value}
                onChange={handleChange}
                {...otherProps}
            />
            {adornmentEnd && (
                <div className={typeWrapper}>
                    <Typography variant="body1">
                        {adornmentEnd}
                    </Typography>
                </div>
            )}
            {closeIcon && value && (
                <img className={clearIconClass} onClick={handleClean} src={clearIconSvg} alt=""/>
            )}
        </div>
    )
}
