var LOCK = false;

sources = [];
sources_notes_display = [];
dests = [];
dests_notes_display = [];

function refreshHistory() {
    $("#history").load("/note/transfer/ #history");
}

function reset(refresh=true) {
    sources_notes_display.length = 0;
    sources.length = 0;
    dests_notes_display.length = 0;
    dests.length = 0;
    $("#source_note_list").html("");
    $("#dest_note_list").html("");
    let source_field = $("#source_note");
    source_field.val("");
    let event = jQuery.Event("keyup");
    event.originalEvent = {charCode: 97};
    source_field.trigger(event);
    source_field.removeClass('is-invalid');
    source_field.attr("data-original-title", "").tooltip("hide");
    let dest_field = $("#dest_note");
    dest_field.val("");
    dest_field.trigger(event);
    dest_field.removeClass('is-invalid');
    dest_field.attr("data-original-title", "").tooltip("hide");
    let amount_field = $("#amount");
    amount_field.val("");
    amount_field.removeClass('is-invalid');
    $("#amount-required").html("");
    let reason_field = $("#reason");
    reason_field.val("");
    reason_field.removeClass('is-invalid');
    $("#reason-required").html("");
    $("#last_name").val("");
    $("#first_name").val("");
    $("#bank").val("");
    $("#user_note").val("");
    $("#profile_pic").attr("src", "/media/pic/default.png");
    $("#profile_pic_link").attr("href", "#");
    if (refresh) {
        refreshBalance();
        refreshHistory();
    }

    LOCK = false;
}

$(document).ready(function() {
    /**
     * If we are in credit/debit mode, check that only one note is entered.
     * More over, get first name and last name to autocomplete fields.
     */
    function checkUniqueNote() {
        if ($("#type_credit").is(":checked") || $("#type_debit").is(":checked")) {
            let arr = $("#type_credit").is(":checked") ? dests_notes_display : sources_notes_display;

            if (arr.length === 0)
                return;

            let last = arr[arr.length - 1];
            arr.length = 0;
            arr.push(last);

            last.quantity = 1;

            if (!last.note.user) {
                $.getJSON("/api/note/note/" + last.note.id + "/?format=json", function(note) {
                    last.note.user = note.user;
                    $.getJSON("/api/user/" + last.note.user + "/", function(user) {
                        $("#last_name").val(user.last_name);
                        $("#first_name").val(user.first_name);
                    });
                });
            }
            else {
                $.getJSON("/api/user/" + last.note.user + "/", function(user) {
                    $("#last_name").val(user.last_name);
                    $("#first_name").val(user.first_name);
                });
            }
        }

        return true;
   }

    autoCompleteNote("source_note", "source_note_list", sources, sources_notes_display,
        "source_alias", "source_note", "user_note", "profile_pic", checkUniqueNote);
    autoCompleteNote("dest_note", "dest_note_list", dests, dests_notes_display,
        "dest_alias", "dest_note", "user_note", "profile_pic", checkUniqueNote);

    let source = $("#source_note");
    let dest = $("#dest_note");

    $("#type_transfer").click(function() {
        if (LOCK)
            return;

        $("#source_me_div").removeClass('d-none');
        $("#source_note").removeClass('is-invalid');
        $("#dest_note").removeClass('is-invalid');
        $("#special_transaction_div").addClass('d-none');
        source.removeClass('d-none');
        $("#source_note_list").removeClass('d-none');
        $("#credit_type").addClass('d-none');
        dest.removeClass('d-none');
        $("#dest_note_list").removeClass('d-none');
        $("#debit_type").addClass('d-none');

        $("#source_note_label").text(select_emitters_label);
        $("#dest_note_label").text(select_receveirs_label);

        location.hash = "transfer";
    });

    $("#type_credit").click(function() {
        if (LOCK)
            return;

        $("#source_me_div").addClass('d-none');
        $("#source_note").removeClass('is-invalid');
        $("#dest_note").removeClass('is-invalid');
        $("#special_transaction_div").removeClass('d-none');
        $("#source_note_list").addClass('d-none');
        $("#dest_note_list").removeClass('d-none');
        source.addClass('d-none');
        source.tooltip('hide');
        $("#credit_type").removeClass('d-none');
        dest.removeClass('d-none');
        dest.val('');
        dest.tooltip('hide');
        $("#debit_type").addClass('d-none');

        $("#source_note_label").text(transfer_type_label);
        $("#dest_note_label").text(select_receveir_label);

        if (dests_notes_display.length > 1) {
            $("#dest_note_list").html('');
            dests_notes_display.length = 0;
        }

        location.hash = "credit";
    });

    $("#type_debit").click(function() {
        if (LOCK)
            return;

        $("#source_me_div").addClass('d-none');
        $("#source_note").removeClass('is-invalid');
        $("#dest_note").removeClass('is-invalid');
        $("#special_transaction_div").removeClass('d-none');
        $("#source_note_list").removeClass('d-none');
        $("#dest_note_list").addClass('d-none');
        source.removeClass('d-none');
        source.val('');
        source.tooltip('hide');
        $("#credit_type").addClass('d-none');
        dest.addClass('d-none');
        dest.tooltip('hide');
        $("#debit_type").removeClass('d-none');

        $("#source_note_label").text(select_emitter_label);
        $("#dest_note_label").text(transfer_type_label);

        if (sources_notes_display.length > 1) {
            $("#source_note_list").html('');
            sources_notes_display.length = 0;
        }

        location.hash = "debit";
    });

        $("#credit_type").change(function() {
            let type = $("#credit_type option:selected").text();
            if ($("#type_credit").is(":checked"))
                source.val(type);
            else
                dest.val(type);
        });

    // Ensure we begin in transfer mode. Removing these lines may cause problems when reloading.
    let type_transfer = $("#type_transfer"); // Default mode
    type_transfer.removeAttr('checked');
    $("#type_credit").removeAttr('checked');
    $("#type_debit").removeAttr('checked');

    if (location.hash)
        $("#type_" + location.hash.substr(1)).click();
    else
        type_transfer.click();

    $("#source_me").click(function() {
        if (LOCK)
            return;

        // Shortcut to set the current user as the only emitter
        sources_notes_display.length = 0;
        sources.length = 0;
        $("#source_note_list").html("");

        let source_note = $("#source_note");
        source_note.focus();
        source_note.val("");
        let event = jQuery.Event("keyup");
        event.originalEvent = {charCode: 97};
        source_note.trigger(event);
        source_note.val(username);
        event = jQuery.Event("keyup");
        event.originalEvent = {charCode: 97};
        source_note.trigger(event);
        let fill_note = function() {
            if (sources.length === 0) {
                setTimeout(fill_note, 100);
                return;
            }
            event = jQuery.Event("keypress");
            event.originalEvent = {charCode: 13};
            source_note.trigger(event);

            source_note.tooltip('hide');
            source_note.val('');
            $("#dest_note").focus();
        };
        fill_note();
    });
});

$("#btn_transfer").click(function() {
    if (LOCK)
        return;

    LOCK = true;

    let error = false;

    let amount_field = $("#amount");
    amount_field.removeClass('is-invalid');
    $("#amount-required").html("");

    let reason_field = $("#reason");
    reason_field.removeClass('is-invalid');
    $("#reason-required").html("");

    if (!amount_field.val() || isNaN(amount_field.val()) || amount_field.val() <= 0) {
        amount_field.addClass('is-invalid');
        $("#amount-required").html("<strong>Ce champ est requis et doit comporter un nombre décimal strictement positif.</strong>");
        error = true;
    }

    let amount = Math.floor(100 * amount_field.val());
    if (amount > 2147483647) {
        amount_field.addClass('is-invalid');
        $("#amount-required").html("<strong>Le montant ne doit pas excéder 21474836.47 €.</strong>");
        error = true;
    }

    if (!reason_field.val()) {
        reason_field.addClass('is-invalid');
        $("#reason-required").html("<strong>Ce champ est requis.</strong>");
        error = true;
    }

    if (!sources_notes_display.length && !$("#type_credit").is(':checked')) {
        $("#source_note").addClass('is-invalid');
        error = true;
    }

    if (!dests_notes_display.length && !$("#type_debit").is(':checked')) {
        $("#dest_note").addClass('is-invalid');
        error = true;
    }

    if (error) {
        LOCK = false;
        return;
    }

    let reason = reason_field.val();

    if ($("#type_transfer").is(':checked')) {
        // We copy the arrays to ensure that transactions are well-processed even if the form is reset
        [...sources_notes_display].forEach(function (source) {
            [...dests_notes_display].forEach(function (dest) {
                if (source.note.id === dest.note.id) {
                    addMsg("Attention : la transaction de " + pretty_money(amount) + " de la note " + source.name
                        + " vers la note " + dest.name + " n'a pas été faite car il s'agit de la même note au départ" +
                        " et à l'arrivée.","warning", 10000);
                    LOCK = false;
                    return;
                }

                $.post("/api/note/transaction/transaction/",
                    {
                        "csrfmiddlewaretoken": CSRF_TOKEN,
                        "quantity": source.quantity * dest.quantity,
                        "amount": amount,
                        "reason": reason,
                        "valid": true,
                        "polymorphic_ctype": TRANSFER_POLYMORPHIC_CTYPE,
                        "resourcetype": "Transaction",
                        "source": source.note.id,
                        "source_alias": source.name,
                        "destination": dest.note.id,
                        "destination_alias": dest.name
                    }).done(function () {
                        if (source.note.membership && source.note.membership.date_end < new Date().toISOString())
                            addMsg("Attention : la note émettrice " + source.name + " n'est plus adhérente.",
                                "danger", 30000);
                        if (dest.note.membership && dest.note.membership.date_end < new Date().toISOString())
                            addMsg("Attention : la note destination " + dest.name + " n'est plus adhérente.",
                                "danger", 30000);

                        if (!isNaN(source.note.balance)) {
                            let newBalance = source.note.balance - source.quantity * dest.quantity * amount;
                            if (newBalance <= -5000) {
                                addMsg("Le transfert de "
                                    + pretty_money(source.quantity * dest.quantity * amount) + " de la note "
                                    + source.name + " vers la note " + dest.name + " a été fait avec succès, " +
                                    "mais la note émettrice est en négatif sévère.", "danger", 10000);
                                reset();
                                return;
                            }
                            else if (newBalance < 0) {
                                addMsg("Le transfert de "
                                    + pretty_money(source.quantity * dest.quantity * amount) + " de la note "
                                    + source.name + " vers la note " + dest.name + " a été fait avec succès, " +
                                    "mais la note émettrice est en négatif.", "warning", 10000);
                                reset();
                                return;
                            }
                        }
                        addMsg("Le transfert de "
                            + pretty_money(source.quantity * dest.quantity * amount) + " de la note " + source.name
                            + " vers la note " + dest.name + " a été fait avec succès !", "success", 10000);

                        reset();
                    }).fail(function (err) { // do it again but valid = false
                        let errObj = JSON.parse(err.responseText);
                        if (errObj["non_field_errors"]) {
                            addMsg("Le transfert de "
                                + pretty_money(source.quantity * dest.quantity * amount) + " de la note " + source.name
                                + " vers la note " + dest.name + " a échoué : " + errObj["non_field_errors"], "danger");
                            LOCK = false;
                            return;
                        }

                        $.post("/api/note/transaction/transaction/",
                        {
                            "csrfmiddlewaretoken": CSRF_TOKEN,
                            "quantity": source.quantity * dest.quantity,
                            "amount": amount,
                            "reason": reason,
                            "valid": false,
                            "invalidity_reason": "Solde insuffisant",
                            "polymorphic_ctype": TRANSFER_POLYMORPHIC_CTYPE,
                            "resourcetype": "Transaction",
                            "source": source.note.id,
                            "source_alias": source.name,
                            "destination": dest.note.id,
                            "destination_alias": dest.name
                        }).done(function () {
                            addMsg("Le transfert de "
                                + pretty_money(source.quantity * dest.quantity * amount) + " de la note " + source.name
                                + " vers la note " + dest.name + " a échoué : Solde insuffisant", "danger", 10000);
                            reset();
                        }).fail(function (err) {
                            let errObj = JSON.parse(err.responseText);
                            let error = errObj["detail"] ? errObj["detail"] : errObj["non_field_errors"]
                            if (!error)
                                error = err.responseText;
                            addMsg("Le transfert de "
                                + pretty_money(source.quantity * dest.quantity * amount) + " de la note " + source.name
                                + " vers la note " + dest.name + " a échoué : " + error, "danger");
                            LOCK = false;
                    });
                });
            });
        });
    } else if ($("#type_credit").is(':checked') || $("#type_debit").is(':checked')) {
        let special_note;
        let user_note;
        let alias;
        let given_reason = reason;
        let source_id, dest_id;
        if ($("#type_credit").is(':checked')) {
            special_note = $("#credit_type").val();
            user_note = dests_notes_display[0].note;
            alias = dests_notes_display[0].name;
            source_id = special_note;
            dest_id = user_note.id;
            reason = "Crédit " + $("#credit_type option:selected").text().toLowerCase();
            if (given_reason.length > 0)
                reason += " (" + given_reason + ")";
        }
        else {
            special_note = $("#debit_type").val();
            user_note = sources_notes_display[0].note;
            alias = sources_notes_display[0].name;
            source_id = user_note.id;
            dest_id = special_note;
            reason = "Retrait " + $("#credit_type option:selected").text().toLowerCase();
            if (given_reason.length > 0)
                reason += " (" + given_reason + ")";
        }
        $.post("/api/note/transaction/transaction/",
            {
                "csrfmiddlewaretoken": CSRF_TOKEN,
                "quantity": 1,
                "amount": amount,
                "reason": reason,
                "valid": true,
                "polymorphic_ctype": SPECIAL_TRANSFER_POLYMORPHIC_CTYPE,
                "resourcetype": "SpecialTransaction",
                "source": source_id,
                "source_alias": sources_notes_display.length ? alias : null,
                "destination": dest_id,
                "destination_alias": dests_notes_display.length ? alias : null,
                "last_name": $("#last_name").val(),
                "first_name": $("#first_name").val(),
                "bank": $("#bank").val()
            }).done(function () {
                addMsg("Le crédit/retrait a bien été effectué !", "success", 10000);
                if (user_note.membership && user_note.membership.date_end < new Date().toISOString())
                    addMsg("Attention : la note " + alias +  " n'est plus adhérente.", "danger", 10000);
                reset();
            }).fail(function (err) {
                let errObj = JSON.parse(err.responseText);
                let error = errObj["detail"] ? errObj["detail"] : errObj["non_field_errors"]
                if (!error)
                    error = err.responseText;
                addMsg("Le crédit/retrait a échoué : " + error, "danger", 10000);
                LOCK = false;
        });
    }
});