require('../../../node_modules/canvasjs/dist/canvasjs.3');

var $ = require('jquery');
// JS is equivalent to the normal "bootstrap" package
// no need to set this to a variable, just require it
require('bootstrap-sass');
// or you can include specific pieces
// require('bootstrap-sass/javascripts/bootstrap/tooltip');
// require('bootstrap-sass/javascripts/bootstrap/popover');

$(document).ready(function () {
    $('[data-toggle="popover"]').popover();
    $('#menu_button').on('click', function () {
        $('#menu-dashboard').toggleClass('shown');
    })
});

require('./caisseCtrl');
require('./dashboard');
var PrevisionnelCtrl = require('./previsionnel');

console.log('hello console for main.js');
var stuff = ['initialstuff'];

// TODO split controllers in other files
angular
  .module('caisse', [])
  .controller('CaisseCtrl', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
      $scope.productsFromDB = [];   // loaded products
      $scope.categories = [];       // product categories
      $scope.sellingComment = "un gens";      // comment about the client or the current selling
      $scope.initLoadDone = false;  // becames true after first init of product loading
      $scope.recentSellings = [];
      $scope.lesParams = {};
      $scope.countProductsSoldForActiveFestival = {};
      $scope.paidAmount = 0;
      $scope.expressSelling = true;
      $scope.pausedSelling = [];
      $scope.show_config = {
          stock_count: false,
          sold       : true,
      };
      $scope.activeItemsSold = [];    // list of products ID to sell
      $scope.activeSelling = [];    // list of products to sell
      $scope.activeSellingFiltered = [];    // list of products to sell
      $scope.activeFestival = {     // an event where selling take place
          id            : null,
          name          : "le festival",
          dateCreation  : new Date(),
          chiffreAffaire: 0,
          clientsCount  : 0,
          commentaire   : ""
      };

      /**
       * set the right paid amount
       */
      $scope.setRightAmountPaid = function () {
          // debugger;
          $scope.paidAmount += $scope.sumOfList($scope.activeSelling);
      }
      /**
       * deduplicate the active selling items in the view,
       * show a count for each of them when there are more than one
       */
      $scope.refreshDeduplicateSellings = () => {
          let soldObjectsIdsCount = {}
          $scope.activeSellingFiltered = {};

          $scope.activeSelling.forEach(elem => {
              let groupId = elem.id;
              let group = soldObjectsIdsCount[groupId];
              if (group) { // sort elements by the product id corresponding
                  group.count++;
                  group.totalPrice += (elem.price * 1);
                  group.sellings.push(elem);
              } else {

                  soldObjectsIdsCount[groupId] = {
                      groupId   : groupId,
                      count     : 1,
                      name      : elem.name,
                      unitPrice : elem.price * 1,
                      totalPrice: elem.price * 1,
                      sellings  : [elem],
                  }
              }
          });
          $scope.activeSellingFiltered = soldObjectsIdsCount;
      }

      /**
       * get the sum of products prices
       * @param list
       * @returns {number}
       */
      $scope.sumOfList = function (list) {
          let counter = 0;
          for (let i = 0; i < list.length; i++) {
              counter += list[i].price * 1;
          }
          return counter;
      };
      /**
       * sum of current selling list prices
       * @returns {number}
       * @constructor
       */
      $scope.CurrentSellingTotal = function () {
          return $scope.sumOfList($scope.activeSelling);
      };

      $scope.categoriesVisibleCount = function () {
          let count = 0;
          $scope.categories.forEach(function (elem) {
              elem.hidden ? count++ : "";
          });
          return count;
      }

      $scope.regenActiveSellingIds = function () {
          $scope.activeItemsSold = [];
          $scope.paidAmount = 0;
          for (let obj in $scope.activeSelling) {
              $scope.activeItemsSold.push(obj.id);
          }
      };
      $scope.stuff = stuff;
      $scope.setActiveSelling = function (selling) {
          $scope.activeSelling = selling;
      };
      $scope.pauseSelling = function (selling) {
          $scope.pausedSelling.push(selling);
      };
      /**
       * add to current sell list
       * @param product
       */
      $scope.addProduct = function (product) {
          product.stockCount--;
          $scope.activeSelling.push(product);
          $scope.activeItemsSold.push(product.id);
          $scope.regenActiveSellingIds();
          $scope.refreshDeduplicateSellings();
          $scope.setRightAmountPaid();
      };
      /**
       * remove from current sell list
       * @param product
       */
      $scope.removeProduct = function (product, index) {
          product.stockCount++;
          $scope.activeSelling.splice($index, 1);
          $scope.regenActiveSellingIds();
          $scope.refreshDeduplicateSellings();
      };
      /**
       * remove all products of a certain group id in the active Selling
       * @param productId
       * @returns {*}
       */
      $scope.removeGroupeProducts = function (productId) {
          console.log("##### removeGroupeProducts", productId);
          console.log("$scope.activeSelling", $scope.activeSelling);
          $scope.activeSelling = $scope.activeSelling.filter(elem => elem.id != productId)
          console.log("$scope.activeSelling", $scope.activeSelling);
          $scope.regenActiveSellingIds();
          $scope.refreshDeduplicateSellings();
      }
      $scope.removeAll = function () {

          $scope.activeSelling = [];
          $scope.regenActiveSellingIds();
          $scope.refreshDeduplicateSellings();
      };
      $scope.pauseSelling = function () {
          $scope.pausedSelling.push(angular.copy($scope.activeSelling));
          $scope.activeSelling = [];
      };
      $scope.setBackPausedSelling = function (sellingList, index) {
          $scope.activeSelling = angular.copy(sellingList);
          $scope.pausedSelling.splice(index, 1);
      };

      $scope.clearSellingComment = function () {
          $scope.sellingComment = '';
          document.querySelector('.client-now input').focus();
      };
      $scope.clearCurrentSelling = function () {
          $scope.paidAmount = 0;
          $scope.clearSellingComment();
          $scope.activeSelling = [];
          $scope.removeAll();
      };

      // http related calls
      $scope.fetchProductsFromDB = function () {
          console.log('fetch products...');
          $http.get('get-my-products').then((rep) => {

              console.log('ok', rep);
              customCategories = [];
              for (let c of rep.data.categories) {
                  c.hidden = false;
                  customCategories.push(c);
              }
              console.log('customCategories', customCategories);
              $scope.categories = customCategories;
              $scope.productsFromDB = customCategories;
              // $scope.recentSellings = rep.data.history;
              // festoche
              $scope.activeFestival.id = rep.data.lastFestival.id;
              $scope.activeFestival.name = rep.data.lastFestival.name;
              $scope.activeFestival.dateCreation = rep.data.lastFestival.dateCreation;
              $scope.activeFestival.commentaire = rep.data.lastFestival.commentaire;
              $scope.activeFestival.chiffreAffaire = rep.data.lastFestival.chiffreAffaire;
              $scope.activeFestival.fondDeCaisseAvant = rep.data.lastFestival.fondDeCaisseAvant;
              $scope.activeFestival.fondDeCaisseApres = rep.data.lastFestival.fondDeCaisseApres;
              $scope.activeFestival.clientsCount = rep.data.lastFestival.clientsCount;
              // stat count for items
              $scope.countProductsSoldForActiveFestival = rep.data.lastFestival.sold;
              console.log(' $scope.countProductsSoldForActiveFestival', $scope.countProductsSoldForActiveFestival);
              //done
              $scope.initLoadDone = true;
          }, (err) => {
              console.log(err);
              $scope.initLoadDone = true;
          });
      };

      /**
       * sell one product, assuming the client has the right amount of money
       * @param product
       */
      $scope.expressSell = function (product) {
          $scope.addProduct(product);
          $scope.sendForm();
      };
      $scope.recentId = 0;
      $scope.logger = function (stuff) {
          console.log('logger', stuff);
      };
      $scope.sendForm = function () {
          console.log('$scope.sellingComment', $scope.sellingComment);
          console.log("$scope.activeSelling", $scope.activeSelling);
          let lesParams = {
              paidByClient  : $scope.paidAmount,
              sellingComment: $scope.sellingComment,
              activeSelling : $scope.activeSelling,
              activeFestival: $scope.activeFestival
          };
          $scope.recentSellings.push({
              id        : $scope.recentId++,
              amount    : $scope.CurrentSellingTotal(),
              paidAmount: $scope.paidAmount,
              products  :
                angular
                  .copy($scope.activeSelling)
          });
          console.log('$scope.recentSellings', $scope.recentSellings);
          $scope.lesParams = lesParams;
          $http({
              method : 'POST',
              url    : 'add-selling',
              headers: {
                  'Content-Type': 'application/json'
              },
              data   : lesParams  // pass in data as strings
          }).then(function (rep) {

              $scope.clearCurrentSelling();
              // if successful, bind success message to message
              $scope.successMessage = rep.data.message;
              $scope.activeFestival.chiffreAffaire = rep.data.newChiffreAffaire;
              $scope.activeFestival.clientsCount = rep.data.clientsCount;
              $scope.countProductsSoldForActiveFestival = rep.data.activeFestival.sold;
              $scope.showTemporaryMessage();
              console.log(rep);
              if (!rep.success) {
                  // if not successful, bind errors to error variables
                  $scope.errors = rep.errors;
              }
          }, function (rep) {
              console.log('nope! ', rep.data);
              $scope.showTemporaryErrorMessage();
          })
          ;
      };

      $scope.sellingOk = false;
      $scope.sellingError = false;
      $scope.tempMessage = {};
      $scope.showTemporaryMessage = function () {
          console.log('show message');
          if ($scope.sellingOk) {
              $scope.sellingOk = false;
              return;
          }
          $scope.sellingOk = true;
          $timeout.cancel($scope.tempMessage);
          $scope.tempMessage = $timeout(function () {
              console.log('hide message');
              $scope.sellingOk = false;
          }, 2000)
      };
      $scope.showTemporaryErrorMessage = function () {
          console.log('show message');
          if ($scope.sellingError) {
              $scope.sellingError = false;
              return;
          }
          $scope.sellingError = true;
          $timeout.cancel($scope.tempMessage);
          $scope.tempMessage = $timeout(function () {
              console.log('hide message');
              $scope.sellingError = false;
          }, 2000)
      };
      $scope.init = (function () {
          $scope.fetchProductsFromDB();
      })();
  }])
  .controller('previsionnelCtrl', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {

      $scope.config = {
          initialLoadingDone    : false,
          loading               : false,
          lines                 : 24,
          debounceTime          : 300, // miliseconds to wait before updating model and saving changes
          /**
           * expenses kind of the user
           */
          disponibility         : 5000,
          averageMonthlyEarnings: 600,
          warningThershold      : 2000,
          showDelays            : false,
          showRepeats           : false,
          monthsBeforeNoMoney   : null,
      };

      let exampleExpenses = [
          {name: "appart", amount: 800, delay: 0, repeat: $scope.config.lines, enabled: true},
          {name: "assurance voiture", amount: 50, delay: 0, repeat: $scope.config.lines, enabled: true},
          {name: "internet", amount: 20, delay: 0, repeat: $scope.config.lines, enabled: true},
          {name: "elec", amount: 100, delay: 0, repeat: $scope.config.lines, enabled: true},
          {name: "chat", amount: 20, delay: 0, repeat: $scope.config.lines, enabled: true},
          {name: "transports", amount: 70, delay: 0, repeat: $scope.config.lines, enabled: false},
      ];

      // $scope.expenses=[];
      $scope.expenses = exampleExpenses;

      /**
       * sum of all monthly expenses, ignoring delay
       * @returns {number}
       */
      $scope.sumMonthlyExpenses = () => {
          let sum = 0;
          $scope.expenses.forEach((elem) => {
              if (elem.enabled) {
                  sum += elem.amount;
              }
          })
          return sum;
      };
      $scope.previsionTable = [];
      $scope.calculatePrevisionTable = () => {
          let turns = $scope.config.lines;
          let monthly = $scope.sumMonthlyExpenses();
          let available = $scope.config.disponibility;
          let previsionTable = [];
          let changedNoMoneyConfig = false;
          $scope.config.monthsBeforeNoMoney = null;
          for (let i = 0; i <= turns; i++) {
              // TODO take in account delays in expenses
              available = available - monthly + $scope.config.averageMonthlyEarnings;
              let newLine = {
                  expense  : monthly,
                  available: available,
              };

              if (available <= 0 && !changedNoMoneyConfig) {
                  $scope.config.monthsBeforeNoMoney = i;
                  changedNoMoneyConfig = true;
              }
              previsionTable.push(newLine);
          }
          $scope.previsionTable = previsionTable;
          $scope.makeGraphPointsOfPrevisionTable(previsionTable);
          return previsionTable;
      };
      $scope.graphPointsPrevision = [];
      $scope.makeGraphPointsOfPrevisionTable = (previsionTable) => {
          console.log("previsionTable", previsionTable);
          $scope.graphPointsPrevision = [];
          for (let i = 0; i < previsionTable.length; i++) {
              $scope.graphPointsPrevision.push({
                  label: previsionTable[i].available + " euros restants dans " + i + " mois",
                  y    : previsionTable[i].available,
                  x    : i,
              })
          }

      }

      $scope.updateconf = (rep) => {
          // update view calculs
          $scope.calculatePrevisionTable();
          $scope.updateCanevas()
          // flags
          $scope.config.loading = false;
          $scope.config.initialLoadingDone = true;
          $scope.config.disponibility = rep.data.disponibility;
          $scope.config.averageMonthlyEarnings = rep.data.averageMonthlyEarnings;
          // default data when user has nothing saved
          console.log('rep.data.expenses.length', rep.data.expenses.length)
          if (!rep.data.expenses.length) {
              $scope.expenses = exampleExpenses;
          } else {
              $scope.expenses = rep.data.expenses;
          }
      };
      // http related calls
      $scope.fetchExpenses = () => {
          console.log('fetch expenses...');
          $scope.config.loading = true;

          $http.get('get-my-expenses').then((rep) => {
                console.log('get-my-expenses', rep.data.expenses);
                $scope.updateconf(rep)
            },
            $scope.manageError)
      };
      $scope.save = function () {
          if ($scope.config.loading) {
              console.log('already saving');
              return;
          }
          console.log('update expenses...');
          $scope.config.loading = true;
          $http.post('save-my-expenses', {
              expenses: $scope.expenses,
              config  : $scope.config
          })
            .then((rep) => {
                  console.log('save-my-expenses', rep);
                  $scope.updateconf(rep)
              },
              $scope.manageError)
      };
      $scope.addExpense = function () {
          $scope.expenses.push({
              name  : "",
              repeat: 0,
              delay : 0,
              amount: 0,
          })
      };
      $scope.init = function () {
          $scope.fetchExpenses();
      };
      $scope.manageError = (error) => {
          console.error(error);
          $scope.config.loading = false;

      };
      $scope.updateCanevas = function () {
          var dataPoints = $scope.graphPointsPrevision;
          var chartContainer = new CanvasJS.Chart("simulationPrevision", {
              title: {
                  text: "Euros disponibles dans le temps"
              },
              // animationEnabled: true,
              data : [
                  {
                      // Change type to "doughnut", "line", "splineArea", etc.
                      type      : "splineArea",
                      dataPoints: dataPoints
                  }
              ]
          });
          chartContainer.render();
      };
      $scope.init();
  }]);