'use strict';

angular.module('journey-manager', ['cs.services', 'ark-ui-bootstrap',
                                   'cs.services.util', 'angularMoment'])
.directive('interactionTimelineView', function () {
	return {
		templateUrl: function(ele,attr){
			if (attr.csUrl){
				return attr.csUrl + '/../../develop/app/modules/context-services/interaction-view.html'
			} else {
				return './app/modules/context-services/interaction-view.html'
			}
		},
		restrict: 'E',
		scope:{
			moments : '='
		}
	};
}).directive('interactionTimelineMoment', function($timeout) {
	return {
		link: function(scope, ele, attrs){
			scope.getUrl = function(){
				return 'app/modules/context-services/interaction-moment.html';
			}
		},
		restrict: 'EA',
		template: '<div ng-include src="getUrl()" class="moment"></div>'
	};
	
}).filter('datefilter', function(){
	return function(input){
		input = input || '';
		var date = new Date(input);
		date = date.toUTCString();
		return date;
	};
}).directive('additionalInfoTemplate', function($compile, PROFILE_CONFIG){
	var renderTemplate = function(addInfo){
		return addInfo;
	}
	var linkingFunction = function(scope, ele, attrs){
		//scope.expressionsList = PROFILE_CONFIG.STATE_EXPRESSIONS;
		
		ele.html("<p class=\"additionalInfo\">" + scope.additionalInfo.expression + "</p>");//.show();
		$compile(ele.contents())(scope);
	}
	return{
		restrict: "E",
		link: linkingFunction,
		scope: {
			additionalInfo : '=info'
		}
	};
}).directive('csInteractionTimelineView', function (csApi, csUtils, $http, TIMELINE_ICONS, TIMELINE_COLORS, $filter, PROFILE_CONFIG) {
	return {
		templateUrl: function(ele, attr){

				return 'app/modules/context-services/interaction-view.html'

		},
		restrict: 'EA',
		scope: {
			csUrl : '@',
			serviceId : '@',
			stateObj : '=?'
			//hideMoment : '='				
		},
		link: function(scope, ele, attrs){
			var defaultIconMaps = {
					100 : 'fonticon icon-audio-voice',
					101 : 'fonticon icon-agent',
					102 : 'fonticon icon-email',
					103 : 'fonticon icon-voicemail',
					104 : 'fonticon icon-email',
					105 : 'fonticon icon-chat',
					106 : 'fonticon icon-chat-video',
					107 : 'fonticon icon-cobrowse',
					108 : 'fonticon icon-checkbox',
					109 : 'fonticon icon-share',
					110 : 'fonticon icon-page-single',
					111 : 'fonticon icon-agent-status-work',
					112 : 'fonticon icon-iw-active-circle-callback',
					113 : 'fonticon icon-printer',
					114 : 'fonticon icon-people-chat',
					115 : 'fonticon icon-event-cluster',
					116 : 'fonticon icon-alert-triangle',
					117 : 'fonticon icon-sms-transfer',
					118 : 'fonticon icon-help',
					119 : 'fonticon icon-agent-status-work',
					120 : 'fonticon icon-outbound',
					121 : 'fonticon icon-training',
					122 : 'fonticon icon-sms-message',
					123 : 'fonticon icon-inspect',
					124 : 'fonticon icon-inspect-chat',
					'default' : 'fonticon icon-agent-status-queue-empty'
				};

				var defaultColorMap = {
					100 : '#203B73',
					101 : '#2E69DB',
					102 : '#5E99FF',
					103 : '#9BBCE0',
					104 : '#5A6B8C',
					105 : '#0F6A51',
					106 : '#569180',
					107 : '#14819C',
					108 : '#7EC0C2',
					109 : '#AFD6D2',
					110 : '#584FB3',
					111 : '#7272E0',
					112 : '#B9B9F0',
					113 : '#575746',
					114 : '#827C75',
					115 : '#C9C4B7',
					116 : '#8C6542',
					117 : '#8A4D67',
					118 : '#C48C88',
					119 : '#EBC8BE',
					120 : '#724787',
					121 : '#B07EC2',
					122 : '#D1B4D9',
					123 : '#555D66',
					124 : '#4AC764',
					'default' : '#555D66'
				}

			function setDefaultIcons(){
				scope.iconMaps = defaultIconMaps;
			}

			function setDefaultColors(){
				scope.colorMap = defaultColorMap;
			}

			scope.maxMoments = 9;
			//scope.showMoment = true; bool used to show moments until they can not fit into the div (height set by user)
			
			//code below for when user clicks on KPI or other option, changes journey details variable to false
			scope.stateObj.switchToJD = false;
			scope.stateObj.switchJDbool = function(){
				scope.stateObj.switchToJD = false;
			}
			
			scope.expressionsList = PROFILE_CONFIG.STATE_EXPRESSIONS;
			
			function updateTimeline(){
				scope.showUp = false;
				//scope.showDown = true;
				var momentCounter = 0;
				var dateCounter = 0;
				var filePath = 'url.txt';
				$http.get(filePath)
				.then(function(response) {
				// The URL is in the response.data
				var baseUrl = response.data.trim();
				
				if(!baseUrl){
					baseUrl = '/genesys/1/cs';
				}
					
				if (scope.csUrl && scope.serviceId){
					csApi.getBusinessAttributes(baseUrl).then(function(data){
						scope.businessAttributes = data;		
						
						csApi.queryStates(baseUrl, scope.serviceId, {'extensions': '*'}).then(function(response){	//gets extensions
							scope.states = response.data;

							scope.minIndex = 0;
							//scope.maxMoments = 9;
							scope.dates = [];
							scope.hiddenDates = {};
							
							if (scope.states === ""){ 
								scope.states = []; 
							}
							if (PROFILE_CONFIG.TIMELINE_CUSTOMIZATION && PROFILE_CONFIG.TIMELINE_CUSTOMIZATION.stateOrder === 'reverse'){
								scope.states = scope.states.sort(function(node1, node2){
									return new Date(node2.started.timestamp).getTime() - new Date(node1.started.timestamp).getTime();
								});
							} else {
								scope.states = scope.states.sort(function(node1, node2){
									return new Date(node1.started.timestamp).getTime() - new Date(node2.started.timestamp).getTime();
								});
							}
							
							var timelineFull = false;

							function getDisplayName(i){
								if(angular.isDefined(scope.businessAttributes.state[scope.states[i].state_type].display_name) &&
									scope.businessAttributes.state[scope.states[i].state_type].display_name !== ''){
									return scope.businessAttributes.state[scope.states[i].state_type].display_name;
								} else {
									return scope.businessAttributes.state[scope.states[i].state_type].name;
								}
							}

							for (i = 0; i < scope.states.length; i++) {					
								//Convert UTC Timestamp to local Timestamp							
								var localTimeStamp = moment(scope.states[i].started.timestamp).format("YYYY-MM-DD HH:mm:ss");

								//Determine what the timezone offset is to display it as a label
								var newDate = new Date();
								var offset = newDate.getTimezoneOffset() / 60;
								var timezoneLabelOffset = "";
								if (offset < 0) {
									timezoneLabelOffset = "GMT+" + offset * -1;
								} else if (offset > 0) {
									timezoneLabelOffset = "GMT-" + offset;
								} else {
									timezoneLabelOffset = "GMT";
								}
								
								if (scope.states[i].hasOwnProperty('completed')) {
								
									var stateBeginDate = scope.states[i].started.timestamp;
									var stateEndDate = scope.states[i].completed.timestamp;
																
									var stateDuration = Date.parse(stateEndDate) - Date.parse(stateBeginDate) ;
								
									scope.states[i].duration = stateDuration; 
									
								}
								
								var momentObject = {
										'title' : (scope.businessAttributes.state[scope.states[i].state_type] ?
												getDisplayName(i) : scope.states[i].state_type),
										'icon': TIMELINE_ICONS.default || defaultIconMaps.default,
						                'color': {'background-color' : (scope.states[i].completed ? '#2e69db' : '#f0ad4e')},
						                'badgeColor': {'background-color' : TIMELINE_COLORS.default || defaultColorMap.default},
						                'time': localTimeStamp.split(' ')[1],
						                'timezoneOffset' : timezoneLabelOffset,
						                'body': scope.states[i].state_id,
						                'tags': '[]',        
						                'activeTasks' : scope.states[i].active_tasks,
						                'completedTasks': scope.states[i].completed_tasks,
						                'reverse' : momentCounter % 2,
						                'startObj' : scope.states[i].started,
						                'completed' : (scope.states[i].completed ? true : false),
						                'completeObj':  scope.states[i].completed,
						                'beginDate' : scope.states[i].started.timestamp,
						                'duration' : (scope.states[i].duration !== undefined ? csUtils.convertToReadableDate(stateDuration) :
						                	csUtils.convertToReadableDate((new Date().getTime() - moment(localTimeStamp).toDate().getTime()))),
						                'additionalData' : []
								};
								
								//code below adds additional data to moment object for display in state box for vertical timeline
								var AIConstructor = function(label, substance, exp){
									this.name = label;
									this.value = substance;
									this.expression = exp
								};
								
								scope.getMediaDisplayName = function(mediaType){
									if (scope.businessAttributes['media']['state'][mediaType] !== undefined &&
										scope.businessAttributes['media']['state'][mediaType]['display_name'] !== undefined)
										return scope.businessAttributes['media']['state'][mediaType]['display_name'];
									return mediaType;
								};
								
								for (var stateObject in scope.states[i]){
									for (var expressionName in scope.expressionsList){
										if (stateObject == expressionName){
											scope.states[i][stateObject].media_type = scope.getMediaDisplayName(scope.states[i][stateObject].media_type);
											momentObject.additionalData.push(new AIConstructor(expressionName, scope.states[i][stateObject], scope.expressionsList[expressionName]));
										}
									}
								};
								//Use state_type icon (and color) if specified in configuration json
								//else use the icon (and color) for the media_type if specified in the json
								//else fall back to the default.
								if(angular.isDefined(TIMELINE_ICONS[scope.states[i].state_type])){
									momentObject.icon = TIMELINE_ICONS[scope.states[i].state_type];

									if(angular.isDefined(TIMELINE_COLORS[scope.states[i].state_type])){
										momentObject.badgeColor = TIMELINE_COLORS[scope.states[i].state_type];
									}

								} else if (scope.states[i].started.media_type){

									if (TIMELINE_ICONS[scope.states[i].started.media_type]){
										momentObject.icon = TIMELINE_ICONS[scope.states[i].started.media_type] ||
													defaultColorMap[scope.states[i].started.media_type];
									}

									if (TIMELINE_COLORS[scope.states[i].started.media_type]){
										momentObject.badgeColor = {'background-color' : TIMELINE_COLORS[scope.states[i].started.media_type] ||
													defaultColorMap[scope.states[i].started.media_type]};
									}

								}

								if (scope.states[i].est_duration && !scope.states[i].completed){
									momentObject.progress = Math.min(99, Math.round((((new Date().getTime() - new Date(localTimeStamp).getTime()) / 1000) / scope.states[i].est_duration) * 100));
								}
								
								if (scope.states[i].customstart)
									momentObject.customstart = scope.states[i].customstart;
								if (scope.states[i].customcomplete)
									momentObject.customcomplete = scope.states[i].customcomplete;
								
								if (momentObject.completed)
									momentObject.finishDate = stateEndDate; 
								
								momentCounter++;

								var dateString = localTimeStamp.split(' ')[0];
								var dateFound = false;
								for (var j = 0; j < scope.dates.length; j++){
									if (scope.dates[j].date === dateString){
										scope.dates[j].moments.push(momentObject);
										dateFound = true;
										break;
									}
								}
								
								if (!dateFound){
									scope.dates.push({'date': dateString, 'moments' : [momentObject], 'show' : true,
										'showMoments' : true, 'minIndex' : 0});
									dateCounter++;
								}
							}

							
							if (momentCounter + dateCounter <= scope.maxMoments){ //needs to be adjusted for when the size of the div is very large if (moment + date) && size < ## etc...
								scope.showDown = false;
							}
							else{
								scope.showDown = true;
							}
						});
					});
				}
				})
			}
			scope.reSize = true;
			scope.$watch(function(){
				//used to shift all moments in interactive timeline to one side during mobile view( when screen less than 830px)
				return window.innerWidth;
			}, function(value){
				if (value <= 830){
					scope.reSize = false;
				}
				else
					scope.reSize = true;
			});
			
		    scope.stateClicked = function (state){
		    	// use this function to send state info from the interaction timeline up to query controller. 
		    	
		    	if (!scope.stateObj)
		    		return; 
		    	
		    	if (scope.stateObj && state.body !== scope.stateObj.id || scope.stateObj.focusOn !== "state"){
		    		
		    		scope.stateObj.clicked = true; 
		    		scope.stateObj.focusOn = "state";
		    		
		    		scope.stateObj.activeTasksCount = state.activeTasks.length;
		    		scope.stateObj.completedTasksCount = state.completedTasks.length;
		    		
		    		scope.stateObj.resetStateDetails(); 
		    		
		    		scope.stateObj.started = state.startObj; 
		    		scope.stateObj.completed = state.completeObj;
		    		
		    		scope.stateObj.switchToJD = true; //when user clicks on state, variable will become true, infobox switches to journey details
		    		
		    		scope.stateObj.id = state.body; 
		    	    scope.stateObj.beginDate = moment(state.beginDate);
		    	    
		    		if(state.customstart)
		    			scope.stateObj.custom = state.customstart;
		    		
		    		if(state.customcomplete){
		    			if (scope.stateObj.custom !== undefined) {
			    			for (var attrname in state.customcomplete){
			    				scope.stateObj.custom[attrname] = state.customcomplete[attrname]
			    			}
		    			}
		    			else
		    				scope.stateObj.custom = state.customcomplete; 
		    		}
		    		
		    		if (state.completed)
		    			scope.stateObj.finishDate = moment(state.finishDate);
		    		else
		    			scope.stateObj.finishDate = "State not yet completed";
		    			    		
		    		
		    		scope.stateObj.title = state.title; 
		    		scope.stateObj.getData();
		    	}
		    }
		    
			scope.formatWithDuration = function (date){
				return date + " - " + moment(date).fromNow();						
			};
			
			scope.$watchCollection(function(){
				return [scope.serviceId];
			}, function() {
				updateTimeline();
			});
			//========================================================================================|
			
			scope.$watch(function(){
				return $("#interaction").height();
			},function(value){
				var adjustedValue = value - 158;

				$("#interaction-inner").css("height", (adjustedValue) + "px");
				if (adjustedValue <= 342){
					if (scope.maxMoments != 3){
						scope.maxMoments = 3;
						updateTimeline();
					}
				}
				else if (adjustedValue <= 442){
					if (scope.maxMoments != 4){
						scope.maxMoments = 4;
						updateTimeline();
					}
				}
				else if (adjustedValue <= 542){
					if (scope.maxMoments != 5){
						scope.maxMoments = 5;
						updateTimeline();
					}
				}
				else if (adjustedValue <= 642){
					if (scope.maxMoments != 6){
						scope.maxMoments = 6;
						updateTimeline();
					}
				}
				else if (adjustedValue <= 742){
					if (scope.maxMoments != 7){
						scope.maxMoments = 7;
						updateTimeline();
					}
				}
				else if (adjustedValue <= 842){
					if (scope.maxMoments != 8){
						scope.maxMoments = 8;
						updateTimeline();
					}
				}
				else{
					if (scope.maxMoments != 9){
						scope.maxMoments = 9;
						if(scope.Showdown){
							updateTimeline();
						}
					}
				}
			});
			//=========================================================================================|
			
			scope.scrollDown = function(){
				scope.toSkip = scope.maxMoments - 1;//(scope.showUp ? 7 : 8);
				scope.showUp = true;
				var lastDate = scope.dates.slice(-1);
				for (var i = 0; i < scope.dates.length; i++){
					if (scope.dates[i].show){
						if (scope.dates[i].showMoments){
							if (scope.dates[i].moments.length - scope.dates[i].minIndex + 1 < scope.toSkip){
								scope.dates[i].show = false;
								scope.toSkip -= (scope.dates[i].moments.length - scope.dates[i].minIndex + 1)
							} else if (scope.dates[i].moments.length - scope.dates[i].minIndex + 1=== scope.toSkip){
								scope.dates[i].show = false;
								break;
							} else {
								scope.dates[i].minIndex += scope.toSkip - 1;
								break;
							}
						} 
						else {
							scope.dates[i].show = false;
							if (scope.toSkip > 1){
								scope.toSkip -= 1;
							} else {
								break;
							}
						}
					}
				}
				scope.setShowDown(); // Hide down button if no more to scroll
				
			};
			
			scope.setShowDown = function(){
				// Hide down button if no more to scroll
				var counter = 0; // number of dates and moments shown
				for (var i = 0; i < scope.dates.length; i++){
					if (scope.dates[i].show){
						if (scope.dates[i].showMoments){
							counter += scope.dates[i].moments.length - scope.dates[i].minIndex;
						}
						counter += 1;
					}
				}
				scope.showDown = (counter > scope.maxMoments - 1);
			};
			
			scope.setShowUp = function(){
				// Hide up button if no more to scroll
				var earliestDate = Object.keys(scope.dates)[0];
				scope.showUp = (!scope.dates[earliestDate].show || (scope.dates[earliestDate].showMoments && scope.dates[earliestDate].minIndex != 0));
			}
			
			scope.scrollUp = function(){
				var toShow = scope.maxMoments - 1; //orig 8 
				var localDates = [];
				for (var i = scope.dates.length - 1; i > -1; i--){
					if (scope.dates[i].show && scope.dates[i].minIndex){
						if (scope.dates[i].minIndex + 1 > toShow){
							scope.dates[i].minIndex -= (toShow - 1);
							scope.setShowDown();
							return;
						} else if (scope.dates[i].minIndex + 1 === toShow){
							scope.dates[i].minIndex -= (toShow - 1);
							if (i === localDates.length - 1){
								scope.showUp = false;
							}
							scope.setShowDown();
							return;
						} else {
							toShow -= (scope.dates[i].minIndex + 1)
							scope.dates[i].minIndex = 0;
						}
					} else if (!(scope.dates[i].show)){
						if (!(scope.dates[i].showMoments)){
							scope.dates[i].show = true;
							if (toShow === 1){
								if (i === localDates.length - 1){
									scope.showUp = false;
								}
								scope.setShowDown();
								return;
							} else {
								toShow -= 1;
							}
						} else if (scope.dates[i].moments.length + 1 < toShow){
							scope.dates[i].show = true;
							toShow -= (scope.dates[i].moments.length + 1)
						} else if (scope.dates[i].moments.length + 1 === toShow){
							scope.dates[i].show = true;
							if (i === localDates.length - 1){
								scope.showUp = false;
							}
							scope.setShowDown();
							return;
						} else {
							scope.dates[i].show = false;
							//scope.dates[localDates[i]].minIndex = scope.dates[localDates[i]].moments.length + 1 - toShow;
							scope.setShowDown();
							return;
						}
					}
				}
				scope.showUp = false;
				scope.setShowDown();
			}
			
		}
	}
});
