/**
 * Parse the attributes of provide element into choice object.
 * @param choiceInputElmt
 */
export function parseChoice(
    choiceInputElmt: HTMLInputElement,
    isNested = false
) {
    let choice: any;
    if (choiceInputElmt) {
        choice = {
            id: choiceInputElmt.id,
            name: choiceInputElmt.name,
            value: choiceInputElmt.value,
            isChecked: choiceInputElmt.checked,
            display: choiceInputElmt.dataset.display,
            isVisible: true,
        };

        if (isNested) {
            choice.isParent = choiceInputElmt.dataset.isparent;
            choice.parentValue = choiceInputElmt.dataset.parentid;
        }
    }

    return choice;
}

/**
 * Extract the data from the Drop Choice Component element under provided elmtId.
 * @param elmtId
 * @return
 * {
    "choices":[
        {
            "id":"...",
            "name":"...",
            "value":"...",
            "isChecked":(true|false),
            "display":"...",
            "isVisible":(true|false),
            "isParent":"(true|false)", //optional for non-nested choices
            "children":[ //optional for non-nested choices
                {
                    "id":"...",
                    "name":"...",
                    "value":"...",
                    "isChecked":(true|false),
                    "display":"...",
                    "isVisible":(true|false),
                    "parentValue":"..."
                },
                ...
            ],
            "isIndeterminate":(true|false) //optional for non-nested choices
        }
    ]
    }
 */
export function getMmuiDropChoiceData(elmtId: string, isNested = false) {
    let data = { choices: [] },
        elmt = document.getElementById(elmtId),
        choiceInputElmt,
        choiceInputElmts = elmt.querySelectorAll('.form-check-input'),
        choice;

    const parentChoices = [],
        childChoices = [];
    for (let i = 0; i < choiceInputElmts.length; i++) {
        choiceInputElmt = choiceInputElmts[i];
        choice = parseChoice(choiceInputElmt, isNested);
        if (isNested) {
            if (choice.isParent) {
                parentChoices.push(choice);
            } else {
                childChoices.push(choice);
            }
        } else {
            parentChoices.push(choice);
        }
    }

    if (childChoices.length > 0) {
        let parentChoice, childChoice;
        for (let p = 0; p < parentChoices.length; p++) {
            parentChoice = parentChoices[p];
            parentChoice.children = [];
            for (let c = 0; c < childChoices.length; c++) {
                childChoice = childChoices[c];
                if (childChoice.parentValue === parentChoice.value) {
                    parentChoice.children.push(childChoice);
                }
            }

            if (parentChoice.children.length > 0) {
                let isAllChecked = true,
                    isAnyChecked = false;
                for (let c = 0; c < parentChoice.children.length; c++) {
                    childChoice = parentChoice.children[c];

                    isAllChecked = isAllChecked && childChoice.isChecked;
                    isAnyChecked = isAnyChecked || childChoice.isChecked;
                }

                parentChoice.isChecked = isAllChecked;
                if (isAllChecked) {
                    parentChoice.isIndeterminate = false;
                } else {
                    parentChoice.isIndeterminate = isAnyChecked;
                }
            }
        }
    }

    data.choices = parentChoices;

    return data;
}

/**
 * Clone the provided choice.
 * @param choice - choice object to clone
 * @param copyChildren - whether to copy the children property into the new object.
 */
export function cloneChoice(choice: any, copyChildren = false) {
    const newChoice = {};

    for (const k in choice) {
        if (Object.prototype.hasOwnProperty.call(choice, k)) {
            if (k === 'children' && !copyChildren) {
                continue;
            }

            newChoice[k] = choice[k];
        }
    }

    return newChoice;
}

/**
 * Get checked choices from list of choices
 * @param choices
 */
export function getMmuiCheckedDropChoices(choices) {
    const checkedChoices = [];
    let choice;
    for (let c = 0; c < choices.length; c++) {
        choice = choices[c];
        if (choice.isChecked) {
            checkedChoices.push(choice);
        }
    }

    return checkedChoices;
}

/**
 * Get first checked choice from list of choices
 * @param choices
 */
export function getMmuiFirstCheckedDropChoice(choices) {
    let checkedChoice, choice;
    for (let c = 0; c < choices.length; c++) {
        choice = choices[c];
        if (choice.isChecked) {
            checkedChoice = choice;
            break;
        }
    }

    return checkedChoice;
}
