import React, { useState, useCallback } from 'react';
import { classNames } from 'primereact/utils';
import { Controller } from 'react-hook-form';
import { Checkbox } from 'primereact/checkbox';
import { klona } from 'klona';
import { wrap } from 'object-path-immutable';

import { maxChecks, minChecks } from '../../../../helpers/validators';

const Checkboxes = ({
                        fieldName,
                        label,
                        control,
                        errors,
                        defaultValue = [],
                        config = {},
                        infoText = null,
                        options = [],
                        disabled = false
                    }) => {
    const [fieldVal, setFieldVal] = useState(defaultValue);

    const onCheckboxesChange = useCallback((e, updateFn) => {
        let data = [...fieldVal];

        if (e.checked) {
            data.push(e.value);
        } else {
            data.splice(data.indexOf(e.value), 1);
        }

        setFieldVal(data);
        updateFn(data);
    }, [fieldVal]);

    const properConfig = (config) => {
        let newConfig = klona(config);
        if (config.min) {
            newConfig = wrap(newConfig).set(['validate', 'minChecks'], (v) => minChecks(v, config.min)).value();
        }
        if (config.max) {
            newConfig = wrap(newConfig).set(['validate', 'maxChecks'], (v) => maxChecks(v, config.max)).value();
        }

        return newConfig;
    }

    const input = <Controller
        name={fieldName}
        control={control}
        defaultValue={fieldVal}
        rules={properConfig(config)}
        render={({ field, fieldState }) =>
            options.map(o => <div className="appForm__fieldItem" key={o.name}>
                <Checkbox
                    inputId={`${fieldName}_${o.name}`}
                    disabled={disabled}
                    name={fieldName}
                    value={o.name}
                    onChange={(e) => onCheckboxesChange(e, field.onChange)}
                    checked={field.value && field.value.includes ? field.value.includes(o.name) : false}
                    className={classNames({ 'p-invalid': fieldState.invalid })}/>
                <label htmlFor={`${fieldName}_${o.name}`}>{o.label}</label>
            </div>)}/>
    return (
        <>
            <label htmlFor={fieldName} className={classNames({ 'p-error': errors[fieldName] })}>
                {label}{config.required || config.isRequired ? <span className="appForm__field--required">*</span> : null}
            </label>
            {input}
            {infoText ? <small>{infoText}</small> : null}
        </>)
}

export default Checkboxes;