// Copyright (C) 2020 - Today: GRAP (http://www.grap.coop)
// @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
// License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

odoo.define("pos_meal_voucher.screens", function (require) {
    "use strict";

    var screens = require("point_of_sale.screens");
    var core = require('web.core');
    var formats = require('web.formats');
    var _t = core._t;
    var QWeb = core.qweb;
    var Model = require('web.DataModel');
    var config_parameter = new Model('ir.config_parameter');
    var utils = require("web.utils");
    var round_pr = utils.round_precision;

    screens.ScreenWidget.include({
        barcode_meal_voucher_payment_action: function (code) {
            var order = this.pos.get_order();
            if(!order.paper_meal_vouche_number_already_used(code.code)){
                // Display the payment screen, if it is not the current one.
                if (this.pos.gui.current_screen.template !== "PaymentScreenWidget"){
                    this.gui.show_screen("payment");
                }
                var paymentScreen = this.pos.gui.current_screen;
                var amount = code.value;

                // Check if the total amount is OK regarding to max amounts
                var total_eligible = order.get_total_meal_voucher_eligible();
                var max_amount = this.pos.config.max_meal_voucher_amount;
                var total_received = order.get_total_meal_voucher_received() + amount;
                let order_due = order.get_due();  

                // Display info popup if amount is too high
                // bug fix below : as order_due deduces previous paiement lines from initial due,
                // it must be compared to amount of current line only and not to total_received
                if (/*total_received*/amount > order_due) {
                    this.gui.show_popup("alert", {
                        'title': _t("Impossible d'utiliser ce Titre Restaurant"),
                        'body':  _t("Vous ne pouvez pas ajouter ce ticket restaurant car le montant total est supérieur au montant restant dû de la commande")
                    });
                    return;
                }
                if (total_received > total_eligible) {
                    this.gui.show_popup("alert", {
                        'title': _t("Impossible d'utiliser ce Titre Restaurant"),
                        'body':  _t("Vous ne pouvez pas ajouter ce ticket restaurant car le montant total est supérieur au montant éligible en titres restaurant")
                    });
                    return;
                } 
                if (total_received > max_amount && max_amount > 0) {
                    this.gui.show_popup("alert", {
                        'title': _t("Impossible d'utiliser ce Titre Restaurant"),
                        'body':  _t("Vous ne pouvez pas ajouter ce ticket restaurant car le montant total est supérieur au montant maximum autorisé")
                    });
                    return;
                } 

                var cashregister = null;
                // find a meal voucher cash register, if exist
                for ( var i = 0; i < this.pos.cashregisters.length; i++ ) {
                    if ( this.pos.cashregisters[i].journal.meal_voucher_type === "paper" ){
                        cashregister = this.pos.cashregisters[i];
                        break;
                    }
                }
                if (!cashregister){
                    return;
                }

                // Add new payment line with the amount found in the barcode
                this.pos.get_order().add_paymentline(cashregister);
                paymentScreen.reset_input()
                order.selected_paymentline.set_amount(amount);
                order.selected_paymentline.statement_note = code.code;
                paymentScreen.order_changes();
                paymentScreen.render_paymentlines();
                paymentScreen.$(".paymentline.selected .edit").text(paymentScreen.format_currency_no_symbol(amount));
                
            }else{
                this.gui.show_popup("alert", {
                    'title': _t("Titre restaurant déjà scanné"),
                    'body':  _t("Le ticket restaurant ") +
                    code.code + _t(" a déjà été scanné")
                });
            }
        },

        // Setup the callback action for the "meal_voucher_payment" barcodes.
        show: function () {
            this._super();
            this.pos.barcode_reader.set_action_callback(
                "meal_voucher_payment",
                _.bind(this.barcode_meal_voucher_payment_action, this));
        },
    });


    screens.OrderWidget.include({
        //check if POS if configured to accept payment in meal voucher
        meal_voucher_activated: function() {
          var is_meal_voucher_method = this.pos.cashregisters.map(function(cash_register) {
            if (cash_register.journal.meal_voucher_type === "paper" || cash_register.journal.meal_voucher_type === "dematerialized") {
              return true
            }
          })
          return is_meal_voucher_method.includes(true);
        },

        update_summary: function () {
            this._super.apply(this, arguments);
            var order = this.pos.get_order();

            if (!this.meal_voucher_activated()) {
              const meal_voucher_summary = this.el.querySelector(".summary .meal-voucher");
              if (meal_voucher_summary != null) {
                meal_voucher_summary.style.display = 'none';
              }
              // this.el.querySelector(".summary .meal-voucher").style.display = 'none';
              return;
            }
            if (!order.get_orderlines().length) {
                return;
            }
            this.el.querySelector(".summary .meal-voucher .value").textContent = this.format_currency(order.get_total_meal_voucher_eligible());
        },
    });


    screens.PaymentScreenWidget.include({
        //check if POS if configured to accept payment in meal voucher
        meal_voucher_activated: function() {
          var is_meal_voucher_method = this.pos.cashregisters.map(function(cash_register) {
            if (cash_register.journal.meal_voucher_type === "paper" || cash_register.journal.meal_voucher_type === "dematerialized") {
              return true
            }
          })
          return is_meal_voucher_method.includes(true);
        },

        // odoo/addons/point_of_sale/static/src/js/screens.js
        // We need to change the default behaviour of locking input with 
        // popup bcause of the papar meal voucher
        init: function(parent, options) {
            var self = this;
            this._super(parent, options);
            
            // This is a keydown handler that prevents backspace from
            // doing a back navigation. It also makes sure that keys that
            // do not generate a keypress in Chrom{e,ium} (eg. delete,
            // backspace, ...) get passed to the keypress handler.
            this.keyboard_keydown_handler = function(event){
                // We overight the expected behaviour if a popup is open
                if (self.gui.has_popup()) {
                    
                }
                else if (event.keyCode === 8 || event.keyCode === 46) { // Backspace and Delete
                    event.preventDefault();
                    console.log('keyboard_keydown_handler')
                    // These do not generate keypress events in
                    // Chrom{e,ium}. Even if they did, we just called
                    // preventDefault which will cancel any keypress that
                    // would normally follow. So we call keyboard_handler
                    // explicitly with this keydown event.
                    self.keyboard_handler(event);
                }
            };
            
            // This keyboard handler listens for keypress events. It is
            // also called explicitly to handle some keydown events that
            // do not generate keypress events.
            this.keyboard_handler = function(event){
                var key = '';
                // We overight the expected behaviour if a popup is open
                if (self.gui.has_popup()) {
                    
                }
                else{
                    if (event.type === "keypress") {
                        if (event.keyCode === 13) { // Enter
                            self.validate_order();
                        } else if ( event.keyCode === 190 || // Dot
                                    event.keyCode === 110 ||  // Decimal point (numpad)
                                    event.keyCode === 188 ||  // Comma
                                    event.keyCode === 46 ) {  // Numpad dot
                            key = self.decimal_point;
                        } else if (event.keyCode >= 48 && event.keyCode <= 57) { // Numbers
                            key = '' + (event.keyCode - 48);
                        } else if (event.keyCode === 45) { // Minus
                            key = '-';
                        } else if (event.keyCode === 43) { // Plus
                            key = '+';
                        }
                    } else { // keyup/keydown
                        if (event.keyCode === 46) { // Delete
                            key = 'CLEAR';
                        } else if (event.keyCode === 8) { // Backspace
                            key = 'BACKSPACE';
                        }
                    }
        
                    self.payment_input(key);
                    event.preventDefault();
                }
                
                
            };

            this.meal_voucher_issuers = [];
            // get meal voucher issuers from config
            config_parameter.call('get_param', ['pos_meal_voucher.meal_voucher_issuers'])
                .then( function(value){
                    try {
                        self.meal_voucher_issuers = JSON.parse(value);
                    } catch (error) {
                        self.gui.show_popup("alert", {
                            'title': _t("Problème de configuration du POS"),
                            'body':  _t("Le paramètre des émetteurs de CB déj est mal formatté dans la configuration d'Odoo. Veuillez demander à un.e salarié.e de régler ce problème (Configuration > Paramètres systèmes > pos_meal_voucher.meal_voucher_issuers). Vous pouvez continuer à utiliser la caisse.")
                        });
                    }
                });
        },

        payment_input: function(input) {
            var newbuf = this.gui.numpad_input(this.inputbuffer, input, {'firstinput': this.firstinput});

            this.firstinput = (newbuf.length === 0);
    
            if (newbuf !== this.inputbuffer) {
                this.inputbuffer = newbuf;
                var order = this.pos.get_order();
                // We choose to unactivated the editing of the amount for the paper meal voucher
                if (order.selected_paymentline && !order.selected_paymentline.is_paper_meal_voucher()) {
                    var amount = this.inputbuffer;
    
                    if (this.inputbuffer !== "-") {
                        amount = formats.parse_value(this.inputbuffer, {type: "float"}, 0.0);
                    }
    
                    order.selected_paymentline.set_amount(amount);
                    this.order_changes();
                    this.render_paymentlines();
                    this.$('.paymentline.selected .edit').text(this.format_currency_no_symbol(amount));
                }
            }

            var order = this.pos.get_order();

            if(order.selected_paymentline && order.selected_paymentline.is_dematerialized_meal_voucher()){
                var total_eligible = order.get_total_meal_voucher_eligible();
                var total_received = order.get_total_meal_voucher_received();
                var max_amount = this.pos.config.max_meal_voucher_amount;
                var current_max = total_eligible;
                if (max_amount) {
                    current_max = Math.min(total_eligible, max_amount);
                }

                // If there is change -> the amount of last payment line was above the order remaining due amount
                let order_change = order.get_change();
                if (order_change > 0) {
                    let last_line_amount = order.selected_paymentline.get_amount();
                    let limit_amount = round_pr(last_line_amount - order_change, this.pos.currency.rounding)
                    current_max = Math.min(current_max, limit_amount);
                }
                
                if (total_received > current_max){
                    this.gui.show_popup("alert", {
                        'title': _t("Meal Voucher Amount incorrect"),
                        'body':  _t("Le montant saisi est supérieur au maximum éligible/au montant restant dû de ") +
                           this.format_currency(current_max),
                    });
                    const max_current_amount = current_max-total_received+order.selected_paymentline.get_amount() ;
                    order.selected_paymentline.set_amount(max_current_amount);
                    this.order_changes();
                    this.render_paymentlines();
                    this.$('.paymentline.selected .edit').text(this.format_currency_no_symbol(max_current_amount));
                    this.inputbuffer = "";
                }

            }
        },

        click_paymentmethods_meal_voucher_mixed: function(id) {
            var cashregister = null;
            for ( var i = 0; i < this.pos.cashregisters.length; i++ ) {
                if ( this.pos.cashregisters[i].journal_id[0] === id ){
                    cashregister = this.pos.cashregisters[i];
                    break;
                }
            }
            this.pos.get_order().add_paymentline( cashregister );
            // manually set meal voucher
            this.pos.get_order().selected_paymentline.manual_meal_voucher = true;
            this.reset_input();
            this.render_paymentlines();
        },
        render_paymentmethods: function() {
            var self = this;
            var methods = this._super.apply(this, arguments);
            methods.on('click','.paymentmethod-meal-voucher-mixed',function(){
                self.click_paymentmethods_meal_voucher_mixed($(this).data('id'));
            });
            return methods;
        },
        remove_selected_paymentline: function(order) {
            this.pos.get_order().remove_paymentline(order.selected_paymentline);
            var paymentScreen = this.pos.gui.current_screen;
            paymentScreen.reset_input();
            paymentScreen.render_paymentlines();
        },
        click_paymentmethods: function(id) {
            var self = this;
            var methods = this._super.apply(this, arguments);


            var paymentScreen = this.pos.gui.current_screen;
            var order = this.pos.get_order();

            if (
                order.selected_paymentline.is_meal_voucher()
                && order.get_total_meal_voucher_eligible() == 0
            ) {
                this.gui.show_popup("alert", {
                    'title': _t("Impossible de payer en titre restaurant"),
                    'body':  _t("Aucun article du panier n'est éligible en titres restaurants (Montant éligible : 0€)."),
                    cancel: function() {
                        self.remove_selected_paymentline(order);
                    }
                });

                return false;
            }
                        
            // if user choose card meal voucher
            if(order.selected_paymentline.is_meal_voucher() && order.selected_paymentline.is_dematerialized_meal_voucher()){
                // Set selected payment line amount to 0 before any further check
                order.selected_paymentline.set_amount(0);
                paymentScreen.order_changes();
                paymentScreen.render_paymentlines();
                paymentScreen.$(".paymentline.selected .edit").text(paymentScreen.format_currency_no_symbol(0));

                // update selected (last) payment line & order with meal voucher data
                function update_order_meal_voucher_data(issuer = '') {
                    var total_eligible = order.get_total_meal_voucher_eligible();

                    // Function defined in module "lacagette_mona", that may not be activated.
                    // If said module is activated, consider this eligible amount.
                    if (typeof order.get_total_meal_vouchers_eligible_including_mona === "function") {
                        total_eligible = order.get_total_meal_vouchers_eligible_including_mona();
                    }

                    var total_received = order.get_total_meal_voucher_received();
                    var max_amount = self.pos.config.max_meal_voucher_amount;
                    var current_max = total_eligible;
                    if (max_amount) {
                        current_max = Math.min(total_eligible, max_amount);
                    }

                    // Check how much is still possible to pay with meal voucher
                    // The selected line is "by default" set to the rest to pay of the order
                    let max_current_amount = current_max-total_received +order.selected_paymentline.get_amount();

                    // Limit the amount paid to the remaining due amount
                    const order_due_amount = order.get_due();
                    max_current_amount = Math.min(max_current_amount, order_due_amount);
            
                    order.selected_paymentline.set_amount(max_current_amount);
                    order.selected_paymentline.set_meal_voucher_issuer(issuer);

                    paymentScreen.order_changes();
                    paymentScreen.render_paymentlines();
                    paymentScreen.$(".paymentline.selected .edit").text(paymentScreen.format_currency_no_symbol(max_current_amount));
                }

                // If required by the config, ask for the meal voucher issuer
                if (this.pos.config.meal_voucher_ask_for_issuer) {
                    let select_data = [{
                        'val': "",
                        'text': "- Choississez un émetteur"
                    }];

                    for (let issuer of this.meal_voucher_issuers) {
                        select_data.push({
                            "val": issuer,
                            "text": issuer
                        });
                    }

                    this.gui.show_popup("select-or-textinput", {
                        'title': _t("Émetteur du titre restaurant"),
                        'body':  _t("Si l'émetteur n'est pas dans la liste ci-dessus, veuillez le noter dans le champs ci-dessous : "),
                        'selectText':  _t("Veuillez sélectionner l'émetteur de CB déj dans la liste ci-dessous : "),
                        'selectData': select_data,
                        confirm: function(value) {
                            let issuer = value;
                            update_order_meal_voucher_data(issuer)
                        },
                        cancel: function(value) {
                            self.remove_selected_paymentline(order);
                        },
                    });
                } else {
                    update_order_meal_voucher_data();
                }
            }
            
            // If user choose paper meal voucher
            // Open a popup asking for the number of the meal voucher
            if(order.selected_paymentline.is_meal_voucher() && order.selected_paymentline.is_paper_meal_voucher()){
                // Maybe not needed but cleaner : Set selected payment line amount to 0 before any further check
                order.selected_paymentline.set_amount(0);
                paymentScreen.order_changes();
                paymentScreen.render_paymentlines();
                paymentScreen.$(".paymentline.selected .edit").text(paymentScreen.format_currency_no_symbol(0));

                this.gui.show_popup("textinput", {
                    'title': _t("Chèque Restaurant"),
                    'body':  _t("Pour ajouter un chèque restaurant, merci de scanner le code barre du chèque. Si le chèque est illisible, veuillez rentrer le code à la main."),
                    confirm: function(value) {
                        this.pos.get_order().remove_paymentline(order.selected_paymentline);
                        var paymentScreen = this.pos.gui.current_screen;
                        paymentScreen.reset_input();
                        paymentScreen.render_paymentlines();
                        var core = '';
                        odoo.define('coreservice', function(require){core=require('web.core');})
                        core.bus.trigger('barcode_scanned', value)

                    },
                    cancel: function(vaue) {
                        self.remove_selected_paymentline(order);
                    },
                });
            }
        },
        render_paymentlines: function() {
            var self  = this;
            
            this._super.apply(this, arguments);
            var order = this.pos.get_order();
            if (!order) {
                return;
            }

            // Update meal voucher summary
            var total_eligible = order.get_total_meal_voucher_eligible();
            var max_amount = this.pos.config.max_meal_voucher_amount;

            this.el.querySelector("#meal-voucher-eligible-amount").textContent = this.format_currency(Math.min(total_eligible,max_amount));

            var total_received = order.get_total_meal_voucher_received();
            this.el.querySelector("#meal-voucher-received-amount").textContent = this.format_currency(total_received);

            // Display warnings
            if (total_received > total_eligible) {
                this.$("#meal-voucher-eligible-warning").removeClass("oe_hidden");
            } else {
                this.$("#meal-voucher-eligible-warning").addClass("oe_hidden");
            }
            if (total_received > max_amount) {
                this.$("#meal-voucher-max-warning").removeClass("oe_hidden");
            } else {
                this.$("#meal-voucher-max-warning").addClass("oe_hidden");
            }

            if (!this.meal_voucher_activated()) {
              this.$(".meal-voucher-summary").addClass("oe_hidden");
            }
        },

        order_is_valid: function(force_validation) {
            var self = this;
            var order = this.pos.get_order();

            var total_eligible = order.get_total_meal_voucher_eligible();
            var total_received = order.get_total_meal_voucher_received();
            var max_amount = this.pos.config.max_meal_voucher_amount;

            var current_max = total_eligible;
            if (max_amount) {
                current_max = Math.min(total_eligible, max_amount);
            }

            // if the change is too large, it's probably an input error, if giving change is accepted make the user confirm.
            if (!force_validation && (total_received > current_max) && this.pos.config.meal_voucher_change_accepted) {
                this.gui.show_popup("confirm", {
                    'title': _t("Please Confirm Meal Voucher Amount"),
                    'body':  _t("You are about to validate a meal voucher payment of ") +
                           this.format_currency(total_received) +
                           _t(", when the maximum amount is ") +
                           this.format_currency(current_max) +
                           _t(".\n\n Clicking 'Confirm' will validate the payment."),
                    confirm: function() {
                        // Note: Due to the bad design of the original function
                        // the check "Large Amount" will be skipped in that case.
                        self.validate_order("confirm");
                    },
                });
                return false;
            }
            //else force user to correct
            else if (!force_validation && (total_received > current_max) && !this.pos.config.meal_voucher_change_accepted) {
                this.gui.show_popup("alert", {
                    'title': _t("Meal Voucher Amount incorrect"),
                    'body':  _t("Warning, the maximum amount of meal voucher accepted ( ") +
                           this.format_currency(current_max) +
                           _t(" ) is under the amount input ( ") +
                           this.format_currency(total_received) +
                           _t(")"),
                });
                return false;
            }
            return this._super.apply(this, arguments);
        },
    });

    /* point_of_sale/statis/src/js/screens.js */
    screens.ReceiptScreenWidget.include({
        render_receipt: function() {
            var order = this.pos.get_order();            
            order.meal_voucher_used = order.is_meal_voucher_used();

            this.$('.pos-receipt-container').html(QWeb.render('PosTicket',{
                widget:this,
                order: order,
                receipt: order.export_for_printing(),
                orderlines: order.get_orderlines(),
                paymentlines: order.get_paymentlines()
            }));
        }
    });
});