define([
    '../../core/utils/data',
    '../../core/utils/helper',
    '../../core/utils/method',
    '../../core/models/index'
], (data, helper, method, model) => {
    (function($) {
        new method('input', {
            init: function (element) {
                const context = this;

                const options = context.local._options;
                const $label = $(context.$helper.parseTemplate('label')).insertAfter(element);
                const $placeholder = $(context.$helper.parseTemplate('placeholder')).text(element.attr('placeholder') || element.attr('title'));
                const type = element.data('type') || (options ? options.type : '');
                let placeholder = '';

                let validation = false;
                const changeDetector = function (value) {
                    value = value || element.val();

                    placeholder = element.attr('placeholder');
                    if (placeholder) {
                        $label.addClass('works-input-label-placeholder');
                        $placeholder.text(placeholder);
                        element.attr('placeholder', '');
                    }

                    if (element.is(':focus')) {
                        $label.addClass('works-input-focus');
                        $label.addClass('works-input-lock');
                    }
                    else {
                        $label.removeClass('works-input-focus');
                        if (!value) {
                            $label.removeClass('works-input-lock');
                        }
                        else {
                            $label.addClass('works-input-lock');
                        }
                    }
                };

                /* jshint ignore:start */
                /* @DATE 2016. 06. 28 */
                /* @USER Kenneth */


                /* @NOTE dataset에서 받아오는 boolean 타입 보정 !!구문 유효성문제로 인해 escape 처리. */
                if (typeof options.validation !== 'object' || !!options.validation.disable !== true) {
                    validation = true;
                }
                /* jshint ignore:end */

                rule = {
                    notnull: element.attr('notnull') || true,
                    minlen:  element.attr('minlen') || 0,
                    maxlen:  element.attr('maxlen') || 10,
                    numeric: element.attr('numeric') || false,
                };

                context.local.type = type;
                context.local.rule = rule;

                if (element.is(':visible') === true && options.static === true && element.hasClass('input-block') === false) {
                    $label.width(element.outerWidth());
                }
                element.appendTo($label);
                $placeholder.insertBefore(element);

                context.$helper.bind(element, 'focus', () => {
                    $label
                        .addClass('works-input-lock')
                        .addClass('works-input-focus');
                    if (validation === true) {
                        context.local._prototype.validation.call(context, element, 'clear');
                    }
                });

                context.$helper.bind(element, 'blur', event => {
                    if (type === 'number') {
                        element.val(element.val().replace(/[^\d.]+/gi, ''));
                    }

                    if (event.originalEvent) {
                        if (validation === true) {
                            context.local._prototype.validation.call(context, element);
                        }
                    }

                    if (!element.val()) {
                        $label.removeClass('works-input-lock');
                    }
                    else {
                        $label.addClass('works-input-lock');
                    }

                    element.parent().removeClass('works-input-focus');
                }, true);

                element
                    .unbind('update')
                    .bind('update', value => {
                        changeDetector(value);
                    });

                if (element.attr('class')) {
                    const extractedClasses = element.attr('class').match(/input-(\w+)/gi);
                    if (extractedClasses !== null && extractedClasses.length > 0) {
                        for (const idx in extractedClasses) {
                            const className = extractedClasses[idx];
                            $label.addClass('works-' + className);
                        }
                    }
                }

                if (element.prop('disabled') === true) {
                    $label.addClass('works-input-disabled');
                }

                if (validation === true) {
                    element.parent().addClass('works-input-label-validation');
                }

                context.$helper.promise(() => {
                    context.$helper.triggerHandler(element, 'blur');
                }, 25);

                changeDetector();
            },
            method: {
                validation: function (element, type) {
                    const context = this;

                    const allowedType = ['success', 'error', 'clear'];
                    element.parent().find('.works-input-validation').remove();

                    if (!type || allowedType.indexOf(type) === -1) {
                        if (!element.val()) {
                            if (!context.local.rule.notnull || context.local.rule.notnull === false) {
                                type = 'success';
                            }
                            else {
                                type = 'error';
                            }
                        }
                        else {
                            if (context.local.rule.notnull) type = 'success';
                        }
                    }

                    let $validator = null;
                    if (type === 'success') {
                        element.parent().removeClass('works-input-label-validation-error').addClass('works-input-label-validation-success');
                        $validator = $(context.$helper.parseTemplate('validationSuccess'));
                        $validator.insertAfter(element);
                    }
                    else if (type === 'error') {
                        element.parent().addClass('works-input-label-validation-error').removeClass('works-input-label-validation-success');
                        $validator = $(context.$helper.parseTemplate('validationError'));
                        $validator.insertAfter(element);
                    }
                    else {
                        element.parent().removeClass('works-input-label-validation-error').removeClass('works-input-label-validation-success').removeClass('works-input-label-validation-active');
                    }

                    if (type === 'success' || type === 'error') {
                        context.$helper.promise(() => {
                            element.parent().addClass('works-input-label-validation-active');
                        }, 25);
                    }
                }
            },
            template: {
                label: `<label class="works-input-label"></label>`,
                placeholder: `<span class="works-input-placeholder"></span>`,
                validationSuccess: `<span class="works-input-validation works-input-validation-success"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path class="works-input-validation-first" d="M 10 15 l -4 -4" stroke-dasharray="5.6568" stroke-width="2" /><path class="works-input-validation-last" d="M 9 15 l 8 -7" stroke-dasharray="10.6301" stroke-width="2" /></svg></span>`,
                validationError: `<span class="works-input-validation works-input-validation-error"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path class="works-input-validation-first" d="M 8 8 L 16 16" stroke-dasharray="11.3137" stroke-width="2" /><path class="works-input-validation-last" d="M 16 8 L 8 16" stroke-dasharray="11.3137" stroke-width="2" /></svg></span>`
            },
            options: {
                once: true,
                static: true,
                validation: {
                    disable: false
                }
            }
        });
    }(jQuery));
});
