import React, { ChangeEvent, useState, useRef, useEffect } from 'react';
import { Wrapper, InputCheck, FakeCheck, CheckMark, IndeterminateMark } from './style';
import { useSpring } from 'react-spring';
import CheckboxGroup from './group';
import { ICheckbox } from './types';

const Checkbox = function({
    checked,
    children,
    onChange,
    disabled,
    indeterminate,
    defaultChecked,
    ...rest
}: ICheckbox) {
    const [isChecked, setCheck] = useState(false);
    const controlledCheck = 'checked' in arguments[0];

    const defaultSetted = useRef(false);
    const input = useRef();
    useEffect(() => {
        if (defaultChecked) {
            (input.current as any).checked = defaultChecked;
        }
    }, []);
    const [style, setStyle] = useSpring(() => ({
        transform: `scale(${isChecked ? 1 : 0}) rotate(45deg)`,
        config: { mass: 5, friction: 180, tension: 3500, clamp: true },
    }));

    if (controlledCheck && isChecked !== checked) {
        setCheck(checked as boolean);
        setStyle({ transform: `scale(${checked ? 1 : 0})) rotate(45deg)` });
    }
    if (defaultChecked && !defaultSetted.current) {
        defaultSetted.current = true;
        setCheck(true);
        setStyle({ transform: `scale(1) rotate(45deg)` });
    }
    const indStyle = useSpring({
        transform: `scale(${indeterminate ? 1 : 0})`,
        config: { mass: 5, friction: 180, tension: 3500, clamp: true },
    });
    return (
        <Wrapper disabled={disabled} {...rest}>
            <InputCheck
                ref={input}
                disabled={disabled}
                checked={controlledCheck ? isChecked : undefined}
                onChange={(e: ChangeEvent<HTMLInputElement>) => {
                    if (!controlledCheck) {
                        setCheck(e.target.checked);
                        setStyle({ transform: `scale(${e.target.checked ? 1 : 0})) rotate(45deg)` });
                    }
                    onChange && onChange(e.target.checked);
                }}
            />
            <FakeCheck checked={isChecked} disabled={disabled} indeterminate={indeterminate} />
            <IndeterminateMark style={indStyle} />
            {!indeterminate && <CheckMark style={style} />}
            {children && typeof children === 'string' ? <span>{children}</span> : children}
        </Wrapper>
    );
};
Checkbox.Group = CheckboxGroup;

export default Checkbox;
