// Bootstrap manually the ng application, since :
// - it allows to correctly reinit the ng app after a (portal) page edition. Indeed, if we use the automatic init,
//   when the (portal) page is edited and then saved, the module are not registered again, so they are not executed
// - it is a good practice if we want to allow several ng app in the same html page (which could be the case with several portlets)
require( ["SHARED/jquery", "ticketAdminControllers"], function ( $,  ticketAdminControllers)
{
    const JIRASERVERURL = "https://jira.exoplatform.org";
	$( document ).ready(function() {
	  var csAppRoot = $('#csAddon');
      var csApp = angular.module('csApp', [])
      .factory('PagerService', PagerService);
      csApp.filter('startFrom', function() {
          return function(input, start) {
              start = +start; //parse to int
              return input.slice(start);
          }
      });

      csApp.filter('parseJiraUrl', function($sce) {
        return function (jiratickets) {
            if( jiratickets == null ){
                return $sce.trustAsHtml("");
            }
            const JIRA_PATTERN = /[A-Z]+-[0-9]+/g;
            const TASK_PATTERN = /[0-9]+/g;
            jiratickets = jiratickets.replace(/[|&;$%@"<>()+,]/g, " ").replace(/\s+/," ").trim();
            var jiralinks = "";
            jiratickets.split(" ").forEach( elt => {
               if(elt.match(JIRA_PATTERN)){
                   jiralinks += '<a target=\"_blank\" href=\"'+ JIRASERVERURL +'/browse/'+elt+'\" >'+elt+'</a> ';
               } else if(elt.match(TASK_PATTERN)){
                   jiralinks += '<a target="_blank" href="/portal/dw/tasks/taskDetail/'+elt+'" >'+elt+'</a> ';
                   getStatusColor(elt,'/portal/dw/tasks/taskDetail/'+elt)
               } else {
                   jiralinks += elt + ' ';
               }
            });
            return $sce.trustAsHtml(jiralinks.trim());
        }
      });
            csApp.filter('decodeStr', function($sce) {
            return function (str) {
				if( str == null ){
					return $sce.trustAsHtml("");
				}
                  var textArea = document.createElement('textarea');
				textArea.innerHTML = str;
				return $sce.trustAsHtml(textArea.innerText);
            }
      });
      csApp.directive('excelExport',
               function () {
                 return {
                   restrict: 'A',
                   scope: {
                   	fileName: "@",
                       data: "&exportData"
                   },
                   replace: true,
                   template: '<a data-placement="bottom" rel="tooltip" class="actionIcon" data-original-title="Export to Excel" ng-click="download()"><i class="uiIcon16x16FileExcel uiIconLightGray"></i></a>',
                   link: function (scope, element) {

                   	scope.download = function() {

                   		function datenum(v, date1904) {
                       		if(date1904) v+=1462;
                       		var epoch = Date.parse(v);
                       		return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
                       	};

                       	function getSheet(data, opts) {
                         	// Prepare Excel data:

           	var jsonToExport = [];

             // Headers:
           	 jsonToExport.push(["Rate", "Title", "type", "Severity", "status", "owner", "task", "assignee", "Creator", "Created", "Updated"]);
             // Data:
           	angular.forEach(data, function(value, key) {

                var rateValue='';
                if (value.customerSatisfied == false){
                    rateValue='Bad'
                }
                else if (value.customerSatisfied == true){
                    rateValue='Good'
                }
               jsonToExport.push([rateValue, value.title, value.type, value.severity, value.status, value.owner, value.attachedJira , value.assignee, value.creator, new Date(value.startDate), new Date(value.updateDate)]);
           	});
             data = jsonToExport;
                       		var ws = {};
                       		var range = {s: {c:10000000, r:10000000}, e: {c:0, r:0 }};
                       		for(var R = 0; R != data.length; ++R) {
                       			for(var C = 0; C != data[R].length; ++C) {
                       				if(range.s.r > R) range.s.r = R;
                       				if(range.s.c > C) range.s.c = C;
                       				if(range.e.r < R) range.e.r = R;
                       				if(range.e.c < C) range.e.c = C;
                       				var cell = {v: data[R][C] };
                       				if(cell.v == null) continue;
                       				var cell_ref = XLSX.utils.encode_cell({c:C,r:R});

                       				if(typeof cell.v === 'number') cell.t = 'n';
                       				else if(typeof cell.v === 'boolean') cell.t = 'b';
                       				else if(cell.v instanceof Date) {
                       					cell.t = 'n'; cell.z = XLSX.SSF._table[14];
                       					cell.v = datenum(cell.v);
                       				}
                       				else cell.t = 's';

                       				ws[cell_ref] = cell;
                       			}
                       		}
                       		if(range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
                       		return ws;
                       	};

                       	function Workbook() {
                       		if(!(this instanceof Workbook)) return new Workbook();
                       		this.SheetNames = [];
                       		this.Sheets = {};
                       	}

                       	var wb = new Workbook(), ws = getSheet(scope.data());
                       	/* add worksheet to workbook */
                       	wb.SheetNames.push(scope.fileName);
                       	wb.Sheets[scope.fileName] = ws;
                       	var wbout = XLSX.write(wb, {bookType:'xlsx', bookSST:true, type: 'binary'});

                       	function s2ab(s) {
                       		var buf = new ArrayBuffer(s.length);
                       		var view = new Uint8Array(buf);
                       		for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
                       		return buf;
                       	}

                   		saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), scope.fileName+'.xlsx');

                   	};

                   }
                 };
               }
            );

        function stringToRGB(str){
            var hash = 0;
            for (var i = 0; i < str.length; i++) {
                hash = str.charCodeAt(i) + ((hash << 5) - hash);
            }
            var c = (hash & 0x00FFFFFF)
                    .toString(16)
                    .toUpperCase();
            return "00000".substring(0, 6 - c.length) + c;
        }


        function getStatusColor(item, url){
            $.ajax({
                url: '/portal/rest/tasks/logs/'+item,
                type: "GET",
                dataType: 'json',
                async: true,
                success: function (data) {
                    if (! data || data.length == 0 || ! data[data.length - 1].task.status){
                        return 0;
                    }
                    var status = data[data.length - 1].task.status.name;
                    var affectedColor = "#"+stringToRGB(status);   
                    $("a[href$='"+url+"']").css('color', affectedColor);
                    $("a[href$='"+url+"']").attr('title', status.match(/[A-Z][a-z]+/g) ? status.match(/[A-Z][a-z]+/g).join(" ") : status);
                }
            });
        }
        function PagerService() {
          // service definition
          var service = {};

          service.GetPager = GetPager;

          return service;

          // service implementation
          function GetPager(totalItems, currentPage, pageSize) {
              // default to first page
              currentPage = currentPage || 1;

              // default page size is 10
              pageSize = pageSize || 10;

              // calculate total pages
              var totalPages = Math.ceil(totalItems / pageSize);

              //set current page to latest page if it exceeds total pages
              if(currentPage > totalPages){
                currentPage = totalPages;
              }

              var startPage, endPage;
              if (totalPages <= 10) {
                  // less than 10 total pages so show all
                  startPage = 1;
                  endPage = totalPages;
              } else {
                  // more than 10 total pages so calculate start and end pages
                  if (currentPage <= 6) {
                      startPage = 1;
                      endPage = 10;
                  } else if (currentPage + 4 >= totalPages) {
                      startPage = totalPages - 9;
                      endPage = totalPages;
                  } else {
                      startPage = currentPage - 5;
                      endPage = currentPage + 4;
                  }
              }

              // calculate start and end item indexes
              var startIndex = (currentPage - 1) * pageSize;
              var endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1);

              // create an array of pages to ng-repeat in the pager control
              var pages = [];
                  for (var i = startPage; i <= endPage; i++) {
                      pages.push(i);
                  }
              //var pages = _.range(startPage, endPage + 1);

              // return object with all pager properties required by the view
              return {
                  totalItems: totalItems,
                  currentPage: currentPage,
                  pageSize: pageSize,
                  totalPages: totalPages,
                  startPage: startPage,
                  endPage: endPage,
                  startIndex: startIndex,
                  endIndex: endIndex,
                  pages: pages
              };
          }
      }
      try {
	      csApp.controller('csCtrl', ticketAdminControllers);
		  angular.bootstrap(csAppRoot, ['csApp']);
      } catch(e) {
    	  console.log(e);
      }
	});
});
