{% extends 'kfet/base.html' %}
{% load static %}

{% block extra_head %}
<link rel="stylesheet" style="text/css" href="{% static 'kfet/css/kpsul_grid.css' %}">
<script type="text/javascript" src="{% static 'vendor/jquery/jquery.autocomplete-light.min.js' %}"></script>
<script type="text/javascript" src="{% static 'kfet/vendor/moment/moment-timezone-with-data-2012-2022.min.js' %}"></script>
<script type="text/javascript" src="{% static 'kfet/js/history.js' %}"></script>
<script type="text/javascript" src="{% url 'js_reverse' %}" ></script>
<script type="text/javascript" src="{% static 'kfet/vendor/underscore-min.js' %}"></script>
<script type="text/javascript" src="{% static 'kfet/vendor/backbone-min.js' %}"></script>
<script type="text/javascript" src="{% static 'kfet/js/account.js' %}"></script>
<script type="text/javascript" src="{% static 'kfet/js/kpsul.js' %}"></script>
{% endblock %}

{% block title %}K-Psul{% endblock %}

{% block header %}{% endblock %}
{% block footer %}{% endblock %}

{% block help %}

<div class="row">
  <div class="col-md-6">
    <div class="block">
      <h4>Opérations</h4>
      <div class="row">
        <div class="col-xs-3"><b>F3</b></div>
        <div class="col-xs-9">Charge</div>
      </div>
      <div class="row">
        <div class="col-xs-3"><b>Shift + F3</b></div>
        <div class="col-xs-9">Retrait</div>
      </div>
      <div class="row">
        <div class="col-xs-3"><b>F8</b></div>
        <div class="col-xs-9">Edition</div>
      </div>
    </div>
  </div>
  <div class="col-md-6">
    <div class="block">
      <h4>Général</h4>
      <div class="row">
        <div class="col-xs-3"><b>F1</b></div>
        <div class="col-xs-9">Reset</div>
      </div>
      <div class="row">
        <div class="col-xs-3"><b>F2</b></div>
        <div class="col-xs-9">Reset panier</div>
      </div>
      <div class="row">
        <div class="col-xs-3"><b>Shift + F2</b></div>
        <div class="col-xs-9">Reset compte</div>
      </div>
      <div class="row">
        <div class="col-xs-3"><b>F9</b></div>
        <div class="col-xs-9">Majoration</div>
      </div>
      <div class="row">
        <div class="col-xs-3"><b>F10</b></div>
        <div class="col-xs-9">Hard reset</div>
      </div>
    </div>
  </div>
</div>

{% endblock %}

{% block content %}

{% include 'kfet/base_messages.html' %}

<div class="row kpsul_top">
  <div class="col-sm-8">
    <div class="row" id="account">
      <div class="col-lg-3 col-xs-4" id="account_form">
        {{ trigramme_form.trigramme }}
      </div>
      <div class="col-lg-9 col-xs-8" id="account_data">
        <div id="account-balance" class="data_line"></div>
        <div id="account-name" class="data_line"></div>
        <div id="account-nickname" class="data_line"></div>
        <div class="data_line">
          <span id="account-is_cof"></span>
          <span id="account-departement"></span>
          <span id="account-promo"></span>
        </div>
        <div id="account-email" class="data_line"></div>
        <div class="buttons">
        </div>
      </div>
    </div>
  </div>
  <div class="col-sm-4" id="checkout">
    <div id="checkout_form">
      {{ checkout_form.checkout }}
    </div>
    <div id="checkout_data">
      <div>
        <b>En caisse:</b> <span id="checkout-balance"></span> €
      </div>
      <div id="last_statement">
      </div>
      <div class="buttons">
      </div>
    </div>
  </div>
</div>

<div class="row kpsul_middle">
  <div class="col-sm-8 kpsul_middle_left_col">
    <div class="kpsul_middle_left">
      <div class="kpsul_middle_left_top">
        <div id="special_operations" class="btn-group btn-group-justified">
          <div class="btn-group">
            <button type="button" class="btn btn-primary" id="operation_deposit">
              Charge <span class="hidden-xs hidden-sm">(F3)</span>
            </button>
          </div>
          <div class="btn-group">
            <button type="button" class="btn btn-primary" id="operation_withdraw">
              Retrait <span class="hidden-xs hidden-sm">(Shift+F3)</span>
            </button>
          </div>
          <div class="btn-group">
            <button type="button" class="btn btn-primary" id="cool_reset">
              RAZ <span class="hidden-xs hidden-sm">(F1)</span>
            </button>
          </div>
          <div class="btn-group">
            <button type="button" class="btn btn-primary" id="ask_addcost">
              Major. <span class="hidden-xs hidden-sm">(F9)</span>
            </button>
          </div>
        </div>
        <div id="article_selection">
          <input type="text" id="article_autocomplete" autocomplete="off">
          <input type="number" id="article_number" step="1" min="1">
          <span type="stock" id="article_stock"></span>
          <input type="hidden" id="article_id" value="">
        </div>
        <div id="articles_data">
          <table>
            <tbody>
            </tbody>
          </table>
        </div>
      </div>
      <div class="row kpsul_middle_left_bottom">
        <div class="col-sm-6">
          <div id="basket">
            <table id="basket_table">
            </table>
          </div>
        </div>
        <div class="col-sm-3">
          <div id="basket_rel">
          </div>
        </div>
        <div class="col-sm-3">
          <div id="previous_op">
          </div>
        </div>
      </div>
    </div>
  </div>
  <div class="col-sm-4 kpsul_middle_right_col">
    <div id="history">
    </div>
  </div>
</div>

<div id="history2">
</div>

<form id="operationgroup_form" style="display:none;">{{ operationgroup_form }}</form>
<form id="operation_formset" style="display:none;">{{ operation_formset }}</form>

<div style="display:none;" id="operation_empty_html" data-opeindex="__prefix__">
    {{ operation_formset.empty_form }}
</div>

{% csrf_token %}

<script type="text/javascript">
$(document).ready(function() {
    // -----
    // General
    // -----

    // Lock to avoid multiple requests
    window.lock = 0;

    // Retrieve settings

    settings = {}

    function resetSettings() {
        return $.ajax({
            dataType: "json",
            url     : "{% url 'kfet.kpsul.get_settings' %}",
            method  : "POST",
        })
        .done(function(data) {
            settings['addcost_for'] = data['addcost_for'];
            settings['addcost_amount'] = parseFloat(data['addcost_amount']);
            settings['subvention_cof'] = parseFloat(data['subvention_cof']);
        });
    }


    // -----
    // Account data management
    // -----

    var account_manager = new AccountManager();
    var triInput = $('#id_trigramme');


    // -----
    // Checkout data management
    // -----

    // Initializing
    var checkout_container = $('#checkout');
    var checkoutInput = $('#id_checkout_select');
    var checkout_data = {}
    var checkout_data_default = {
        'id'  : 0,
        'name': '',
        'balance'   : '',
        'valid_from': '',
        'valid_to'  : '',
        'last_statement_balance': '',
        'last_statement_at'     : '',
        'last_statement_by_trigramme' : '',
        'last_statement_by_first_name': '',
        'last_statement_by_last_name' : '' ,
    }
    var last_statement_container = $('#last_statement');
    var last_statement_html_default = '<b>Dernier relevé: </b><br><span id="checkout-last_statement_balance"></span>€ le <span id="checkout-last_statement_at"></span> par <span id="checkout-last_statement_by_trigramme"></span>';

    // If only one checkout is available, select it
    var checkout_choices = checkoutInput.find("option[value!='']");
    if (checkout_choices.length == 1) {
        $(checkout_choices[0]).prop("selected", true);
    }

    // Display data
    function displayCheckoutData() {
        var at_formated = '';
        if (checkout_data['last_statement_at']) {
            last_statement_container.html(last_statement_html_default);
            var at = moment.tz(checkout_data['last_statement_at'], 'UTC');
            at_formated = at.tz('Europe/Paris').format('DD/MM/YY à HH:mm');
        } else {
            last_statement_container.html('');
        }
        for (var elem in checkout_data) {
            $('#checkout-'+elem).text(checkout_data[elem]);
        }
        $('#checkout-last_statement_at').text(at_formated);
        var buttons = '';
        if (checkout_data['id'] !== 0) {
            var url_base = "{% url 'kfet.checkoutstatement.create' 1 %}";
            url_base = url_base.substr(0,url_base.length - 16);
            buttons += '<a class="btn btn-primary" href="'+url_base+checkout_data['id']+'/statements/add" title="Effectuer un relevé" target="_blank"><span class="glyphicon glyphicon-euro"></span></a>';
            buttons += '<a class="btn btn-primary" href="'+url_base+checkout_data['id']+'" title="Modifier" target="_blank"><span class="glyphicon glyphicon-cog"></span></a>';
        }
        checkout_container.find('.buttons').html(buttons);
    }

    // Clear data
    function resetCheckout() {
        checkout_data = checkout_data_default;
        $('#id_checkout').val(0);
        checkoutInput.find('option:first').prop('selected', true);
        displayCheckoutData();
    }

    // Store data
    function storeCheckoutData(data) {
        checkout_data = $.extend({}, checkout_data_default, data);
        $('#id_checkout').val(checkout_data['id']);
        displayCheckoutData();
    }

    // Retrieve data
    function retrieveCheckoutData(id) {
        $.ajax({
            dataType: "json",
            url     : "{% url 'kfet.kpsul.checkout_data' %}",
            method  : "POST",
            data    : { 'pk': id },
        })
         .done(function(data) { storeCheckoutData(data) })
         .fail(function() { resetCheckout() });
    }

    // Event listener
    checkoutInput.on('change', function() {
        retrieveCheckoutData(checkoutInput.val());
        if (account_manager.data['trigramme']) {
            articleSelect.focus().select();
        } else {
            triInput.focus().select();
        }
    });

    // -----
    // Auth
    // -----

    function askComment(callback) {
        var comment = $('#id_comment').val();
        $.confirm({
            title: 'Commentaire requis',
            content: '<input type="text" name="comment_opegroup" value="'+comment+'" autofocus>',
            backgroundDismiss: true,
            animation: 'top',
            closeAnimation: 'bottom',
            keyboardEnabled: true,
            confirm: function() {
                $('#id_comment').val(this.$content.find('input').val());
                callback();
            },
            onOpen: function() {
                var that = this;
                this.$content.find('input').on('keydown', function(e) {
                    if (e.keyCode == 13)
                        that.$confirmButton.click();
                });
            },
            onClose: function() { this._lastFocused = articleSelect; }
        });
    }

    function resetComment() {
        $('#id_comment').val('');
    }

    // -----
    // Perform operations
    // -----

    var performButton  = $('#perform_operations');
    var operationGroup = $('#operationgroup_form');
    var operations     = $('#operation_formset');

    function performOperations(password = '') {
        if (window.lock == 1)
            return false;
        window.lock = 1;
        var data = operationGroup.serialize() + '&' + operations.serialize();
        $.ajax({
            dataType: "json",
            url     : "{% url 'kfet.kpsul.perform_operations' %}",
            method  : "POST",
            data    : data,
            beforeSend: function ($xhr) {
                $xhr.setRequestHeader("X-CSRFToken", csrftoken);
                if (password != '')
                    $xhr.setRequestHeader("KFetPassword", password);
            },
        })
        .done(function(data) {
            updatePreviousOp();
            coolReset();
            window.lock = 0;
        })
        .fail(function($xhr) {
            var data = $xhr.responseJSON;
            switch ($xhr.status) {
                case 403:
                    requestAuth(data, performOperations, articleSelect);
                    break;
                case 400:
                    if ('need_comment' in data) {
                        askComment(performOperations);
                    } else {
                        displayErrors(data);
                    }
                    break;
            }
            window.lock = 0;
        });
    }

    // Event listeners
    performButton.on('click', function() {
        performOperations();
    });

    // -----
    // Articles data
    // -----

    var articles_container = $('#articles_data tbody');
    var article_category_default_html = '<tr class="category"><td colspan="3"></td></tr>';
    var article_default_html = '<tr class="article"><td class="name"></td><td class="price"></td><td class="stock"></td></tr>';

    function addArticle(article) {
        var article_html = $(article_default_html);
        article_html.attr('id', 'data-article-'+article['id']);
        article_html.addClass('data-category-'+article['category_id']);
        for (var elem in article) {
            article_html.find('.'+elem).text(article[elem])
        }
        if (-5 <=  article['stock'] && article['stock'] <= 5) {
            article_html.addClass('low-stock');
        }
        article_html.find('.price').text(amountToUKF(article['price'], false, false)+' UKF');
        var category_html = articles_container
            .find('#data-category-'+article['category_id']);
        if (category_html.length == 0) {
            category_html = $(article_category_default_html);
            category_html.attr('id', 'data-category-'+article['category_id']);
            category_html.find('td').text(article['category__name']);
            var added = false;
            articles_container.find('.category').each(function() {
                if (article['category__name'].toLowerCase() < $(this).text().toLowerCase()) {
                    $(this).before(category_html);
                    added = true;
                    return false;
                }
            });
            if (!added) articles_container.append(category_html);
        }
        var $after = articles_container.find('#data-category-'+article['category_id']);
        articles_container
            .find('.article.data-category-'+article['category_id']).each(function() {
                if (article['name'].toLowerCase() < $('.name', this).text().toLowerCase())
                    return false;
                $after = $(this);
            });
        $after.after(article_html);
        // Pour l'autocomplétion
        articlesList.push([article['name'],article['id'],article['category_id'],article['price'], article['stock'],article['category__has_addcost'],article['category__has_reduction']]);
    }

    function getArticles() {
        $.ajax({
            dataType: "json",
            url     : "{% url 'kfet.kpsul.articles_data' %}",
            method  : "GET",
        })
        .done(function(data) {
            for (var i=0; i<data['articles'].length; i++) {
                addArticle(data['articles'][i]);
            }
        });
    }

    function resetArticles() {
        articles_container.find('tr').remove();
        articlesList = [];
    }

    // -----
    // Article selection
    // -----

    var articleSelect = $('#article_autocomplete');
    var articleId = $('#article_id');
    var articleNb = $('#article_number');
    var articleStock = $('#article_stock');
    // 8:Backspace|9:Tab|13:Enter|38-40:Arrows|46:DEL|112-117:F1-6|119-123:F8-F12
    var normalKeys = /^(8|9|13|37|38|39|40|46|112|113|114|115|116|117|119|120|121|122|123)$/;
    var articlesList = [];

    function deleteNonMatching(array, str) {
        var dup = [];
        var lower_str = str.toLowerCase();
        for (var i=0; i<array.length; i++) {
            if (((array[i][0]).toLowerCase()).indexOf(lower_str) === 0)
                dup.push(array[i])
        }
        return dup;
    }

    function callbackForPrefix(elt) {
        return elt[0].toLowerCase();
    }

    function sharedPrefix(array) {
        var dup = array.map(callbackForPrefix);
        dup.sort(); // On trie l'array
        // On récupère le préfixe du premier et du dernier élément
        var first = dup[0], last = dup[array.length-1],
            length = first.length, i = 0;
        while (i < length && first.charAt(i) === last.charAt(i)) i++;
        return first.substring(0, i);
    }

    function displayMatchedArticles(array) {
        var categories_to_display = [];
        for (var i=0; i<articlesList.length; i++) {
            if (array.indexOf(articlesList[i]) > -1) {
                articles_container.find('#data-article-'+articlesList[i][1]).show();
                if (categories_to_display.indexOf(articlesList[i][2]) == -1)
                    categories_to_display.push(articlesList[i][2]);
            } else {
                articles_container.find('#data-article-'+articlesList[i][1]).hide();
            }
        }
        articles_container.find('.category').hide();
        for (var i=0; i<categories_to_display.length; i++) {
            articles_container
                .find('#data-category-'+categories_to_display[i])
                .show();
        }
    }

    function updateMatchedArticles(str, commit = true) {
        var lower_str = str.toLowerCase();
        var articlesMatch = deleteNonMatching(articlesList, lower_str);

        if (articlesMatch.length == 1) {
            articleId.val(0);
            // 1 seul résultat, victoire
            if (commit) {
                articleId.val(articlesMatch[0][1]);
                articleSelect.val(articlesMatch[0][0]);
                articleStock.text('/'+articlesMatch[0][4]);
                displayMatchedArticles(articlesList);
                return true;
            }
            displayMatchedArticles(articlesMatch);
        } else if (articlesMatch.length > 1) {
            articleId.val(0);
            if (commit)
                articleSelect.val(sharedPrefix(articlesMatch));
            displayMatchedArticles(articlesMatch);
        }
        return false;
    }

    // A utiliser après la sélection d'un article
    function goToArticleNb() {
        articleNb.val('1');
        articleNb.focus().select();
    }

    articleSelect.on('keydown', function(e) {
        var text = articleSelect.val();
        // Comportement normal pour ces touches
        if (normalKeys.test(e.keyCode) || e.ctrlKey) {
            if (text == '' && e.keyCode == 13)
                performOperations();
            if (e.keyCode == 8)
                updateMatchedArticles(text.substring(0,text.length-1), commit=false);
            if (e.charCode == 65 && e.ctrlKey) {
                articleId.val(0);
                articleSelect.val('');
            }
            return true;
        }
        if (updateMatchedArticles(text+e.key))
            goToArticleNb();
        return false;
    });

    function getArticleId($article) {
        return $article.attr('id').split('-')[2];
    }

    function getArticleName($article) {
        return $article.find('.name').text();
    }

    function getArticleStock($article) {
        return $article.find('.stock').text();
    }

    // Sélection des articles à la souris/tactile
    articles_container.on('click', '.article', function() {
        articleId.val(getArticleId($(this)));
        articleSelect.val(getArticleName($(this)));
        articleStock.text('/'+getArticleStock($(this)));
        displayMatchedArticles(articlesList);
        goToArticleNb();
    });

    function is_nb_ok(nb) {
        return /^[0-9]+$/.test(nb) && nb > 0;
    }

    articleNb.on('keydown', function(e) {
        if (e.keyCode == 13 && is_nb_ok(articleNb.val()) && articleId.val() > 0) {
            addPurchase(articleId.val(), articleNb.val());
            articleSelect.val('');
            articleNb.val('');
            articleStock.text('');
            articleSelect.focus();
            displayMatchedArticles(articlesList);
            return false;
        }
        if (normalKeys.test(e.keyCode) || arrowKeys.test(e.keyCode) || e.keyCode == 8 || e.ctrlKey) {
            if (e.ctrlKey && e.charCode == 65)
                articleNb.val('');
            return true;
        }
        var nb = articleNb.val()+e.key;
        if (is_nb_ok(nb))
            return true;
        return false;
    });

    // -----
    // Basket
    // -----

    var item_basket_default_html = '<tr><td class="amount"></td><td class="number"></td><td ><span class="lowstock glyphicon glyphicon-alert"></span></td><td class="name"></td></tr>';
    var basket_container = $('#basket table');
    var arrowKeys = /^(37|38|39|40)$/;

    function amountEuroPurchase(id,nb) {
        var i = 0;
        while (i<articlesList.length && id != articlesList[i][1]) i++;
        article_data = articlesList[i];
        var amount_euro = - article_data[3] * nb ;
        if (settings['addcost_for']
            && settings['addcost_amount']
            && account_manager.data['trigramme'] != settings['addcost_for']
            && article_data[5])
                amount_euro -= settings['addcost_amount'] * nb;
        var reduc_divisor = 1;
        if (account_manager.data['is_cof'] && article_data[6])
            reduc_divisor = 1 + settings['subvention_cof'] / 100;
        return (amount_euro / reduc_divisor).toFixed(2);
    }

    function addPurchase(id, nb) {
        var existing = false;
        formset_container.find('[data-opeindex]').each(function () {
            var opeindex = $(this).attr('data-opeindex');
            var article_id = $(this).find('#id_form-'+opeindex+'-article').val();
            if (article_id == id) {
                existing = true ;
                addExistingPurchase(opeindex, nb);
            }
        });
        if (!existing) {
            var amount_euro = amountEuroPurchase(id, nb);
            var index = addPurchaseToFormset(article_data[1], nb, amount_euro);
            article_basket_html = $(item_basket_default_html);
            article_basket_html
                .attr('data-opeindex', index)
                .find('.number').text('('+nb+'/'+article_data[4]+')').end()
                .find('.name').text(article_data[0]).end()
                .find('.amount').text(amountToUKF(amount_euro, account_manager.data['is_cof'], false));
            basket_container.prepend(article_basket_html);
            if (is_low_stock(id, nb))
                article_basket_html.find('.lowstock')
                                   .show();
            updateBasketRel();
        }
    }

    function is_low_stock(id, nb) {
        var i = 0 ;
        while (i<articlesList.length && id != articlesList[i][1]) i++;
        article_data = articlesList[i];

        stock = article_data[4] ;
        return (-5 <= stock - nb && stock - nb <= 5); 
    }

    function addDeposit(amount) {
        var deposit_basket_html = $(item_basket_default_html);
        var amount = parseFloat(amount).toFixed(2);
        var index = addDepositToFormset(amount);
        deposit_basket_html
            .attr('data-opeindex', index)
            .find('.number').text(amount+"€").end()
            .find('.name').text('Charge').end()
            .find('.amount').text(amountToUKF(amount, account_manager.data['is_cof'], false));
        basket_container.prepend(deposit_basket_html);
        updateBasketRel();
    }

    function addEdit(amount) {
        var deposit_basket_html = $(item_basket_default_html);
        var amount = parseFloat(amount).toFixed(2);
        var index = addEditToFormset(amount);
        deposit_basket_html
            .attr('data-opeindex', index)
            .find('.number').text(amount+"€").end()
            .find('.name').text('Édition').end()
            .find('.amount').text(amountToUKF(amount, account_manager.data['is_cof'], false));
        basket_container.prepend(deposit_basket_html);
        updateBasketRel();
    }

    function addWithdraw(amount) {
        var withdraw_basket_html = $(item_basket_default_html);
        var amount = (- parseFloat(amount)).toFixed(2);
        var index = addWithdrawToFormset(amount);
        withdraw_basket_html
            .attr('data-opeindex', index)
            .find('.number').text(amount+"€").end()
            .find('.name').text('Retrait').end()
            .find('.amount').text(amountToUKF(amount, account_manager.data['is_cof'], false));
        basket_container.prepend(withdraw_basket_html);
        updateBasketRel();
    }

    basket_container.selectable({
        filter: 'tr',
    });

    $(document).on('keydown', function (e) {
        switch(e.which) {
            case 46:
                // DEL (Suppr)
                basket_container.find('.ui-selected').each(function () {
                    deleteFromBasket($(this).data('opeindex'));
                });
                break;
            case 38:
                // Arrow up
                basket_container.find('.ui-selected').each(function () {
                    addExistingPurchase($(this).data('opeindex'), 1);
                });
                break;
            case 40:
                // Arrow down
                basket_container.find('.ui-selected').each(function () {
                    addExistingPurchase($(this).data('opeindex'), -1);
                });
                break;
        }
    });

    function isBasketEmpty() {
        return !basket_container.find('[data-opeindex]').length;
    }

    function getAmountBasket() {
        var total = 0;
        formset_container.find('[data-opeindex]').each(function () {
            var opeindex = $(this).attr('data-opeindex');
            if (!$(this).find('#id_form-'+opeindex+'-DELETE').prop('checked'))
                total += parseFloat($(this).find('#id_form-'+opeindex+'-amount').val());
        });
        return total;
    }

    function updateBasketAmount() {
        formset_container.find('[data-opeindex]').each(function () {
            var opeindex = $(this).attr('data-opeindex');
            var deleted = $(this).find('#id_form-'+opeindex+'-DELETE').prop('checked');
            var type = $(this).find('#id_form-'+opeindex+'-type').val();
            var article_id = $(this).find('#id_form-'+opeindex+'-article').val();
            var article_nb = $(this).find('#id_form-'+opeindex+'-article_nb').val();
            var amount = $(this).find('#id_form-'+opeindex+'-amount');
            if (!deleted && type == "purchase")
                amount.val(amountEuroPurchase(article_id, article_nb));
            basket_container.find('[data-opeindex='+opeindex+'] .amount').text(amountToUKF(amount.val(), account_manager.data['is_cof'], false));
        });
    }

    var basketrel_container = $('#basket_rel');

    function updateBasketRel() {
        var basketrel_html = '';
        if (account_manager.data['trigramme'] == 'LIQ' && !isBasketEmpty()) {
            var amount = - getAmountBasket();
            basketrel_html += '<div>Total: '+amount.toFixed(2)+' €</div>';
            if (amount < 5)
                basketrel_html += '<div>Sur 5€: '+ (5-amount).toFixed(2) +' €</div>';
            if (amount < 10)
                basketrel_html += '<div>Sur 10€: '+ (10-amount).toFixed(2) +' €</div>';
            if (amount < 20)
                basketrel_html += '<div>Sur 20€: '+ (20-amount).toFixed(2) +' €</div>';
        } else if (account_manager.data['trigramme'] != '' && !isBasketEmpty()) {
            var amount = getAmountBasket();
            var amountUKF = amountToUKF(amount, account_manager.data['is_cof'], false);
            var newBalance = account_manager.data['balance'] + amount;
            var newBalanceUKF = amountToUKF(newBalance, account_manager.data['is_cof'], true);
            basketrel_html += '<div>Total: '+amountUKF+'</div>';
            basketrel_html += '<div>Nouveau solde: '+newBalanceUKF+'</div>';
            if (newBalance < 0)
                basketrel_html += '<div>Manque: '+ (-newBalance).toFixed(2) +' €</div>';
        }
        basketrel_container.html(basketrel_html);
    }

    function deleteFromBasket(opeindex) {
        basket_container.find('[data-opeindex='+opeindex+']').remove();
        deleteFromFormset(opeindex);
        updateBasketRel();
    }

    function addExistingPurchase(opeindex, nb) {
        var type = formset_container.find("#id_form-"+opeindex+"-type").val(); 
        var id = formset_container.find("#id_form-"+opeindex+"-article").val(); 
        var nb_before = formset_container.find("#id_form-"+opeindex+"-article_nb").val();
        var nb_after = parseInt(nb_before) + parseInt(nb);
        var amountEuro_after = amountEuroPurchase(id, nb_after);
        var amountUKF_after = amountToUKF(amountEuro_after, account_manager.data['is_cof']);

        if (type == 'purchase') {
            if (nb_after == 0) {
                deleteFromBasket(opeindex);
            } else if (nb_after > 0 && nb_after <= 25) {
                if (nb_before > 0) {
                    var article_html = basket_container.find('[data-opeindex='+opeindex+']');
                    article_html.find('.amount').text(amountUKF_after).end()
                                .find('.number').text('('+nb_after+'/'+article_data[4]+')').end() ;

                } else {
                    article_html = $(item_basket_default_html);
                    article_html
                        .attr('data-opeindex', opeindex)
                        .find('.number').text('('+nb_after+'/'+article_data[4]+')').end()
                        .find('.name').text(article_data[0]).end()
                        .find('.amount').text(amountUKF_after);
                    basket_container.prepend(article_basket_html);

                }

                    if (is_low_stock(id, nb_after))
                        article_html.find('.lowstock')
                                    .show();
                    else
                        article_html.find('.lowstock')
                                    .hide();
                updateExistingFormset(opeindex, nb_after, amountEuro_after);
                updateBasketRel();
            }
        }
    }

    function resetBasket() {
        basket_container.find('tr').remove();
        mngmt_total_forms = 1;
        mngmt_total_forms_input.val(1);
        formset_container.find('div').remove();
        updateBasketRel();
        articleId.val(0);
        articleSelect.val('');
        articleNb.val('');
        articleStock.text('');
        displayMatchedArticles(articlesList);
    }

    // -----
    // Ask deposit or withdraw
    // -----

    function askDeposit() {
        $.confirm({
            title: 'Montant de la charge',
            content: '<input type="number" lang="en" step="0.01" min="0.01" autofocus placeholder="€">',
            backgroundDismiss: true,
            animation:'top',
            closeAnimation:'bottom',
            keyboardEnabled: true,
            confirm: function() {
                var amount = this.$content.find('input').val();
                if (!$.isNumeric(amount) || amount <= 0)
                    return false;
                addDeposit(amount);
            },
            onOpen: function() {
                var that = this
                this.$content.find('input').on('keydown', function(e) {
                    if (e.keyCode == 13) {
                        e.preventDefault();
                        that.$confirmButton.click();
                    }
                });
            },
            onClose: function() { this._lastFocused = (articleSelect.val() ? articleNb : articleSelect) ; }
        });
    }

    function askEdit() {
        $.confirm({
            title: "Montant de l'édition",
            content: '<input type="number" lang="en" step="0.01" min="0.01" autofocus placeholder="€">',
            backgroundDismiss: true,
            animation:'top',
            closeAnimation:'bottom',
            keyboardEnabled: true,
            confirm: function() {
                var amount = this.$content.find('input').val();
                if (!$.isNumeric(amount))
                    return false;
                addEdit(amount);
            },
            onOpen: function() {
                var that = this
                this.$content.find('input').on('keydown', function(e) {
                    if (e.keyCode == 13) {
                        e.preventDefault();
                        that.$confirmButton.click();
                    }
                });
            },
            onClose: function() { this._lastFocused = (articleSelect.val() ? articleNb : articleSelect) ; }
        });
    }

    function askWithdraw() {
        $.confirm({
            title: 'Montant du retrait',
            content: '<input type="number" lang="en" step="0.01" min="0.01" autofocus placeholder="€">',
            backgroundDismiss: true,
            animation:'top',
            closeAnimation:'bottom',
            keyboardEnabled: true,
            confirm: function() {
                var amount = this.$content.find('input').val();
                if (!$.isNumeric(amount) || amount <= 0)
                    return false;
                addWithdraw(amount);
            },
            onOpen: function() {
                var that = this
                this.$content.find('input').on('keydown', function(e) {
                    if (e.keyCode == 13) {
                        e.preventDefault();
                        that.$confirmButton.click();
                    }
                });
            },
            onClose: function() { this._lastFocused = articleSelect; }
        });
    }

    // Event

    var depositButton = $('#operation_deposit');
    var withdrawButton = $('#operation_withdraw');

    depositButton.on('click', function() { askDeposit(); });
    withdrawButton.on('click', function() { askWithdraw(); });

    // -----
    // Operation formset management
    // -----

    var operation_empty_html = $('#operation_empty_html')
        .removeAttr('id')
        .find('label').remove().end()
        .find('#id_form-__prefix__-DELETE').css('display','none').end();
    $('#id_form-0-DELETE').prop('checked',true);

    var formset_container = $('#operation_formset');
    var mngmt_total_forms_input = $('#id_form-TOTAL_FORMS');
    var mngmt_total_forms = 1;
    var prefix_regex = /__prefix__/;

    function addOperationToFormset(type, amount, article='', article_nb='') {
        var operation_html = operation_empty_html.clone();
        var index = mngmt_total_forms;

        operation_html.attr('data-opeindex', index);

        operation_html
            .find('#id_form-__prefix__-type').val(type).end()
            .find('#id_form-__prefix__-amount').val((parseFloat(amount)).toFixed(2)).end()
            .find('#id_form-__prefix__-article').val(article).end()
            .find('#id_form-__prefix__-article_nb').val(article_nb).end();

        mngmt_total_forms_input.val(index+1);
        mngmt_total_forms++;

        operation_html.find(':input').each(function() {
            var name = $(this).attr('name').replace(prefix_regex, index);
            var id = 'id_' + name;
            $(this).attr({'name': name, 'id': id});
        });
        formset_container.append(operation_html);

        return index;
    }

    function addDepositToFormset(amount) {
        return addOperationToFormset('deposit', amount, '', '');
    }

    function addEditToFormset(amount) {
        return addOperationToFormset('edit', amount, '', '');
    }

    function addWithdrawToFormset(amount) {
        return addOperationToFormset('withdraw', amount, '', '');
    }

    function addPurchaseToFormset(article_id, article_nb, amount=0) {
        return addOperationToFormset('purchase', amount, article_id, article_nb);
    }

    function deleteFromFormset(opeindex) {
        updateExistingFormset(opeindex, 0, '0.00');
    }

    function updateExistingFormset(opeindex, nb, amount) {
        formset_container
            .find('#id_form-'+opeindex+'-amount').val((parseFloat(amount)).toFixed(2)).end()
            .find('#id_form-'+opeindex+'-article_nb').val(nb).end()
            .find('#id_form-'+opeindex+'-DELETE').prop('checked', !nb);
    }

    // -----
    // History
    // -----

    khistory = new KHistory({
        fetch_options: {
            start: moment().subtract(1, 'days').format('YYYY-MM-DD HH:mm:ss'),
            opes_only: true,
        },
    });

    var previousop_container = $('#previous_op');

    function updatePreviousOp() {
        var previousop_html = '';
        var trigramme = account_manager.data['trigramme'];
        previousop_html += '<div class="trigramme">Trigramme : '+trigramme+'</div>';
        previousop_html += basketrel_container.html();
        previousop_container.html(previousop_html);
    }

    function resetPreviousOp() {
        previousop_container.html('');
    }

    // -----
    // Addcost
    // -----

    var addcost_default_html = '<div id="addcost">Majoration vers <span class="addcost_for"></span> de <span class="addcost_amount"></span>€</div>';

    function displayAddcost() {
        checkout_container.find('#addcost').remove();
        $('body').css('animation', 'none');
        if (settings['addcost_for'] && settings['addcost_amount']) {
            var addcost_html = $(addcost_default_html);
            addcost_html
                .find('.addcost_for').text(settings['addcost_for']).end()
                .find('.addcost_amount').text(settings['addcost_amount'].toFixed(2)).end();
            checkout_container.prepend(addcost_html);
            $('body').css('animation', 'colorchange 3s infinite');
        }
    }
    function sendAddcost(trigramme, amount, password='') {
        var data = {
            trigramme: trigramme,
            amount: amount,
        }
        $.ajax({
            dataType: "json",
            url     : "{% url 'kfet.kpsul.update_addcost' %}",
            method  : "POST",
            data    : data,
            beforeSend: function ($xhr) {
                $xhr.setRequestHeader("X-CSRFToken", csrftoken);
                if (password != '')
                    $xhr.setRequestHeader("KFetPassword", password);
            },
        })
        .fail(function($xhr) {
            var data = $xhr.responseJSON;
            switch ($xhr.status) {
                case 403:
                    requestAuth(data, function(password) {
                        sendAddcost(trigramme, amount, password);
                    }, triInput);
                    break;
                case 400:
                    askAddcost(getErrorsHtml(data["errors"], is_error=true));
                    break;
            }
        });
    }

    function askAddcost(errors = '') {
        $.confirm({
            title: 'Majoration',
            content: errors + '<input type="text" placeholder="Trigramme" autocomplete="off" name="trigramme" spellcheck="false" style="text-transform:uppercase" autofocus><input type="number" lang="en" step="0.01" min="0.01" placeholder="€" name="amount">',
            backgroundDismiss: true,
            animation:'top',
            closeAnimation:'bottom',
            keyboardEnabled: true,
            confirm: function() {
                var trigramme = this.$content.find('input[name=trigramme]').val().toUpperCase();
                var amount = this.$content.find('input[name=amount]').val();
                sendAddcost(trigramme, amount);
            },
            onOpen: function() {
                var that = this
                this.$content.find('input[name=amount]').on('keydown', function(e) {
                    if (e.keyCode == 13) {
                        e.preventDefault();
                        that.$confirmButton.click();
                    }
                });
            },
            onClose: function() { this._lastFocused = triInput; }
        });
    }


    // -----
    // Cancel from history
    // -----

    $(document).on('keydown', function (e) {
        if (e.keyCode == 46) {
            // DEL (Suppr)
            khistory.cancel_selected()
        }
    });

    // -----
    // Synchronization
    // -----

    OperationWebSocket.add_handler(function(data) {
        for (var i=0; i<data['groups'].length; i++) {
            if (data['groups'][i]['add']) {
                khistory.add_history_group(data['groups'][i]);
            }
        }
        for (var i=0; i<data['checkouts'].length; i++) {
            if (checkout_data['id'] == data['checkouts'][i]['id']) {
                checkout_data['balance'] = data['checkouts'][i]['balance'];
                displayCheckoutData();
            }
        }
        for (var i=0; i<data['articles'].length; i++) {
            var article = data['articles'][i];
            var article_line = articles_container.find('#data-article-'+article.id);
            if (article.stock <= 5 && article.stock >= -5) {
                article_line.addClass('low-stock');
            } else {
                article_line.removeClass('low-stock');
            }
            article_line.find('.stock')
                .text(article['stock']);

            var i = 0;
            while (i < articlesList.length && articlesList[i][1] != article.id) i++ ;
            articlesList[i][4] = article.stock ;
        }
        if (data['addcost']) {
            settings['addcost_for'] = data['addcost']['for'];
            settings['addcost_amount'] = parseFloat(data['addcost']['amount']);
            displayAddcost();
        }
    });

    // -----
    // General
    // -----

    // Reset functions

    function coolReset(give_tri_focus=true) {
        account_manager.reset(true);
        resetBasket();
        resetComment();
        resetSelectable();
        if (give_tri_focus)
            triInput.focus();
    }

    function hardReset(give_tri_focus=true) {
        coolReset(give_tri_focus);
        checkoutInput.trigger('change');
        resetArticles();
        resetPreviousOp();
        khistory.reset();
        resetSettings().done(function (){
            getArticles();
            khistory.fetch();
            displayAddcost();
        });
    }

    function resetSelectable() {
        $('.ui-selected').removeClass('ui-selected');
    }

    // Shorcuts

    $('#cool_reset').click(function() {
        coolReset();
    });

    $('#ask_addcost').click(function() {
        askAddcost();
    });

    $(document).on('keydown', function(e) {
        switch (e.keyCode) {
            case 27:
                // Escape - Hide help
                $('.help').hide('fast');
                return false;
            case 72:
                if (e.ctrlKey) {
                    // Ctrl+H - Display help
                    e.preventDefault();
                    $('.help').show('fast');
                }
                return true;
            case 112:
                // F1 - Cool reset
                coolReset();
                return false;
            case 113:
                if (e.shiftKey) {
                    // Shift+F2 - Account reset
                    account_manager.reset(true);
                    triInput.focus();
                } else {
                    // F2 - Basket reset
                    resetBasket();
                    articleSelect.focus();
                }
                return false;
            case 114:
                if (e.shiftKey) {
                    // Shift+F3 - Withdraw
                    askWithdraw();
                } else {
                    // F3 - Withdraw
                    askDeposit();
                }
                return false;
            case 119:
                // F8 - Edition
                askEdit();
                return false;
            case 120:
                // F9 - Addcost
                askAddcost();
                return false;
            case 121:
                // F10 - Hard reset
                hardReset();
                return false;
        }
    });

    // On exporte les fonctions nécessaires dans `window`
    window.updateBasketAmount = updateBasketAmount;
    window.updateBasketRel = updateBasketRel;
    // -----
    // Initiliazing all
    // -----

    hardReset();

});
</script>

{% endblock %}
