// form core.js
/* global isEmpty, errorHandler, showFeedbackMessage, MessageTypesEnum */

/* exported FileLoader */
function FileLoader(args) {
    var MAX_FILE_SIZE_MB = 20;
    var SIZE_TO_MB = 1048576;
    var CHOOSE_FILE_TEXT = "Выберите файл";
    var ALERT_CHOOSE_FILE = "Необходимо выбрать файл";
    var ALERT_UNKNOWN_FILE_EXT = "Неизвестный тип файлов";
    var ALERT_MAX_FILE = "Файл превышает разрешенный размер";
    var ALERT_EMPTY_FILE = "Файл пуст";
    var ERROR = "Ошибка загрузки файла";

    if (isEmpty(args)) {
        throw "Empty arguments";
    }
    var divId = args.div;
    if (isEmpty(divId)) {
        throw "Div id parameter is not set";
    }
    var url = args.url;
    if (isEmpty(url)) {
        throw "URL parameter is not set";
    }
    var callback = args.callback;
    var maxFileSize = args.maxSize;
    MAX_FILE_SIZE_MB = Math.min((isEmpty(maxFileSize) ? MAX_FILE_SIZE_MB : maxFileSize), MAX_FILE_SIZE_MB);
    var fileExtensions = args.extensions;
    fileExtensions = isEmpty(fileExtensions) ? [] : fileExtensions;

    var div = $("#" + divId).addClass("input-group");
    if (isEmpty(div)) {
        throw "Div with id " + divId + " is not found";
    }

    var fileLabel = $("<input>")
        .attr("type", "text")
        .attr("placeholder", CHOOSE_FILE_TEXT)
        .attr("disabled", true)
        .addClass("form-control");
    div.append(fileLabel);
    var fileInput = $("<input>")
        .attr("type", "file")
        .hide();
    fileInput.change(function () {
        var files = $(this).prop("files");
        if (isEmpty(files)) {
            return;
        }
        fileLabel.val(files[0].name);
    });
    div.append(fileInput);

    var buttonGroup = $("<div>")
        .addClass("input-group-btn");
    div.append(buttonGroup);

    var chooseButton = $("<button>")
        .attr("type", "button")
        .addClass("btn btn-default")
        .append($("<i>").addClass("fa fa-ellipsis-h"));
    chooseButton.click(function () {
        fileInput.click();
    });
    buttonGroup.append(chooseButton);

    var uploadButton = $("<button>")
        .attr("type", "button")
        .addClass("btn btn-default")
        .append($("<i>").addClass("fa fa-upload"));
    uploadButton.click(function () {
        var files = fileInput.prop("files");
        if (isEmpty(files)) {
            showFeedbackMessage(ALERT_CHOOSE_FILE, MessageTypesEnum.DANGER);
            return;
        }
        var currentFile = files[0];
        if (!isEmpty(fileExtensions) && fileExtensions.indexOf(getFileExt(currentFile)) === -1) {
            showFeedbackMessage(ALERT_UNKNOWN_FILE_EXT, MessageTypesEnum.DANGER);
            return;
        }
        if (currentFile.size === 0) {
            showFeedbackMessage(ALERT_EMPTY_FILE, MessageTypesEnum.DANGER);
            return;
        }
        if (currentFile.size / SIZE_TO_MB > MAX_FILE_SIZE_MB) {
            showFeedbackMessage(ALERT_MAX_FILE + " " + MAX_FILE_SIZE_MB + "Mb", MessageTypesEnum.DANGER);
            return;
        }
        upload(currentFile);
    });
    buttonGroup.append(uploadButton);

    var progressDiv = $("<div>")
        .addClass("progress margined-top-10")
        .css("background-color", "#FFFFFF");
    progressDiv.insertAfter(div);
    var progressBar = $("<div>")
        .addClass("progress-bar")
        .attr("role", "progressbar")
        .css("width", "0%");
    progressDiv.append(progressBar);

    function getFileExt(file) {
        return file.name.slice((Math.max(0, file.name.lastIndexOf(".")) || Infinity) + 1);
    }

    function upload(file) {
        progressBar.css("width", "0%");
        var xhr = new XMLHttpRequest();
        xhr.upload.onprogress = function (event) {
            var curProgress = Math.floor(event.loaded / event.total * 100) + "%";
            progressBar
                .css("width", curProgress)
                .text(curProgress);
        };
        xhr.onload = xhr.onerror = function () {
            if (this.status === 200) {
                errorHandler(JSON.parse(this.responseText), callback);
            } else {
                showFeedbackMessage(ERROR, MessageTypesEnum.DANGER);
                console.error("error " + this.status);
            }
        };
        xhr.open("POST", url, true);
        var formData = new FormData();
        formData.append("file", file);
        xhr.send(formData);
    }
}