var angular = require('angular');
require('../modules');
require('jsUtil');
require('../services/TaskRepository');
require('../services/TaskRemoteService');
require('../services/delaySaveDiscussions');
require('../services/TaskDiscussService');
require('../services/CurrentTaskService');
'use strict';

var module = angular.module('task');

module.controller('TaskDiscussCtrl', function($scope, $rootScope, $timeout, $state, $ionicActionSheet,
	CommonService, TaskRemoteService,
	$stateParams, TaskDiscussService, LinkerService, fileService,
	$ionicScrollDelegate, CurrentTaskService, TaskRepository,
	delaySaveDiscussions, DiscussService, AudioPlayerService, $toast) {
	$scope.loading = false;
	$scope.showDiscussions = false;
	$scope.delegate = $ionicScrollDelegate.$getByHandle('mainScroll');

	$scope.init = function() {
		CurrentTaskService.getCurrentTask().then(function(task) {
			$scope.task = task;
			$scope.loadDiscussions();
		});
		if (localStorage.getItem('userId')) {
			$scope.loginUserId = localStorage.getItem('userId');
		} else {
			$scope.loginUserId = LinkerService.currentUserId;
		}
	};

	function scrollBottom() {
		$timeout(function() {
			$scope.delegate.scrollBottom();
		});
	}

	window.addEventListener('native.keyboardshow', scrollBottom);
	window.addEventListener('native.keyboardhide', scrollBottom);

	$timeout(function() {
		$scope.showDiscussions = true;
		$scope.delegate.scrollBottom();
	}, 200);
	/**
	 * 新的消息通过消息推送暴露的事件已经添加到缓存的任务中，而当前查看的任务又是从缓存中获
	 * 取的，因此无需将获取到的discussions赋给task。
	 * 另一方面，请求消息对话列表时，后端将该任务的消息未读数目置为0。因此在请求评论列表成功
	 * 后，要将缓存中的该任务的未读消息数目，即noticeNum置为0。
	 */
	$scope.loadDiscussions = function() {
		TaskDiscussService.loadDiscussions($scope.task.id).then(function(discussions) {
			TaskRepository.changeDiscussions(discussions).then(function() {
				$rootScope.$broadcast('discussions.loaded', $scope.task.id);
				scrollBottom();
			});
		});
	};

	/**
	 * 查看任务详情。
	 */
	$scope.toTaskDetail = function() {
		$state.current.params = $state.params;
		CommonService.setCookie('mission.taskDetail.parent', $state.current);
		$state.get('mission.taskDetail').parent = $state.current;
		$state.go('mission.taskDetail', {
			taskId: $scope.task.id
		});
	};
	/**
	 * 解析日期格式。
	 * @param  {String} dateStr 日期字符串
	 */
	$scope.parseDateStr = function(dateStr) {
		return CommonService.smartInfoDateParser(dateStr);
	};

	$scope.goBack = function() {
		$state.go('mission.task');
	};

	$scope.shortenStr = function(str) {
		return !str ? '无' : str.length < 20 ? str : str.substring(0, 15) + '...';
	};

	$scope.parseImageSrc = function(src) {
		return DiscussService.parseImageSrc(src);
	};

	/**
	 * 图片上传失败。
	 */
	var uploadFileFail = function() {
		$toast.showLongCenter('上传失败，请检查网络连接。');
	};
	/**
	 * 上传语音成功。
	 */
	var uploadAudioSuccess = function(playAudioHtml) {
		$scope.loading = false;
		$scope.sendDiscuss(playAudioHtml);
	};
	/**
	 * 缓存图片成功。
	 * 缓存图片成功之后，暴露discussion.sending事件，该事件的监听会将消息放到页面上；
	 * 滚动到底部；
	 * 向服务器上传图片。
	 * 
	 * @param {fileEntry} fileEntry 
	 */
	var cacheImageSuccess = function(fileEntry) {
		DiscussService.cacheImageSuccess(fileEntry, function(imageHtml) {
			var discuss = $scope.generateDiscussion(imageHtml);
			discuss.id = discuss.id ? discuss.id : delaySaveDiscussions.generateId();
			$rootScope.$broadcast('discussion.sending', discuss, discuss.id);
			scrollBottom();
			uploadImage(fileEntry, discuss);
		});
	};
	/**
	 * 向服务器上传图片。
	 * 上传成功之后调用parseImageAndSend方法；
	 * 上传失败后暴露discussion.sendfail方法，该事件的监听处理会将消息状态改为发送失败。
	 * 
	 * @param  {FileEntry} fileEntry 
	 * @param  {Object} discuss   讨论消息
	 */
	var uploadImage = function(fileEntry, discuss) {
		DiscussService.uploadImage(fileEntry, discuss).then(function(response) {
			parseImageAndSend(response, discuss);
		}, function() {
			$rootScope.$broadcast('discussion.sendfail', discuss, discuss.id);
		});
	};
	/**
	 * 解析图片地址并完成消息的发送。
	 * 
	 * @param  {String} _response 响应结果，json字符串
	 * @param  {String} discuss   讨论的消息
	 */
	var parseImageAndSend = function(_response, discuss) {
		//解析服务器图片
		var file = JSON.parse(_response.response)[0],
			imageHtml = '<img class="image-view" image-id="' + file.id + '" size="150x150">',
			localDiscuss = discuss,
			cloneDiscuss = jsUtil.clone(discuss),
			cacheId = discuss.id;
		cloneDiscuss.content = imageHtml;
		delete cloneDiscuss.id;
		delete cloneDiscuss.status;
		TaskDiscussService.addDiscuss(cloneDiscuss).then(function(discussion) {
			$rootScope.$broadcast('discussion.sended', discussion, cacheId, localDiscuss);
		}, function() {
			$rootScope.$broadcast('discussion.sendfail', discuss, cacheId);
		});
	};
	/**
	 * 缓存图片失败
	 */
	function cacheImageFail(error) {
		console.log('图片发送失败，错误信息为:' + error);
		$toast.showShortCenter('请重选图片');
	}
	/**
	 * 获取图片成功，上传。
	 * @param  {String} fileURL 图片文件的url
	 */
	$scope.onGetPictureSuccess = function(fileURL) {
		DiscussService.onGetPictureSuccess(fileURL).then(cacheImageSuccess, cacheImageFail);
	};
	/**
	 * 录音成功，上传。
	 * @param  {String} audioURL 录音的url
	 */
	$scope.onCaptureAudioSuccess = function(media) {
		$scope.loading = true;
		DiscussService.uploadAudio(media).then(uploadAudioSuccess, uploadFileFail);
	};
	/**
	 * 录音失败。
	 */
	$scope.onCaptureAudioFail = function() {
		$toast.showShortCenter('语音录取失败。');
	};
	/**
	 * 发送文本内容。
	 * @param  {String} text
	 */
	$scope.onSendText = function(text) {
		text = CommonService.escapeHtml(text);
		$scope.sendDiscuss(text, true);
	};

	/**
	 * 发送讨论。
	 * @param  {String} content
	 */
	$scope.sendDiscuss = function(content, focusInput) {
		var discuss = jsUtil.isObject(content) ? content : $scope.generateDiscussion(content);
		var cacheId = discuss.id ? discuss.id : delaySaveDiscussions.generateId();
		$rootScope.$broadcast('discussion.sending', discuss, cacheId);
		if (discuss.content && discuss.content.indexOf('class="image-view"') !== -1) {
			var fileURL = discuss.content.match(/origin-src="(.+)"\ssrc/)[1];

			fileService.resolveURLtoFileEntry(fileURL).then(function(fileEntry) {
				uploadImage(fileEntry, discuss);
			}, function() {
				console.log('文件对象生成失败');
			});
		} else {
			reSendMessage(discuss, focusInput);
		}
	};

	/**
	 * 重发消息
	 * @param  {Object} discuss    群组讨论消息
	 * @param  {Boolean} focusInput 是否获取焦点
	 */
	var reSendMessage = function(discuss, focusInput) {
		var cacheId = discuss.id ? discuss.id : delaySaveDiscussions.generateId();
		var cloneDiscuss = jsUtil.clone(discuss);
		delete cloneDiscuss.id;
		delete cloneDiscuss.status;
		TaskDiscussService.addDiscuss(cloneDiscuss).then(function(discussion) {
			$rootScope.$broadcast('discussion.sended', discussion, cacheId);
		}, function() {
			$rootScope.$broadcast('discussion.sendfail', discuss, cacheId);
		});
		$timeout(function() {
			if (focusInput) {
				document.querySelector('.footerinput input').focus();
			}
			$scope.delegate.scrollBottom();
		});
	};
	/**
	 * 根据文字、图片、语音
	 * @param  {String} content 内容
	 */
	$scope.generateDiscussion = function(content) {
		var discuss = {};
		discuss.content = content;
		discuss.receivePerson = $scope.task.sendPerson;
		discuss.sendPerson = $scope.loginUserId;
		discuss.recordId = $scope.task.id;
		discuss.sendDate = jsUtil.formatDate(new Date(), 'Y-m-dTH:i:s.uZ');
		return discuss;
	};

	$scope.footerInputOptions = {
		onGetPictureSuccess: $scope.onGetPictureSuccess,
		onCaptureAudioSuccess: $scope.onCaptureAudioSuccess,
		onCaptureAudioFail: $scope.onCaptureAudioFail,
		onSendText: $scope.onSendText,
		placeHolder: ' '
	};

	$scope.parseType = function(typeId) {
		return TaskRemoteService.getTypeById(typeId);
	};
	/**
	 * 重新发送未成功发送的消息。
	 */
	$scope.reSend = function(discussion) {
		DiscussService.reSend(function() {
			$scope.sendDiscuss(discussion);
		});
	};
	/**
	 * 正在发送中的任务取消发送
	 */
	$scope.cancelSend = function(discussion) {
		$ionicActionSheet.show({
			buttons: [{
				text: '取消发送'
			}],
			cancelText: '取消',
			cancel: function() {
				return true;
			},
			buttonClicked: function() {
				discussion.status = '4';
				return true;
			}
		});
	};

	/**
	 * 监听语音播放完成事件，播放下一个语音。
	 * @param  {Event} event   事件对象
	 * @param  {String} audioId 语音id
	 */
	$scope.$on('audio.release', function(event, audioId) {
		var node = document.querySelector('[audio-player="' + audioId + '"]'),
			parent = node.parentNode.parentNode;
		AudioPlayerService.playNext(parent, function(parent) {
			return parent.nextElementSibling.querySelector('[audio-player].unplay');
		});
	});

	$scope.$on('$destroy', function() {
		window.removeEventListener('native.keyboardshow');
		window.removeEventListener('native.keyboardhide');
	});

	$scope.init();
});
