function _buildFormData(form_data, data, parentKey) {
    if (data && typeof data === 'object' && !(data instanceof Date) && !(data instanceof File) && !(data instanceof Blob)) {
        Object.keys(data).forEach(key => {
            _buildFormData(form_data, data[key], parentKey ? `${parentKey}[${key}]` : key);
        });
        return;
    }
    form_data.append(parentKey, data);
}

export function toFormData(payload) {
    if ( payload instanceof FormData ) {
        return payload;
    }
    var form_data = new FormData();
    _buildFormData(form_data, payload);
    return form_data;
}

export function formDataToObj(formData) {
    let obj = {};

    const fnGenerateStruct = (path, value) => {
        const reversed = path.reverse();

        let current = value;
        for (const field of reversed) {
            if (field == '') {
                current = [current];
                continue;
            }
            const tmp = {};
            tmp[ field ] = current;
            current = tmp;
        }
        return current;
    }

    for (var pair of formData.entries()) {
        // Case : handle depth
        // TODO : simplify
        if (pair[0].includes('[')) {
            const path = pair[0].split('[').map((item) => {
                return item.replace(/\]$/g, '');
            });
            let current = obj;
            for (let i = 0; i < path.length; i++) {
                const field = path[ i ];

                // Case : Array autoincrement
                if (field == '') {
                    current.push(
                        fnGenerateStruct(path.splice(i+1), pair[1])
                    );
                    break;
                }

                if (! current.hasOwnProperty(field)) {
                    current[ field ] = fnGenerateStruct(path.splice(i+1), pair[1]);
                    break;
                }
                
                current = current[ field ];
            }
            continue;
        }
        obj[ pair[0] ] = pair[1];
    }
    return obj;
}

export function getInputValue(input) {
    if (input.type == 'checkbox') {
        return input.checked ? '1' : '';
    }
    return input.value;
}

export function labelLike(el, event) {
    const inputText = el.querySelector('input[type="text"]');
    if (inputText) inputText.focus();

    const checkbox = el.querySelector('input[type="checkbox"]');
    if (checkbox && event && event.target != checkbox) {
        checkbox.checked = ! checkbox.checked;
        triggerChangeEvent(checkbox);
    }
}

/**
 * Change input value and simulate a change event
 */
export function setInputValue(input, value, eventOption = {}) {
    const oldValue = input.value;
    
    input.value = value;
    
    if (oldValue != value) 
        triggerChangeEvent(input, eventOption);
}