'use strict';

/**
 * @ngdoc controller
 * @name RequestsController
 * @description
 *  Requests 화면
 */
app.controller('RequestsController', function($scope, $state, $location, $timeout, $modal, toastr, ngTableParams, Requests, Systems) {
  $scope.requests = {};

  $scope.searchOptions = [
    {
      name: 'File Name',
      value: 'title'
    },
    {
      name: 'Job ID',
      value: 'job_id'
    },
    {
      name: 'Installation Date',
      value: 'date'
    }
  ];
  $scope.filterType = 'title';

  $scope.search = function() {
    $scope.tableParams.filter({
      name: $scope.filterType,
      min: $scope.filterValue
    });
  };

  function parseSelection(str) {
    //str will be, for example, +status or -status
    return {
      name: str.substr(1),
      reverse: str.charAt(0) === '-' ? true:false
    };
  }

  // 목록 테이블 생성
  //ngTableParams: parameters, settings
  $scope.tableParams = new ngTableParams(
    {
      page: 1,            // show first page
      count: 10          // count per page
    },
    {
      total: 0,           // length of data
      getData: function($defer, params) {
        console.log(params.filter());
        var page = params.page();
        var total = params.total();
        var previousData = params.data;

        var options = { count: params.count() };
        var orderBy = params.orderBy();
        var sortingColumn = !_.isEmpty(orderBy) && parseSelection(orderBy[0]);
        var filter = params.filter();

        if (sortingColumn) {
          angular.extend(options, { orderBy: sortingColumn });
        }
        if (!_.isEmpty(filter)) {
          angular.extend(options, { filter: {
            name: filter.name,
            min: filter.min
          } });
        }
        if (page > 1  ) {
          angular.extend(options, {from: (page-1) * params.count()});
        }

        Requests.get('myjob', options)
          .then(function(data) {
            //If previous total does not equal

            params.total(data.length);
            $timeout(function() {
              console.log(params.total());

              //if (params.total() !== count) params.page(1);

              //$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
              $defer.resolve(data);
            }, 500);
          })
          .catch(function(error) {
            toastr.error(error);
            $defer.resolve(previousData);
          });
      }
    });

  // 목록에서 ready 클릭해서 팝업 띄우기
  $scope.jobImport = function(jobId) {
    Systems.setCurrentJobId(jobId);

    var modal = $modal({
        scope: $scope,
        title: 'Job is ready for import',
        template: 'views/installer/modal-tpls/job-import.html',
        container: '.container',
        show: false
      });

    modal.$promise.then(modal.show);
  }

  // 검색, 정렬 초기화
  $scope.clearSorting = function() {
    $scope.filterType = 'title';
    $scope.filterValue = '';
    $scope.searchForm.$setPristine();

    $scope.tableParams.filter({});
    $scope.tableParams.sorting({});
  };
});

/**
 * @ngdoc controller
 * @name ImportController
 * @description
 *  Import 화면
 */
app.controller('ImportController', function($scope, availableModels, currentJobId) {
  $scope.availableModels = availableModels;
  $scope.jobId = currentJobId;

  $scope.system = {};
  $scope.userInfo = '';
  $scope.import = {};

  $scope.isTmp = function(mac) {
    return !!mac.match('TMP_');
  };

  $scope.isNotTmp = function(mac) {
    return !mac.match('TMP_');
  };
});

/**
 * @ngdoc controller
 * @name ImportOptionsController
 * @description
 *  Import - Enter your programming key 화면
 */
app.controller('ImportOptionsController', function($scope, $state, $modal, toastr, base64, User, Registration, Systems) {
  // 초기값 설정
  $scope.import.option = 'new-system';  // new-system/previous-import 중 선택
  $scope.import.user = 'existing';    // existing/create 중 선택
  $scope.import.modelType = 'HCM-C1';

  $scope.import.create = {};
  $scope.import.working = [];

  $scope.doNext = function() {
    if ($scope.import.option == 'new-system') {   // [1] 새 system import
      var key = $scope.import.key.first + $scope.import.key.second + $scope.import.key.third + $scope.import.key.fourth,
        key = key.toUpperCase(),
        type = $scope.import.modelType;
      console.log(key);

      if ($scope.import.user === 'existing') {   // [1-1] existing account 로 로그인 하면서 system 생성

        var jsonData = JSON.stringify({ key: key, modelType: type, username: $scope.import.username, password: $scope.import.password });
        console.log(jsonData);

        // 시스템 생성을 위한 로그인
        User.loginForCreate(jsonData).then(function(data) {
          if(data.result) {
            Registration.setSystemKey(key);
            Registration.setBStationMac(data.mac);
            Registration.setSystemType(type);

            Systems.setUserInfo(base64.encode($scope.import.username + ':' + $scope.import.password));

            $state.go('import.add-new-system');
          } else {
            toastr.error(data.error);
            $scope.import.password = '';
            $scope.importForm.$setPristine();
          }
        }).catch(toastr.error);
      } else if ($scope.import.user === 'create') {    // [1-2] 사용자 생성을 하면서 system 생성
        var jsonData = JSON.stringify({ key: key, modelType: type, userInfo: base64.encode($scope.import.create.username + ':' + $scope.import.create.password), email: $scope.import.create.email });
        console.log(jsonData);

        // 사용자 생성
        Systems.createUser(jsonData).then(function(data) {

          console.log('create user', data);

          if (data.result) {
            Registration.setSystemKey(key);
            Registration.setSystemType(type);

            Systems.setUserInfo(base64.encode($scope.import.create.username + ':' + $scope.import.create.password));

            $state.go('import.add-new-system');
          } else {
            toastr.error(data.error);
            $scope.import.create.password = '';
            $scope.import.create.confirmed_password = '';
            $scope.importForm.$setPristine();
          }
        }).catch(toastr.error);
      }
    } else if ($scope.import.option == 'previous-import') {   // [2] 기존 import 이어서 작업
      var data = JSON.stringify({jobId: $scope.jobId, userInfo: base64.encode($scope.import.previous.username + ':' + $scope.import.previous.password)});

      Systems.getListWorking(data).then(function(data) {
        console.log('list working', data);
        $scope.import.working = data.systems;

        if ($scope.import.working.length == 0) {
          var modal = $modal({
            scope: $scope,
            title: 'Assign this device?',
            template: 'views/installer/modal-tpls/list-working-empty.html',
            container: '.installer-container',
            show: false
          });

          modal.$promise.then(modal.show);
        } else if ($scope.import.working.length == 1) {
          $scope.goSelectBase($scope.import.working[0].id);
        } else {
          $scope.selectedWorkingSystem = null;

          var modal = $modal({
            scope: $scope,
            title: 'Assign this device?',
            template: 'views/installer/modal-tpls/list-working.html',
            container: '.installer-container',
            show: false
          });

          modal.$promise.then(modal.show);
        }

      }).catch(toastr.error);
    }

    $scope.selectWorkingSystem = function(systemId) {
      $scope.selectedWorkingSystem = systemId;
    };

    $scope.goSelectBase = function(systemId) {
      var jsonData = JSON.stringify( { userInfo: base64.encode($scope.import.previous.username + ':' + $scope.import.previous.password)  } );

      Systems.updateSystem(systemId, jsonData).then(function() {
        $state.go('import.select-base');
      })
        .catch(function(error) {
          toastr.error(error, 'Error');
        });
    };
  };
});

/**
 * @ngdoc controller
 * @name ImportOptionsController
 * @description
 *  Import - setup primary base 화면
 */
app.controller('ImportAddNewSystemController', function($scope, $state, $q, toastr, timeZones, Systems, Registration) {
  var d = $q.defer(),
    data = JSON.stringify({jobId: $scope.jobId});

  // sysetm 정보를 app.installer.js 에 있는 'import.add-new-system' state 에서 resolve 로 받고 싶었으나 원인을 확인하지 못한 오류가 발생하여 여기서 얻음
  Systems.getJobSystem(data).then(function(data) {
    $scope.system = data.data;
    $scope.system.selectedRoom = data.data.rooms[0];

    Systems.loadSystem(data.data);
  }).catch(toastr.error);

  $scope.baseStationMac = Registration.getBStationMac();
  $scope.timeZones = timeZones;
  $scope.system.timezone_dst = true;
  $scope.timeFormat = 'hh:mm:ss a';

  // DST: daylight saving time true/false 설정
  $scope.checkDST = function() {
    if ($scope.system.timeZone.s_time === '0.0.0 00:00:00') {
      $scope.system.timezone_dst = false;
    } else {
      $scope.system.timezone_dst = true;
    }
  };

  $scope.doNext = function() {

    var systemName = $scope.system.name,
      keyData = Registration.getSystemKey(),
      type = Registration.getSystemType();

    var jsonData = JSON.stringify( { userInfo: Systems.getUserInfo(),
      systemName: systemName,
      modelType: type,
      key: keyData,
      timezoneId:  $scope.system.timeZone.id,
      timezoneDst: $scope.system.timezone_dst ? 1:0,
      jobId: $scope.jobId,
      jobRoomId: $scope.system.selectedRoom.id  } );

    console.log(jsonData);

    // system 생성
    Systems.createOne(jsonData)
      .then(function(data) {
        $scope.system.id = data;

        return Systems.updateSystem(data, jsonData);
      })
      .then(function() {
        $state.go('import.select-base');
      })
      .catch(function(error) {
        toastr.error(error, 'Error');
      });
  };

});

/**
 * @ngdoc controller
 * @name ImportSelectBaseController
 * @description
 *  Import - Select a control base to assign 화면
 */
app.controller('ImportSelectBaseController', function($scope, $state, $stateParams, $q, $http, toastr, base64, currentSystem, Systems) {
  $scope.system = currentSystem;
  $scope.userInfo = Systems.getUserInfo();

  // id param 이 넘어온 경우는 review 화면에서 reassign 하려고 넘어온 경우이므로 mac 을 TMP_ 로 변경
  _.each($scope.system.rooms, function(room) {
    _.each(room.bstations, function(bstation) {
      if (bstation.id == $stateParams.id) {
        bstation.mac = 'TMP_';
      }
    });
  });

  $scope.setRoomBstation = function(roomId, roomName, bstationName, bstationType, bstationId) {
    $scope.import.selectedRoomId = roomId;
    $scope.import.selectedRoomName = roomName;
    $scope.import.selectedBstationName = bstationName;
    $scope.import.selectedBstationType = bstationType;
    $scope.import.selectedBstationId = bstationId;

    Systems.setSelectedBstation({
      roomId: roomId,
      roomName: roomName,
      bstationName: bstationName,
      bstationType: bstationType,
      bstationId: bstationId
    });

    console.log($scope.import.selectedRoomName, $scope.import.selectedBstationName);
  };

  $scope.doNext = function() {
    $state.go('import.assign-base');
  };

  $scope.doLater = function() {
    $state.go('import.select-remote');
  };

  // base station 들이 모두 assign 되었다면 select-remote 로 이동
  var assigned = true;
  _.each($scope.system.rooms, function(room) {
    _.each(room.bstations, function(bstation) {
      if ($scope.isTmp(bstation.mac)) {
        assigned = false;
      }
    });
  });

  if (assigned) {
    $scope.doLater();
  }
});

/**
 * @ngdoc controller
 * @name ImportAssignBaseController
 * @description
 *  Import - Assign discovered device 화면
 */
app.controller('ImportAssignBaseController', function($scope, $state, $q, $modal, toastr, base64, currentSystem, searchResults, Systems) {
  $scope.system = currentSystem;
  $scope.userInfo = Systems.getUserInfo();
  $scope.baseStations = searchResults.searchedDevices;
  $scope.searchKey = searchResults.searchKey;
  $scope.selectedBstation = Systems.getSelectedBstation();

  $scope.refresh = function() {
    Systems.searchHardware($scope.selectedBstation.bstationType, {userInfo: $scope.userInfo}).then(
      function(data) {
        if (data && data.searchedDevices) {
          $scope.baseStations = data.searchedDevices;
          $scope.searchKey = data.searchKey;
        } else {
          $scope.baseStations = [];
          $scope.searchKey = null;
        }
      },
      function (error) {
        if (error.match('NO DEVICE')) {
          $scope.baseStations = [];
          $scope.searchKey = null;
        } else {
          toastr.error(error);
        }
      }
    ).catch(toastr.error);
  };

  $scope.selectMac = function(mac) {
    $scope.selectedMac = mac;
  };

  $scope.openModal = function() {
    var modal = $modal({
      scope: $scope,
      title: 'Assign this device?',
      template: 'views/installer/modal-tpls/assign-base.html',
      container: '.installer-container',
      show: false
    });

    modal.$promise.then(modal.show);
  };

  $scope.assignBase = function() {
    if (!$scope.selectedMac) {
      return;
    }

    var jsonData = JSON.stringify({
      userInfo: $scope.userInfo,
      mac: $scope.selectedMac,
      type: $scope.selectedBstation.bstationType,
      roomId: $scope.selectedBstation.roomId,
      id: $scope.selectedBstation.bstationId,
      searchKey: $scope.searchKey
    });

    Systems.assignBaseStation($scope.system.id, jsonData).then(
      function(data) {
        if (data.result) {
          Systems.updateSystem($scope.system.id, JSON.stringify({userInfo: $scope.userInfo})).then(function(data) {
            $state.go('import.select-base');
          }).catch(function(error) {
            toastr.error(error);
          });
        } else {
          toastr.error(data.error);
        }
      },
      function (error) {
        toastr.error(error);
      }
    ).catch(toastr.error);
  };
});

/**
 * @ngdoc controller
 * @name ImportSelectRemoteController
 * @description
 *  Import - Select a remote control to assign 화면
 */
app.controller('ImportSelectRemoteController', function($scope, $state, $stateParams, $q, $http, toastr, base64, currentSystem, Systems) {
  $scope.system = currentSystem;
  $scope.userInfo = Systems.getUserInfo();

  // id param 이 넘어온 경우는 review 화면에서 reassign 하려고 넘어온 경우이므로 mac 을 TMP_ 로 변경
  _.each($scope.system.rooms, function(room) {
    _.each(room.remotes, function(remote) {
      if (remote.id == $stateParams.id) {
        remote.mac = 'TMP_';
      }
    });
  });

  $scope.setRoomRemote = function(roomId, roomName, remoteName, remoteType, remoteId) {
    $scope.import.selectedRoomId = roomId;
    $scope.import.selectedRoomName = roomName;
    $scope.import.selectedRemoteName = remoteName;
    $scope.import.selectedRemoteType = remoteType;
    $scope.import.selectedRemoteId = remoteId;

    Systems.setSelectedRemote({
      roomId: roomId,
      roomName: roomName,
      remoteName: remoteName,
      remoteType: remoteType,
      remoteId: remoteId
    });

    console.log($scope.import.selectedRoomName, $scope.import.selectedRemoteName);
  };

  $scope.doNext = function() {
    $state.go('import.assign-remote');
  };

  $scope.doLater = function() {
    $state.go('import.assign-ip-address');
  };

  // remote 가 없거나 remote 들이 모두 assign 되었다면 assign-ip-address 로 이동
  var assigned = true;
  _.each($scope.system.rooms, function(room) {
    _.each(room.remotes, function(remote) {
      if ($scope.isTmp(remote.mac)) {
        assigned = false;
      }
    });
  });

  if (assigned) {
    $scope.doLater();
  }
});

/**
 * @ngdoc controller
 * @name ImportAssignRemoteController
 * @description
 *  Import - Assign discovered device 화면
 */
app.controller('ImportAssignRemoteController', function($scope, $state, $q, $modal, toastr, base64, currentSystem, searchResults, Systems) {
  $scope.system = currentSystem;
  $scope.userInfo = Systems.getUserInfo();
  $scope.remotes = searchResults.searchedDevices;
  $scope.searchKey = searchResults.searchKey;
  $scope.selectedRemote = Systems.getSelectedRemote();

  $scope.refresh = function() {
    Systems.searchHardware($scope.selectedRemote.remoteType, {userInfo: $scope.userInfo}).then(
      function(data) {
        if (data && data.searchedDevices) {
          $scope.remotes = data.searchedDevices;
          $scope.searchKey = data.searchKey;
        } else {
          $scope.remotes = [];
          $scope.searchKey = null;
        }
      },
      function (error) {
        if (error.match('NO DEVICE')) {
          $scope.remotes = [];
          $scope.searchKey = null;
        } else {
          toastr.error(error);
        }
      }
    );
  };

  $scope.selectMac = function(mac) {
    $scope.selectedMac = mac;
  };

  $scope.openModal = function() {
    var modal = $modal({
      scope: $scope,
      title: 'Assign this device?',
      template: 'views/installer/modal-tpls/assign-remote.html',
      container: '.installer-container',
      show: false
    });

    modal.$promise.then(modal.show);
  };

  $scope.assignRemote = function() {
    if (!$scope.selectedMac) {
      return;
    }

    var jsonData = JSON.stringify({
      userInfo: $scope.userInfo,
      mac: $scope.selectedMac,
      type: $scope.selectedRemote.remoteType,
      roomId: $scope.selectedRemote.roomId,
      id: $scope.selectedRemote.remoteId,
      searchKey: $scope.searchKey
    });

    Systems.assignRemoteControl($scope.system.id, jsonData).then(
      function(data) {
        if (data.result) {
          Systems.updateSystem($scope.system.id, JSON.stringify({userInfo: $scope.userInfo})).then(function(data) {
            $state.go('import.select-remote');
          }).catch(function(error) {
            toastr.error(error);
          });
        } else {
          toastr.error(data.error);
        }
      },
      function (error) {
        toastr.error(error);
      }
    ).catch(toastr.error);
  };


});

/**
 * @ngdoc controller
 * @name ImportAssignIpAddressController
 * @description
 *  Import - Input IP addresses for network devices 화면
 */
app.controller('ImportAssignIpAddressController', function($scope, $state, $modal, toastr, base64, currentSystem, Systems) {
  $scope.system = currentSystem;
  $scope.userInfo = Systems.getUserInfo();

  var networkDevicesLen = 0;

  // system 의 device 들 중 network controlled 만 표시함
  _.each($scope.system.rooms, function(room) {
    var devices = [];

    _.each(room.devices, function(device) {
      if (device.target_type == 2) {
        devices.push(device);
        networkDevicesLen++;
      }
    });

    room.devices = devices;
  });

  $scope.doNext = function() {
    var modal = $modal({
      scope: $scope,
      title: 'Assign these devices?',
      template: 'views/installer/modal-tpls/assign-devices.html',
      container: '.installer-container',
      show: false
    });

    modal.$promise.then(modal.show);
  };

  $scope.assignDevices = function() {
    var deviceData = [];

    _.each($scope.system.rooms, function(room) {
      _.each(room.devices, function(device) {
        deviceData.push({
          roomId: room.id,
          deviceId: device.id,
          target: {
            type: device.target_type,
            addr: device.target_addr,
            port: device.target_port
          }
        });
      });
    });

    var jsonData = JSON.stringify({
      userInfo: $scope.userInfo,
      data: deviceData
    });

    Systems.assignDevices($scope.system.id, jsonData).then(
      function(data) {
        if (data.result) {
          Systems.updateSystem($scope.system.id, JSON.stringify({userInfo: $scope.userInfo})).then(function(data) {
            $state.go('import.review');
          }).catch(function(error) {
            toastr.error(error);
          });
        } else {
          toastr.error(data.error);
        }
      },
      function (error) {
        toastr.error(error);
      }
    ).catch(toastr.error);
  };

  $scope.doLater = function() {
    $state.go('import.review');
  };

  // network controlled device 가 없으면 review 로 이동
  if (networkDevicesLen == 0) {
    $scope.doLater();
  }
});

/**
 * @ngdoc controller
 * @name ImportReviewController
 * @description
 *  Import - Review your work 화면
 */
app.controller('ImportReviewController', function($scope, $state, $modal, toastr, base64, currentSystem, Systems) {
  $scope.system = currentSystem;
  $scope.userInfo = Systems.getUserInfo();

  $scope.completed = true;

  // system 의 device 들 중 network controlled 만 표시함
  _.each($scope.system.rooms, function(room) {
    var devices = [];

    _.each(room.devices, function(device) {
      if (device.target_type == 2) {
        devices.push(device);
      }
    });

    room.devices = devices;
  });

  // base station 과 remote 들이 assign 되었는지 확인
  _.each($scope.system.rooms, function(room) {
    _.each(room.bstations, function(bstation) {
      if ($scope.isTmp(bstation.mac)) {
        $scope.completed = false;
      }
    });
    _.each(room.remotes, function(remote) {
      if ($scope.isTmp(remote.mac)) {
        $scope.completed = false;
      }
    });
  });

  $scope.assign = function(isTmp, type, id) {
    if (isTmp) {
      if (type == 'bstation') {
        $state.go('import.select-base');
      } else if (type == 'remote') {
        $state.go('import.select-remote');
      } else if (type == 'device') {
        $state.go('import.assign-ip-address');
      }
    } else {
      $scope.selectedType = type;
      $scope.selectedId = id;

      var modal = $modal({
        scope: $scope,
        title: 'Erase and reassign',
        template: 'views/installer/modal-tpls/erase-reassign.html',
        container: '.installer-container',
        show: false
      });

      modal.$promise.then(modal.show);
    }
  };

  $scope.reassign = function() {
    console.log($scope.selectedType);
    console.log($scope.selectedId);

    if ($scope.selectedType == 'bstation') {
      $state.go('import.select-base', {id: $scope.selectedId});
    } else if ($scope.selectedType == 'remote') {
      $state.go('import.select-remote', {id: $scope.selectedId});
    } else if ($scope.selectedType == 'device') {
      $state.go('import.assign-ip-address');
    }
  };

  $scope.finish = function() {
    if (!$scope.completed) {
      var modal = $modal({
        scope: $scope,
        title: 'Incomplete data!',
        template: 'views/installer/modal-tpls/incomplete-data.html',
        container: '.installer-container',
        show: false
      });

      modal.$promise.then(modal.show);
    } else {
      var jsonData = JSON.stringify({userInfo: $scope.userInfo});

      Systems.setDone($scope.system.id, jsonData).then(
        function(data) {
          if (data.result) {
            var modal = $modal({
              scope: $scope,
              title: 'Incomplete data!',
              template: 'views/installer/modal-tpls/import-complete.html',
              container: '.installer-container',
              show: false
            });

            modal.$promise.then(modal.show);
          } else {
            toastr.error(data.error);
          }
        },
        function (error) {
          toastr.error(error);
        }
      ).catch(toastr.error);
    }
  };

  $scope.goHome = function() {
    $state.go('home');
  };
});
