import mask from "./mask";

const form = {
    /**
     * Возвращает массив с данными полей формы
     * @returns Возвращает массив данных полей [...{name, input, container, value}]
     */
    getFields(form: HTMLElement, selector: string = '.j-input') {
        const inputsForm = form.querySelectorAll(selector);
        let inputs: any = [];

        inputsForm.forEach(input => {
            inputs.push({
                container: input,
                input: input.querySelector('[name]'),
                name: input.querySelector('[name]').getAttribute('name'),
                value: input.querySelector<any>('[name]').value
            })
        });

        return inputs
    },

    /**
     * Возвращает обьект с данными поля формы
     * @returns {object} Возвращает данные поля {name, input, container, value}
     */
    getField(element: any) {
        return {
            container: element,
            input: element.querySelector('[name]'),
            name: element.querySelector('[name]').getAttribute('name'),
            value: element.querySelector('[name]').value
        }
    },

    /**
     * Обработчик полей формы, валидирует поля формы
     * @param {HTMLElement} element Элемент валидации
     * @param {object} options Параметры, на которые нужно проверять поле {empty, text, number, phone, email}
     */
    handlerChange(element: any, options: any = {}) {
        if ('text' in options && options.text) {
            element.value = mask.string(this.getField(element).input).value
        }

        if ('phone' in options && options.phone) {
            mask.phone(this.getField(element).input)
        }

        this.getField(element).input.addEventListener('keydown', () => {
            this.validate(this.getField(element), options)
        })
        this.getField(element).input.addEventListener('input', () => {
            this.validate(this.getField(element), options)
        })
    },

    /**
     * Валидация поля формы
     * @param {object} element - обьект с данными поля {name, input, container, value}
     * @param {object} options - параметры валидации {empty, text, number, phone, email}
     * @param {object} result - обьект, с результатами валидации {name: true|false}     *
     * @returns {object} возвращает результат валидаци {name: true|false}
     */
    validate(element: any, options: any = {}, result: any = {}) {
        // сбрасываем состояния
        result[element.name] = false;

        if ('empty' in options && options.empty) {
            element.container.removeAttribute('data-error')
            element.container.removeAttribute('data-accept')

            if (element.value.length < 1) {
                element.container.setAttribute('data-error', '');
                result[element.name] = true;
            } else {
                result[element.name] = false;
                element.container.setAttribute('data-accept', '');
            }
        }

        if ('phone' in options && options.phone && element.value.length == 17 && element.value.indexOf('_') < 0) {
            element.container.removeAttribute('data-error')
            element.container.removeAttribute('data-accept')

            element.container.setAttribute('data-accept', '');
            result[element.name] = false;
        } else if ('phone' in options && options.phone) {
            element.container.removeAttribute('data-error')
            element.container.removeAttribute('data-accept')

            element.container.setAttribute('data-error', '');
            result[element.name] = true;
        }

        if ('email' in options && options.email && element.value.match(/^([\w.%+-]+)@([\w-]+\.)+([\w]{2,})$/i)) {
            element.container.removeAttribute('data-error')
            element.container.removeAttribute('data-accept')

            element.container.setAttribute('data-accept', '');
            result[element.name] = false;
        } else if ('email' in options && options.email) {
            element.container.removeAttribute('data-error')
            element.container.removeAttribute('data-accept')

            element.container.setAttribute('data-error', '');
            result[element.name] = true;
        }

        return result;
    },

    /**
     * Возвращает true если есть ошибки при валидации
     * @param {object} error Результат валидации {name: true|false}
     */
    checkError(error: any) {
        for (let key in error) {
            if (error[key]) {
                return true
            }
        }
        return false
    },

    /**
     * Очищает значение
     * @param {HTMLElement} element
     */
    clear(element: any) {
        element.value = ''
    }
}

export default form