import * as React from 'react';

/**
 * Number Input Form Component
 * @param index
 * @param name
 * @param step
 * @param formData
 * @param formDataArray
 * @param updateFormDataArray
 * @constructor
 */
export const MmuiDynamicNumberInputComponent = ({
    index,
    name,
    attributes,
    formDataArray,
    updateFormDataArray,
    parseFunc = parseInt,
    validationFunc = undefined,
    triggerOnBlur = undefined,
}) => {
    const elmtName = name + `_${index}`,
        elmtId = `id_${elmtName}`,
        value = formDataArray[index][name],
        onChange = (e) => {
            let newValue = parseFunc(e.target.value);
            if (isNaN(newValue)) {
                newValue = e.target.value;
            }
            const formDataArrayClone = JSON.parse(
                JSON.stringify(formDataArray)
            );
            formDataArrayClone[index][name] = newValue;
            updateFormDataArray(formDataArrayClone);
        };

    let onBlur;
    if (triggerOnBlur) {
        onBlur = (e) => {
            triggerOnBlur(e.target.value);
        };
    } else if (validationFunc) {
        onBlur = (e) => {
            const formDataArrayClone = JSON.parse(
                JSON.stringify(formDataArray)
            );
            formDataArrayClone[index][`${name}_errors`] = validationFunc(
                e.target.value,
                attributes
            );
            updateFormDataArray(formDataArrayClone);
        };
    }

    return (
        <>
            <input
                className="form-control mmui-form-control"
                type="number"
                name={elmtName}
                {...attributes}
                value={value}
                id={elmtId}
                onChange={onChange}
                onBlur={onBlur}
            />
        </>
    );
};

export const MmuiDynamicChoiceRadioComponent = ({ index, name, options, formDataArray, updateFormDataArray, onChange }) => {
    const elmtName = name + `_${ index }`,
        elmtId = `id_${ elmtName }`,
        value = formDataArray[index][name],
        onComponentChange = (e) => {
            let formDataArrayClone = JSON.parse(JSON.stringify(formDataArray));
            formDataArrayClone[ index ][name] = e.target.value;
            updateFormDataArray(formDataArrayClone);
            onChange(e);
        }
    ;

    const radioSelectOptions = options.map((d: {label:string, value:string}) => {
        return (
            <div className="form-check form-check-inline mmui-form-check-inline" key={ d.value }>
                <input className="form-check-input" type="radio" id={ elmtId + "_" + d.value } name={ elmtName } value={ d.value } onChange={ onComponentChange } checked={ value === d.value }/>
                <label className="form-check-label mmui-form-check-label" htmlFor={ elmtId + "_" + d.value }>{ d.label }</label>
            </div>
        )
    });

    return (
        <>
            { radioSelectOptions }
        </>
    )
}

export const MmuiDynamicSelectComponent = ({ index, name, options, formDataArray, updateFormDataArray }) => {
    const elmtName = name + `_${ index }`,
        elmtId = `id_${ elmtName }`,
        value = formDataArray[index][name],
        onChange = (e) => {
            let formDataArrayClone = JSON.parse(JSON.stringify(formDataArray));
            formDataArrayClone[ index ][name] = e.target.value;
            updateFormDataArray(formDataArrayClone);
        }
    ;

    const selectOptions = options.map((d: {label:string, value:string}, index) => {
        let key = `error-${index}`;
        return (
            <option key={key} id={ elmtId + "_" + d.value } value={ d.value } data-display={ d.label } selected={ value === d.value }>
                { d.label }
            </option>
        )
    });

    return (
        <div className="mmui-custom-select">
            <div className="mmui-dropdown-toggle"></div>
            <select name={ elmtName }  id={ elmtId } onChange={ onChange }>
                { selectOptions }
            </select>
        </div>
    )
}

export const MmuiDynamicTextInputComponent = ({ index, name, attributes, formDataArray, updateFormDataArray, validationFunc = undefined }) => {
    const elmtName = name + `_${ index }`,
        elmtId = `id_${ elmtName }`,
        value = formDataArray[index][name],
        onChange = (e) => {
            let formDataArrayClone = JSON.parse(JSON.stringify(formDataArray));
            formDataArrayClone[ index ][name] = e.target.value;
            updateFormDataArray(formDataArrayClone);
        }
    ;

    let onBlur;
    if(validationFunc){
        onBlur = (e) => {
            let formDataArrayClone = JSON.parse(JSON.stringify(formDataArray));
            formDataArrayClone[ index ][`${name}_errors`] = validationFunc(e.target.value, attributes);
            updateFormDataArray(formDataArrayClone);
        }
    }

    return (
        <input className="form-control mmui-form-control" type="text" name={ elmtName } {...attributes} value={ value } id={ elmtId } onChange={ onChange } onBlur={onBlur} />
    )
}

export const MmuiErrorsComponent = ({ fieldId, errors }) => {

    let errorsOutput = null;
    if( errors ){
        let errorsArrayOutput = errors.map((e, index) => {
            let key = `error-${index}`;
            return (
                <div key={key} className="mmui-form-error-msg">{e}</div>
            )
        });

        let id = `${fieldId}_errors`;
        errorsOutput = (
            <div id={id}>
                {errorsArrayOutput}
            </div>
        )
    }

    return errorsOutput;
}

export function parseInputElementAttributes(element: HTMLInputElement){

    const attributes:any = {};
    if (element.hasAttributes()) {
        let attrs = element.attributes;
        for(let i = 0; i < attrs.length; i++) {
            switch(attrs[i].name){
                case "required":
                    attributes[attrs[i].name] = true;
                    break;
                case "id":
                case "value":
                case "min":
                case "max":
                case "maxlength":
                case "step":
                    attributes[attrs[i].name] = attrs[i].value;
                    break;
            }
        }
    }

    return attributes;
}

export function getInputElementAttributes(selector:string) {
    const element = document.querySelector(selector) as HTMLInputElement;
    return parseInputElementAttributes(element);
}

export function getChoices(name:string) {
    const elements = document.getElementsByName(name);
    let choices: Array<Object> = [];

    for (let i = 0; i < elements.length; i++) {
        let element = elements[i] as HTMLInputElement;
        let label = document.querySelector("[for=" + element.id + "]");
        choices.push({label: label.textContent, value: element.value});
    }
    return choices
}

export function getSelectOptions(selector:string) {
    const element = document.querySelector(selector);
    let options: Array<Object> = [];

    for (let i = 0; i < element.children.length; i++) {
            let option = element.children[i] as HTMLInputElement;
            options.push({label:option.innerText, value:option.value});
    }
    return options
}
