var angular = require('angular');
require('../modules');
require('jsUtil');
require('./taskMessages');
require('./TaskRepository');
'use strict';

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

var i = 0;

var __hasProp = {}.hasOwnProperty,
	__extends = function(child, parent) {
		for (var key in parent) {
			if (__hasProp.call(parent, key)) {
				child[key] = parent[key];
			}
		}

		function ctor() {
			this.constructor = child;
		}
		ctor.prototype = parent.prototype;
		child.prototype = new ctor();
		child.__super__ = parent.prototype;
		child.__super__.constructor = parent;
		return child;
	};

module.factory('DelaySaveCacheArray', function($q, localforage) {

	function DelaySaveCacheArray(itemKey) {
		this.itemKey = itemKey;
		this.items = [];
		this._idItems = [];
		this.loadFromCache();
		this.id = i++;
	}

	DelaySaveCacheArray.prototype = {
		/**
		 * 将待处理的对象插入到待处理队列。
		 *
		 * @param  {Object} item 待插入的对象
		 */
		insert: function(item) {
			item = this.transferItem(item);
			this.addToRelatedList(item);
			this.addToCache(item);

			var index = this.indexOf(item);
			if (index >= 0) {
				this.items.splice(index, 1);
			}
			this.items.unshift(item);
			return this.syncCache();
		},
		/**
		 * 包装待处理对象
		 * @param  {Object} item 待处理的对象
		 */
		transferItem: function(item) {
			return item;
		},
		/**
		 * 将待处理数据添加到关联的列表中。
		 * @param {Object} item 待处理数据
		 */
		addToRelatedList: function() {

		},
		/**
		 * 将待处理数据添加到缓存中
		 * @param {Object} item 待处理数据
		 */
		addToCache: function() {

		},
		/**
		 * 获取元素在数组中的位置。
		 *
		 * @param  {Id|Object} item 元素
		 * @return {Number} 返回元素所在的位置。
		 */
		indexOf: function(item) {
			var id = _.isObject(item) ? this.getItemId(item) : item,
				self = this,
				result = -1;
			_.each(this.items, function(_item, index) {
				if (id === self.getItemId(_item)) {
					result = index;
				}
			});

			return result;
		},
		/**
		 * 将待处理的对象的ids同步到缓存中
		 * @param  {Object} item 待处理的对象
		 * @return {Promise}
		 */
		syncCache: function() {
			var ids = _.map(this.items, this.getItemId, this);

			this._idItems = ids;

			return $q.when(localforage.setItem(this.itemKey, ids));
		},

		loadCacheItemsInToRelatedList: function() {

		},
		/**
		 * 将缓存中的对象同步到内存中
		 * @return {Promise}
		 */
		loadFromCache: function() {
			var self = this;
			this.cachePromise = localforage.getItem(this.itemKey)
				.then(function(value) {
					self._idItems = value || [];
					return self.getByIds(self._idItems)
						.then(function(items) {
							self.items = items;
							return items;
						});
				});
			return this.cachePromise;
		},
		/**
		 * （为方便测试，添加此方法。）
		 */
		setItemIds: function(ids) {
			return $q.all(localforage.setItem(this.itemKey, ids));
		},
		/**
		 * 获取数据的id。
		 *
		 * @param  {Object} item 数据
		 * @return {string} 返回数据对象
		 */
		getItemId: function(item) {
			return item.id;
		},
		/**
		 * 通过一组id获取数据。需要配置的。
		 *
		 * @return {Promise}
		 */
		getByIds: function() {

		},
		/**
		 * 生成id
		 * @return {String} 唯一的id
		 */
		generateId: function() {
			var id = new Date().getTime() + this.id;
			return id.toString();
		},
		/**
		 * 网络恢复连接后，将未发送的任务或者讨论重新发出。
		 */
		autoSend: function() {

		},
		/**
		 * 将数据从待处理队列中移除
		 * @param  {Object} item 数据
		 * @param {String} cacheId 缓存数据的id
		 * @param {boolean} draftInServer 是否是存在服务器上的草稿
		 * @return {Promise}
		 */
		remove: function(item, cacheId, draftInServer) {
			if(!cacheId) {
				cacheId = item.id;
			}
			var index = this.indexOf(item);
			if (index >= 0) {
				this.items.splice(index, 1);
			}
			this.removeFromCache(cacheId, draftInServer);
			this.removeFromRelatedList(item, cacheId, draftInServer);
			return this.syncCache();
		},
		/**
		 * 将数据从关联列表中移除
		 * @param  {Object} item 待移除的对象数据
		 */
		removeFromRelatedList: function() {

		},
		/**
		 * 将数据从缓存中移除
		 * @param  {Object} item 待移除的对象数据
		 */
		removeFromCache: function() {

		},
		/**
		 * 清空数据。
		 *
		 * @return {Promise}
		 */
		clear: function() {
			this.items = [];
			this._idItems = [];
			return $q.all(localforage.removeItem(this.itemKey));
		}
	};

	return DelaySaveCacheArray;
});

module.factory('DelaySaveDiscussionArray', function(DelaySaveCacheArray, $q, TaskRepository, $rootScope) {
	function DelaySaveDiscussionArray() {
		DelaySaveDiscussionArray.__super__.constructor.apply(this, arguments);
	}

	__extends(DelaySaveDiscussionArray, DelaySaveCacheArray);

	DelaySaveDiscussionArray.prototype.transferItem = function(item) {
		item.status = '3';
		return item;
	};

	DelaySaveDiscussionArray.prototype.addToRelatedList = function() {

	};

	DelaySaveDiscussionArray.prototype.getByIds = function(ids) {
		var promises = _.map(ids, function(id) {
			return TaskRepository.getDiscussionById(id);
		});

		return $q.all(promises);
	};

	DelaySaveDiscussionArray.prototype.addToCache = function(discussion) {
		TaskRepository.setDiscussion(discussion);
		return TaskRepository.addDiscussion(discussion);
	};

	DelaySaveDiscussionArray.prototype.removeFromCache = function(cacheId) {
		return TaskRepository.removeDiscussionFromCache(cacheId);
	};
	/**
	 * 将发送成功的消息替换缓存中正在发送的消息。
	 */
	DelaySaveDiscussionArray.prototype.removeFromRelatedList = function(discussion, cacheId) {
		return TaskRepository.changeDiscussion(discussion, cacheId);
	};

	DelaySaveDiscussionArray.prototype.change = function(discussion, cacheId) {
		discussion.status = '4';//发送失败的状态
		var index = this.indexOf(discussion);
		if (index >= 0) {
			this.items[index] = discussion;
		}
		TaskRepository.setDiscussion(discussion);
		return TaskRepository.changeDiscussion(discussion, cacheId);
	};

	DelaySaveDiscussionArray.prototype.loadCacheItemsInToRelatedList = function(taskId) {
		var clonedItems = jsUtil.clone(this.items).filter(function(item) {
			return item.recordId === taskId;
		});

		var reversedItems = clonedItems.reverse();
		jsUtil.each(reversedItems, function(item) {
			return TaskRepository.addDiscussion(item).then(function() {
				$rootScope.$broadcast('discussion.loadAfter', reversedItems[reversedItems.length - 1]);
			});
		});
	};

	return DelaySaveDiscussionArray;

});

module.factory('DelaySaveTaskArray', function(DelaySaveCacheArray, $q, TaskRepository, taskMessages) {
	function DelaySaveTaskArray() {
		DelaySaveTaskArray.__super__.constructor.apply(this, arguments);
	}

	__extends(DelaySaveTaskArray, DelaySaveCacheArray);

	DelaySaveTaskArray.prototype.transferItem = function(task) {
		task.status = '3';
		return task;
	};
	/**
	 * 将待处理任务添加到消息列表顶端。
	 * @param {Object} item 待处理任务
	 */
	DelaySaveTaskArray.prototype.addToRelatedList = function(task) {
		return taskMessages.insert(task);
	};

	DelaySaveTaskArray.prototype.getByIds = function(ids) {
		var promises = _.map(ids, function(id) {
			return TaskRepository.getTaskById(id);
		});

		return $q.all(promises);
	};

	DelaySaveTaskArray.prototype.addToCache = function(task) {
		return TaskRepository.addOrUpdateTasks(task);
	};

	DelaySaveTaskArray.prototype.removeFromRelatedList = function(task, cacheId, draftInServer) {
		if(!draftInServer) {
			return taskMessages.remove(task);
		}
	};

	DelaySaveTaskArray.prototype.removeFromCache = function(cacheId, draftInServer) {
		if(!draftInServer) {
			return TaskRepository.removeItem(cacheId);
		}
	};

	DelaySaveTaskArray.prototype.loadCacheItemsInToRelatedList = function() {
		var self = this;
		var clonedItems = jsUtil.clone(this.items);
		var reversedItems = clonedItems.reverse();
		jsUtil.each(reversedItems, function(item) {
			return self.addToRelatedList(item);
		});
	};

	return DelaySaveTaskArray;
});