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

    var screens = require("point_of_sale.screens");
    var models = require('point_of_sale.models');
    var core = require('web.core');
    var dataModel = require('web.DataModel');
    var lacagette_products = new dataModel('lacagette.products');
    var _t = core._t;
    const interval = 60 * 60 * 1000; // used for last_price_change call
    var reload_on_prices_change = false;
    models.load_fields("pos.config", ['reload_on_prices_change', 'can_cclose_pos_with_ongoing_order']);
    var close_button_action_setup = false;

    const update_last_price_change_data = async function () {
        /*
            Ask odoo server data about last prices change
            According to response, pos_session variables will be set 
            in order to make decision about reloading or not pos data
        */

        lacagette_products.call('get_last_price_change')
        .then(
            function(received) {
                if (typeof received.data !== "undefined" && received.data.length > 0) {
                    if (typeof posmodel.pos_session.last_price_update != "undefined") {
                        posmodel.pos_session.previous_price_update = posmodel.pos_session.last_price_update
                    }
                    posmodel.pos_session.last_price_update = received.data[0].write_date
                    posmodel.pos_session.last_price_update_load = Date.now();
                    if (posmodel.pos_session.last_price_update != posmodel.pos_session.previous_price_update)
                        posmodel.pos_session.needs_reload = true;

                }
                
            }
        )
        .fail(function(result, ev){
            // Store event date. Used to make the "reloading" decision
            posmodel.pos_session.last_network_failure = Date.now();
            ev.preventDefault();
        })
     }

    screens.ClientListScreenWidget.include({
        init: function(parent, options) {
            this._super(parent, options);
            reload_on_prices_change = this.pos.config.reload_on_prices_change;
            
            if (reload_on_prices_change) {
                posmodel.pos_session.load_at = Date.now();
                posmodel.pos_session.needs_reload = false;
                update_last_price_change_data(); // don't wait for timer for first time
                const confirmRefresh = event => {
                    // Called when unload is unsafe
                    event.preventDefault();
                    const message = _t("Are you sure you want to refresh the page?")
                    (event || window.event).returnValue = confirmationMessage; //Gecko + IE
                    return message; //Gecko + Webkit, Safari, Chrome etc.
                };
                const checkUnload = event => {
                  try {
                    if (window.navigator.onLine == true) {
                        return undefined;
                    } else {
                        return confirmRefresh(event);
                    }
                  } catch(err) {
                    return confirmRefresh(event);
                  }
                  
                }

                window.addEventListener("beforeunload", checkUnload, { capture: true });
                // Let's init a perpetual regular call to prices update data
                setInterval(() => {
                    // catch all the errors.
                    update_last_price_change_data().catch(console.log);
                }, interval); 
            }

        },
        show: function(){
            if (typeof posmodel.pos_session.previous_price_update != "undefined"
                && posmodel.pos_session.needs_reload == true) {
                /*
                    At least one product price has been changed since pos session has been started
                    We can't reload page without having a look to network state
                    If page reload is called while network is down, the browser will show a blank page
                    and there will be no way to show POS screens again.
                    A smarter way to refresh products data would be to process products data retrieve,
                    in ajax mode, without having to reload whole page code.
                    It could be the next improve step for this module.
                */
                const now = Date.now();
                let can_reload_page = false;
                
                if (typeof posmodel.pos_session.last_network_failure == "undefined") {
                    /* 
                      no network failure while retreiving price change data.
                      It doesn't mean that network is now available, 
                      since it could be shutdown after last call
                      Let reload available 
                      only if wifi icon is green is better
                      but not safe at all !
                      beforeunload event capture will ask user for confirmation if network has gone
                    */
                    if ($('.js_connected.oe_icon.oe_green').length > 0)
                        can_reload_page = true;
                } else {
                    // one network failure occured
                    if (posmodel.pos_session.last_price_update_load > posmodel.pos_session.last_network_failure) {
                        can_reload_page = true;
                    }
                }

                if (can_reload_page === true) {
                    this.gui.show_popup("alert", {
                        'title': _t("POS data must been refreshed"),
                        'body':  _t("Some product prices have been changed, page will be refreshed")
                    });
                    setTimeout(function(){
                        window.location.reload();
                    }, 5000);
                } else {
                    this._super();
                }
            } else {
                this._super();
            }
            
        }
    });

    screens.ScreenWidget.include({
        init: function(parent,options){
            this._super(parent,options);

            /*
             * If activated in this pos session, prevent closing the session if there is an ongoing order.
             * This is a hacky DOM manipulation: the user can technically close the session if he closes the popup and press 'Close' again in less than 2s. 
             * But this is very unlikely.
             * 
             * ScreenWidget is a base widget extended by many others, we do this here to be sure this code is called...
             */
            if (close_button_action_setup === false) {
                // ... but we need to make sure it is called only once 
                close_button_action_setup = true;

                if (this.pos.config.can_close_pos_with_ongoing_order === false) {
                    let header_nodes = document.querySelectorAll(".pos-topheader .pos-rightheader div");
                    let close_button_div = header_nodes[header_nodes.length- 1];
                    let self = this;

                    close_button_div.addEventListener("click", function(e) {
                        let order = self.pos.get_order();
                        if (!order.is_empty()) {
                            if (close_button_div.classList.contains("confirm")) {
                                close_button_div.classList.remove("confirm");
                                close_button_div.textContent = _t('Close');
                            }

                            self.gui.show_popup("alert", {
                                'title': _t("Impossible de fermer la caisse"),
                                'body':  _t("Des commandes sont encore en cours.")
                            });
                        }
                    });
                }
            }   
        },
    });
});