var angular = require('angular'),
  _ = require('jsUtil');

require('../modules');

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

module.factory('RemoteDataService', function($http) {
  function RemoteDataService(name, idPropertyName) {
    this.name = name;
    if (this.name.indexOf('/') !== 0) {
      this.name = '/' + this.name;
    }
    this.idPropertyName = idPropertyName;
    if (!this.idPropertyName) {
      throw new Error('创建RemoteDataService实例时必须指定idPropertyName');
    }
  }

  RemoteDataService.prototype = {
    /**
     * 获取编号为id的数据。
     *
     * @param  {String} id 数据编号
     * @return {Promise}   未来对象，包含响应内容
     */
    get: function(id) {
      return $http.get(this.name + '/' + id, {
        timeout: 15000
      }).then(function(response) {
        return response.data;
      });
    },

    /**
     * 获取查找单个数据的url
     */
    getQueryDataUrl: function(id) {
      return this.name + '/' + id;
    },

    /**
     * 创建数据，并保存到远程服务中。
     *
     * @param  {Object} data 需要保存的数据
     * @return {Promise}  未来对象，包含响应内容
     */
    create: function(data) {
      var idPropertyName = this.idPropertyName;
      return $http.post(this.name, data, {
        timeout: 15000
      }).then(function(response) {
        var result = response.data;
        data[idPropertyName] = result[idPropertyName];
        return result;
      });
    },

    /**
     * 更新数据，并保存到远程服务中。
     *
     * @param  {Object} data 需要保存的数据
     * @return {Promise}  未来对象，包含响应内容
     */
    update: function(data) {
      return $http.put(this.name + '/' + data[this.idPropertyName], data, {
        timeout: 15000
      })
      .then(function(response) {
        return response.data;
      });
    },

    /**
     * 删除数据，并且从远程服务中删除此数据。
     *
     * @param  {String} id 需要删除的数据编号
     * @return {Promise}   未来对象
     */
    'delete': function(id) {
      return $http['delete'](this.name + '/' + id);
    },

    /**
     * 获取需要审批的数据列表。
     *
     * @param  {String} userId 审批人，一般为当前登录人。
     * @param  {Number} pageNo 获取数据列表的页码。
     * @return  {Promise}  包含需审批的数据列表的未来对象。
     */
    getTodos: function(userId, pageNo) {
      var params = {};
      if (!_.isUndefined(pageNo)) {
        params['page.pn'] = pageNo;
      }
      return $http.get(this.name + '/' + 'todos/' + userId, {
        params: params,
        timeout: 15000
      }).then(function(response) {
        return response.data;
      });
    },

    /**
     * 获取草稿状态下的数据列表。
     *
     * @param  {String} userId 审批人，一般为当前登录人。
     * @param  {Number} pageNo 需要加载列表数据的页码。
     * @return {Promise}       包含草稿数据的未来对象。
     */
    getDrafts: function(userId, pageNo) {
      var params = {};
      if (!_.isUndefined(pageNo)) {
        params['page.pn'] = pageNo;
      }
      return $http.get(this.name + '/' + 'drafts/' + userId, {
        params: params,
        timeout: 15000
      }).then(function(response) {
        return response.data;
      });
    },

    /**
     * 获取与userId用户相关的数据列表。
     *
     * @param  {String} userId 审批人，一般为当前登录人。
     * @param  {Number} pageNo 需要加载列表数据的页码。
     * @return {Promise}       包含相关数据的未来对象。
     */
    getRelatedList: function(userId, pageNo, searchParams) {
      var params = {};
      if (!_.isUndefined(pageNo)) {
        params['page.pn'] = pageNo;
      }
      if(!_.isUndefined(searchParams)) {
        params['title'] = searchParams.title;
        params['subflag'] = searchParams.subflag;
      }
      return $http.get(this.name + '/' + 'related/' + userId, {
        params: params,
        timeout: 15000
      }).then(function(response) {
        return response.data;
      });
    },

    /**
     * 保存数据。若没有指定id，则是创建数据；否则更新该数据。
     *
     * @param  {Object} data 待保存的数据。
     * @return {Promise}     返回包含响应数据的未来对象。
     */
    save: function(data) {
      if (!data[this.idPropertyName]) {
        return this.create(data);
      } else {
        return this.update(data);
      }
    }
  };

  /**
   * 删除数据
   *
   * 同`delete()`方法。
   *
   * @param {String} id 待删除数据的id
   * @return {Promise} 返回未来对象。
   */
  RemoteDataService.prototype.remove = RemoteDataService.prototype['delete'];

  return RemoteDataService;
});
