'use strict';
/**
 * @ngdoc service
 * @name Systems
 * @description
 *  system 관련 기능
 */
app.service('Systems', function ($http, $q, $window) {

  this.system = null ;
  this.dataMacro = null;
  this.isChanged = false;
  this.currentRoom = { 'id': null };
  this.roomDevices = null;
  this.mainDevice = null;
  this.dataSearchDevices = null;
  this.currentJobId = null;
  this.currentJob = null;

  /**
   * job id 로 부터 job 생성
   * @memberof Systems
   * @param {String} data job ID json string
   * @returns {Promise} Future object
   */
  this.import = function (data) {

    var d = $q.defer();

    // job 생성 API 호출
    $http.post('/urcassistant/api/system/import', data).success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * job id 로 부터 system id 얻기
   * @memberof Systems
   * @param {String} data job ID json string
   * @returns {Promise} Future object
   */
  this.getSystems = function (data) {
    var d = $q.defer();

    // job 생성 API 호출
    $http.post('/urcassistant/api/system/get_systems', data).success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * base station 의 type 들을 얻기
   * @memberof Systems
   * @returns {Promise} Future object
   */
  this.getModelTypes = function() {
    // base station 의 type 들을 얻는 API 호출
    return $http.post('/urcassistant/api/system/types').then(function(response) {
      return response;
    });
  };

  /**
   * remote 의 type 들을 얻기
   * @memberof Systems
   * @returns {Promise} Future object
   */
  this.getRemoteTypes = function() {
    // remote 의 type 들을 얻는 API 호출
    return $http.post('/urcassistant/api/remote/types').then(function(response) {
      return response;
    });
  };

  /**
   * system 생성
   * @memberof Systems
   * @param {String} data system 생성에 필요한 정보들 json string
   * @returns {Promise} Future object
   */
  this.createOne = function (data) {

    var d = $q.defer();

    // system 생성 API 호출
    $http.post('/urcassistant/api/system/create', data).success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response.jobId);   // 만들어진 system 의 job ID
      } else {
        d.reject(response.error);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * job 의 상태 설정 (0:init, 1:processing, 2:Ready)
   * @memberof Systems
   * @param {String} data jobId, status json string
   * @returns {Promise} Future object
   */
  this.setStatus = function (data) {

    var d = $q.defer();

    // system 생성 API 호출
    $http.post('/urcassistant/api/system/set_status', data).success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * job 목록 얻기
   * @memberof Systems
   * @returns {Promise} Future object
   */
  this.jobList = function (options) {

    var d = $q.defer(),
      jsonData;

    if (options) {
      jsonData = JSON.stringify(options);
    }

    // job 목록 얻기 API 호출
    $http.post('/urcassistant/api/system/list', jsonData).success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response.data);
      } else {
        d.reject(response.error);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * system 정보 얻어와서 저장
   * @memberof Systems
   * @param {Number} id system ID
   * @returns {Promise} Future object
   */
  this.updateSystem = function (id, data) {

    var self = this,
           d = $q.defer();

    if (!data) {
      data = JSON.stringify({jobId: self.getCurrentJobId()});
    }

    // system 얻기 API 호출
    $http.post('/urcassistant/api/system/get/' + id, data).success(function(response) {
      console.log(response);
      if(response.result) {
        // 현재 system 의 base station 에 MAC 이 있는지 검사하고 없으면 TMP_ 로 시작하는 임의의 값으로 부여
        _.each(response.data.rooms, function(room) {
          _.each(room.bstations, function(bstation) {
            if (!bstation.mac) {
              bstation.mac = 'TMP_' + bstation.name.split(' ')[1];
            }
          });
        });

        self.loadSystem(response.data);   // 얻어온 system 을 저장
        self.setCurrentJobId(JSON.parse(data).jobId);

        var user = JSON.parse($window.localStorage.getItem('hcm_assistant'));    // localStorage 에서 사용자 정보 얻기
        user.system_id = response.data.id;
        user.job_id = self.getCurrentJobId();

        $window.localStorage.setItem('hcm_assistant', JSON.stringify(user));   // 사용자 정보에 system ID, job ID 를 더해서 localStorage 에 저장
        d.resolve(response.data);
      } else {
        d.reject(response.data);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * system 삭제
   * @memberof Systems
   * @param {Number} id system ID
   * @returns {Promise} Future object
   */
  this.deleteSystem = function (id) {

    var self = this,
           d = $q.defer();

    // system 삭제 API 호출
    $http.post('/urcassistant/api/system/delete/' + id).success(function(response) {
      console.log(response);
      if(response.result) {
        _.remove(self.all, {'id': id});   // 저장되어 있는 system 목록에서 삭제할 system 삭제

        if (self.system.id === id) {    // 삭제한 system 이 현재 system 이었다면
          var user = JSON.parse($window.localStorage.getItem('hcm_assistant'));
          user.system_id = null;
          user.job_id = null;
          $window.localStorage.setItem('hcm_assistant', JSON.stringify(user));   // localStorage 에 저장되어 있는 사용자 정보에서 system ID, job ID 삭제
          
          self.system = null;   // 현재 system null 처리
        }

        d.resolve(response.result);
      } else {
        d.reject(response.error);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * system 저장
   * @memberof Systems
   * @param {Object} system
   */
  this.loadSystem = function(system) {
    this.system = system;   // system 정보를 현재 system 으로 저장

    //$window.localStorage.setItem('system', system.id);
  };

  /**
   * system 정보 얻기
   * @memberof Systems
   * @returns {Object} 현재 system 정보 객체
   */
  this.getCurrentSystem = function() {
    return this.system;
  };

  /**
   * job request data 정보 얻어와서 저장
   * @memberof Systems
   * @param {String} data job id json string
   * @returns {Promise} Future object
   */
  this.getSubmitData = function (data) {
    var self = this,
      d = $q.defer();

    if (!data) {
      data = JSON.stringify({jobId: self.getCurrentJobId()});
    }

    // Job Request Data 얻기 API 호출
    $http.post('/urcassistant/api/system/get_submit_data', data).success(function(response) {
      if(response.result) {
        console.log(response);
        d.resolve(response.data);
      } else {
        d.reject(response.data);
      }
    }, function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * 현재 room ID 얻기
   * @memberof Systems
   * @returns {Number} 현재 room ID
   */
  this.getCurrentRoom = function() {
    console.log('getting curr room id: ' + this.currentRoom.id);
    return this.currentRoom.id;
  };

  /**
   * 현재 room ID 저장
   * @memberof Systems
   * @param {Number} id room ID
   */
  this.setCurrentRoom = function(id) {
    console.log('setting curr room id to ' + id);
    this.currentRoom.id = id;
  };

  /**
   * 현재 system 이 가지고 있는 room 들 중에서 선택한 room 정보 얻기
   * @memberof Systems
   * @param {Number} id room ID
   * @returns {Object|Boolean} room 정보 객체 또는 false
   */
  this.getRoom = function(id) {
    var self = this;
    var room = _.find(self.system.rooms, { 'id': id });
    if (room !== undefined) {
      return room;
    } else {
      return false;
    }
  };

  /**
   * 현재 room 이 가지고 있는 device 들 중에서 선택한 device 정보 얻기
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {Number} deviceId device ID
   * @returns {Object|Boolean} device 정보 객체 또는 false
   */
  this.getDevice = function(roomId, deviceId) {
    var self = this;
    var room = _.find(self.system.rooms, { 'id': roomId });
    var device = _.find(room.devices, { 'id': deviceId });
    if (device !== undefined) {
      return device;
    } else {
      return false;
    }
  };

  /**
   * room 정보 얻어와서 저장
   * @memberof Systems
   * @param {Number} id room ID
   * @returns {Promise} Future object
   */
  this.updateRoomDevices = function(id) {

    var self = this,
           d = $q.defer();

    // room 얻기 API 호출
    $http.post('/urcassistant/api/room/get/' + this.system.id + '/' + id).success(function(response) {
      if(response.result) {
        console.log(response.data);
        self.setRoomDevices(response.data);   // room 정보 저장
        d.resolve(response.data);
      }
      else {
        d.reject('Unable to retrieve the data for the room. Please try again. If the error continues please log out and then log in again.');
      }
    }).error( function(error) {
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * room 정보 저장
   * @memberof Systems
   * @param {Object} roomDevices
   */
  this.setRoomDevices = function(roomDevices) {
    this.roomDevices = roomDevices;
  };

  /**
   * 저장된 room 정보 얻기
   * @memberof Systems
   * @returns {Object|null}
   */
  this.getRoomDevices = function() {
    return this.roomDevices;
  };

  /**
   * 해당 deivce ID 와 연계된 button 의 데이터 얻어와서 저장
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {Number} deviceId device ID
   * @returns {Promise} Future object
   */
  this.updateCurrentMacroForDevice = function(roomId, deviceId) {

    var self = this;
    return self.updateMacro('get_button_macro_with_device', roomId, deviceId, -1);
  };

  /**
   * 해당 room 의 power macro 데이터 얻어와서 저장
   * @memberof Systems
   * @param {Number} roomId room ID
   * @returns {Promise} Future object
   */
  this.updateCurrentMacroForPower = function(roomId) {

    var self = this;
    return self.updateMacro('get_power_macro', roomId, -1, -1);
  };

  /**
   * button ID 에 해당하는 button 의 데이터 얻어와서 저장
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {Number} deviceId device ID
   * @param {Number} buttonId button ID
   * @returns {Promise} Future object
   */
  this.updateCurrentMacro = function(roomId, deviceId, buttonId) {

    var self = this;
    return self.updateMacro('get_button_macro', roomId, deviceId, buttonId);
  };

  /**
   * button 의 정보 얻어와서 저장
   * @memberof Systems
   * @param {String} type 얻어올 button 정보의 type
   * @param {Number} roomId room ID
   * @param {Number} deviceId device ID
   * @param {Number} buttonId button ID
   * @returns {Promise} Future object
   */
  this.updateMacro = function(type, roomId, deviceId, buttonId) {

    var self = this,
           d = $q.defer();
    deviceId = deviceId || null;

    var urlData;
    if(type === 'get_button_macro_with_device') {   // 해당 deivce ID 와 연계된 button 의 데이터 얻기
      if(deviceId < 0) {
        alert('The automated activity could not be saved.  Please check the steps in the command list and try again.');
        return;
      }
      urlData = '/urcassistant/api/btn/get_button_macro_with_device/' + roomId + '/' + deviceId;
    }
    else if(type === 'get_power_macro') {   // 해당 room 의 power macro 데이터 얻기
      urlData = '/urcassistant/api/btn/get_power_macro/' + roomId;
    }
    else if(type === 'get_button_macro') {  // button ID 에 해당하는 button 의 데이터 얻기
      if(buttonId < 0) {
        alert('The automated activity could not be saved.  Please check the steps in the command list and try again.');
        return;
      }
      urlData = '/urcassistant/api/btn/get_button_macro/' + roomId + '/' + deviceId + '/' + buttonId;
    }
    else {
      alert('The automated activity could not be saved.  Please check the steps in the command list and try again.');
      return;
    }

    // 선택된 type 에 따라 정해진 urlData 의 API 호출
    $http.post(urlData).success(function(response) {

      if(response.result) {
        console.log(response.data);
        self.setCurrentMacro(response.data);    // 얻어온 정보를 현재 macro 데이터로 저장
        d.resolve(response.data);
      }
      else {
        alert('Unable to retrieve activity information.  Please try again');
        d.reject('Unable to retrieve activity information.  Please try again');
      }

    }).error(function(error) {
      alert('Please try again');
      d.reject(error);
    });
    return d.promise;
  };

  /**
   * 현재 macro 데이터 저장
   * @memberof Systems
   * @param {Object} dataMacro
   */
  this.setCurrentMacro = function(dataMacro) {
    this.dataMacro = dataMacro;
  };

  /**
   * 현재 macro 데이터 얻기
   * @memberof Systems
   * @returns {Object|null} 현재 macro 데이터
   */
  this.getCurrentMacro = function() {
    return this.dataMacro;
  };

  /**
   * 검색된 device 목록 저장
   * @memberof Systems
   * @param {Array} devices device 목록 array
   */
  this.setSearchDevices = function(devices) {

    this.dataSearchDevices = devices;
  };

  /**
   * 저장되어 있는 검색된 device 목록 얻기
   * @memberof Systems
   * @returns {Array|null} device 목록 array
   */
  this.getSearchDevices = function() {

    return this.dataSearchDevices;
  };

  /**
   * main device 저장
   * @memberof Systems
   * @param {Object} device device 정보 객체
   */
  this.setMainDevice = function(device) {
    this.mainDevice = device;
  };

  /**
   * 저장된 main device 얻기
   * @memberof Systems
   * @returns {Object|null} device 정보 객체
   */
  this.getMainDevice = function() {
    return this.mainDevice;
  };

  /**
   * main device 얻어와서 저장
   * @memberof Systems
   * @param {Number} roomId room ID
   * @returns {Promise} Future object
   */
  this.updateMainDevice = function(roomId) {

    var self = this,
           d = $q.defer(),
         url = '/urcassistant/api/device/get_main/' + roomId;

    // main device 얻어오는 API 호출
    $http.post(url)
    .success(function(response) {
      if(response.result) {
        self.setMainDevice(response.data);  // main device 저장
        d.resolve(response.data);
      }
      else {
        alert(response.error);
        d.reject(response.error);
      }

    })
    .error( function(error) {
      alert('Please try again');
      d.reject(error);
    });

    return d.promise;
  };

  /**
   * main device 정보 서버에 저장
   * @memberof Systems
   * @param {Number} roomId room ID
   * @returns {Promise} Future object
   */
  this.storeMainDevice = function(roomId) {

    var self = this,
           d = $q.defer(),
         url = '/urcassistant/api/device/store_main/' + roomId,
     mainDev = { data : self.getMainDevice() },
    jsonData = JSON.stringify(mainDev);

    console.log(mainDev);

    // main device 정보 저장 API 호출
    $http.post(url,jsonData)
    .success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response);
      } else {
        d.reject(response.error);
      }

    })
    .error( function(error) {
      d.reject(error);
    });
    return d.promise;
  };

  /**
   * 현재 job ID 저장
   * @memberof Systems
   * @param {String} id job ID
   */
  this.setCurrentJobId = function(id) {
    this.currentJobId = id;
  };

  /**
   * 현재 job ID 얻기
   * @memberof Systems
   * @returns {String} job ID
   */
  this.getCurrentJobId = function() {
    return this.currentJobId;
  };

  /**
   * 현재 job 저장
   * @memberof Systems
   * @param {Object} job job data
   */
  this.setCurrentJob = function(job) {
    this.currentJob = job;
  };

  /**
   * 현재 job 얻기
   * @memberof Systems
   * @returns {Object} job data
   */
  this.getCurrentJob = function() {
    return this.currentJob;
  };

  /**
   * system 의 timezone 설정
   * @memberof Systems
   * @param {String} data timezone ID/daylight saving option(0: off, 1: on)/time_type(0: 12hour, 1:24hour) json string
   * @returns {Promise} Future object
   */
  this.setTimeZone = function(data) {

    var d = $q.defer(),
      url = '/urcassistant/api/system/set_timezone/' + this.system.id;
    
    // system 의 timezone 설정하는 API 호출
    $http.post(url,data)
    .success(function(response) {
      console.log(response);
      if(response.result) {
        d.resolve(response.result);
      } else {
        d.reject(response.error);
      }

    })
    .error( function(error) {
      d.reject(error);
    });
    return d.promise;
    
  };

  /**
   * button 생성
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {Number} mainDeviceId main device ID
   * @param {String} data button text/automatic message/edit type(0: activity, 1: macro)/activity data/popup(0: off, 1: on)/macro data json string
   * @returns {Promise} Future object
   */
  this.createCustomButtonMacro = function (roomId, mainDeviceId, data) {
    // button 생성 API 호출
    return $http.post('/urcassistant/api/btn/create/' + roomId + '/' + mainDeviceId, data).then(function(response) {
      return response;
    });
  };

  /**
   * 해당 room 의 power macro 데이터 저장
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {String} data automatic message/edit type(0: activity, 1: macro)/activity data/popup(0: off, 1: on)/macro data json string
   * @returns {Promise} Future object
   */
  this.storePowerMacro = function (roomId, data) {
    // 해당 room 의 power macro 데이터 저장하는 API 호출
    return $http.post('/urcassistant/api/btn/store_power_macro/' + roomId, data).then(function(response) {
      return response;
    });
  };

  /**
   * 해당 device ID 와 연계된 button 의 데이터 저장
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {Number} deviceId device ID
   * @param {String} data automatic message/edit type(0: activity, 1: macro)/activity data/popup(0: off, 1: on)/macro data json string
   * @returns {Promise} Future object
   */
  this.storeDeviceButtonMacro = function (roomId, deviceId, data) {
    // 해당 device ID 와 연계된 button 의 데이터 저장하는 API 호출
    return $http.post('/urcassistant/api/btn/store_button_macro_with_device/' + roomId + '/' + deviceId, data).then(function(response) {
      return response;
    });
  };

  /**
   * button ID 에 해당하는 button 의 데이터 저장
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {Number} mainDeviceId main device ID
   * @param {Number} btnId button ID
   * @param {String} data automatic message/edit type(0: activity, 1: macro)/activity data/popup(0: off, 1: on)/macro data json string
   * @returns {Promise} Future object
   */
  this.storeCustomButtonMacro = function (roomId, mainDeviceId, btnId, data) {
    // button ID 에 해당하는 button 의 데이터 저장하는 API 호출
    return $http.post('/urcassistant/api/btn/store_button_macro/' + roomId + '/' + mainDeviceId + '/' + btnId, data).then(function(response) {
      return response;
    });
  };

  /**
   * 해당 room 의 power macro 삭제
   * @memberof Systems
   * @param {Number} roomId room ID
   * @returns {Promise} Future object
   */
  this.deletePowerMacro = function(roomId) {
    // 해당 room 의 power macro 삭제하는 API 호출
    return $http.post('/urcassistant/api/btn/delete_power_macro/' + roomId).then(function(response) {
      return response;
    });
  };

  /**
   * 해당 device ID 와 연계된 button 의 macro 삭제
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {Number} deviceId device ID
   * @returns {Promise} Future object
   */
  this.deleteButtonMacroWithDevice = function(roomId, deviceId) {
    // 해당 device ID 와 연계된 button 의 macro 삭제하는 API 호출
    return $http.post('/urcassistant/api/btn/delete_button_macro_with_device/' + roomId + '/' + deviceId).then(function(response) {
      return response;
    });
  };

  /**
   * button ID 에 해당하는 button 삭제
   * @memberof Systems
   * @param {Number} roomId room ID
   * @param {Number} deviceId device ID
   * @param {Number} btnId button ID
   * @returns {Promise} Future object
   */
  this.deleteButtonMacro = function(roomId, deviceId, btnId) {
    // button ID 에 해당하는 button 삭제하는 API 호출
    return $http.post('/urcassistant/api/btn/delete_button_macro/' + roomId + '/' + deviceId + '/' + btnId).then(function(response) {
      return response;
    });
  };

});
