angular
  .module("app")
  .controller(
    "ManageViewsCtrl",
    function (
      $scope,
      $rootScope,
      $timeout,
      $q,
      ManageViewsService,
      SQConstants,
      sqPlugin,
      ColumnSettingsService,
      L,
      AppService
    ) {
      console.log("ManageViewsCtrl controller initialized");

      var defaultDatabankViews = SQConstants.getConstants()
        .defaultDatabankViews;

      function init() {
        loadData();
        loadViews();
      }

      $scope.onViewNameChange = function () {
        $scope.changesSaved = false;
      };

      $scope.onRemoveColumn = function (index) {
        if ($scope.isDefaultViewSelected()) {
          $rootScope.showError(L.tsq("Cannot change the default view"));
          return;
        }
        $scope.selectedView.columns.splice(index, 1)

        $scope.changesSaved = false;
      };

      $scope.onMoveColumnBy = function (index, moveBy) {
        let newIndex = index + moveBy;
        if (newIndex < 0) {
          newIndex = 0;
        }
        if (newIndex > $scope.selectedView.columns.length - 1) {
          newIndex = $scope.selectedView.columns.length - 1;
        }

        $scope.selectedView.columns.splice(
          newIndex,
          0,
          $scope.selectedView.columns.splice(index, 1)[0]
        );

        $scope.changesSaved = false;
      };

      $scope.onColumnMoved = function (index) {
        $scope.selectedView.columns.splice(index, 1);

        $scope.changesSaved = false;
      };

      function loadData() {
        $scope.instance.getColumns(function (columns) {
          loadToArray(allColumns, columns);
          removeItem(allColumns, "class", "FiltersResult");

          itemsChooserDeferred.promise.then(function () {
            $scope.columnsChooser.init(allColumns);
          });
        });
      }

      function loadViews() {
        $scope.instance.getViews(function (views, selectedViewName) {
          loadToArray($scope.views, views);

          $scope.selectedView.name = selectedViewName;
          $scope.selectedView.originalName = $scope.selectedView.name;

          if (
            !$scope.selectedView.originalName ||
            !getItem($scope.views, "name", $scope.selectedView.originalName)
          ) {
            $scope.selectedView.originalName =
              $scope.type == "Databank" ? defaultDatabankViews.main : "Default";
          }

          $scope.onViewSelect(true);
        });
      }

      function getColumnText(column) {
        if ($scope.advanced) {
          var valueObj = ManageViewsService.createColumnObj(column);

          return ColumnSettingsService.printColumnTitle(valueObj);
        } else return column.columnName;
      }

      function copyView(target, source) {
        target.name = source.name;
        target.originalName = source.originalName;
        loadToArray(target.columns, source.columns);
      }

      $scope.onClone = function () {
        $scope.createNewView = true;
        $scope.changesSaved = false;
        $scope.selectedView.name = getCloneName();
      };

      function getCloneName() {
        for (var i = 0; i < 100; i++) {
          var name =
            i == 0
              ? $scope.selectedView.originalName + " - Cloned"
              : $scope.selectedView.originalName + " - Cloned" + (i + 1);

          var view = getItem($scope.views, "name", name);
          if (!view) {
            return name;
          }
        }

        return ($scope.selectedView.name += " - Cloned");
      }

      $scope.openColumnsChooser = function () {
        var defaultItemsPure = [];

        if ($scope.type == "Tradelist") {
          // types: Tradelist, wfresults, rt, Databank
          defaultItemsPure = [
            "Ticket",
            "Symbol",
            "Type",
            "OpenTime",
            "OpenPrice",
            "Size",
            "CloseTime",
            "ClosePrice",
            "ProfitLoss",
            "Balance",
            "SampleType",
            "CloseType",
            "MAE",
            "MFE",
            "TimeInTrade",
            "Comment",
          ];
        } else if ($scope.type == "wfresults") {
          defaultItemsPure = [
            "NumberOfTrades",
            "NumberOfTrades",
            "NetProfit",
            "NetProfit",
            "Drawdown",
            "Drawdown",
          ];
        } else if ($scope.type == "rt") {
          defaultItemsPure = [
            "NetProfit",
            "Drawdown",
            "ReturnDDRatio",
            "RExpectancy",
          ];
        }

        if (defaultItemsPure.length > 0) {
          defaultItems = [];
          for (var i = 0; i < defaultItemsPure.length; i++) {
            defaultItems.push({
              name: defaultItemsPure[i],
              weight: 10 - i / 3,
              class: defaultItemsPure[i],
            });
          }
        }

        if (SQConstants.getSettings()[$scope.recentlyUsedKey] != undefined) {
          try {
            $scope.recentItems = JSON.parse(
              "" + SQConstants.getSettings()[$scope.recentlyUsedKey]
            );
          } catch (exp) {
            $scope.recentItems = [];
          }
        }

        $scope.columnsChooser.loadRecentItems($scope.recentItems, defaultItems);
        $scope.columnsChooser.clearSelection();
        $scope.columnsChooser.show();
      };

      $scope.onDelete = function () {
        if ($scope.isDefaultViewSelected()) {
          $rootScope.showError(L.tsq("Cannot remove the default view"));
          return;
        }

        $rootScope.showConfirm(
          L.tsq("Deleting view"),
          L.tsq("Do you really want to delete selected view?"),
          function (confirmed) {
            if (confirmed) {
              $scope.instance.removeView($scope.selectedView.name, loadViews);
            }
          }
        );
      };

      $scope.onAdd = function () {
        $scope.selectedView.name = L.tsq("New view");
        $scope.selectedView.columns = [];
        reset($scope.selectedView.selectedColumn);

        $scope.createNewView = true;
        $scope.changesSaved = false;
      };

      function isNameValid(name) {
        var format = /^[a-zA-Z0-9_\s\-]*$/;

        return format.test(name);
      }

      $scope.onSave = function () {
        if ($scope.isDefaultViewSelected()) {
          $rootScope.showError(L.tsq("Cannot change default view"));
          return;
        }

        if ($scope.selectedView.columns.length == 0) {
          $rootScope.showError(
            L.tsq("The view has to contain at least one column.")
          );
          return;
        }

        if (!isNameValid($scope.selectedView.name)) {
          $rootScope.showError(
            L.tsq(
              "View name cannot contain any special characters except for spaces, hyphens (-), and underscores (_)."
            )
          );

          return;
        }

        var viewXML = ManageViewsService.getViewXML($scope.selectedView);
        if ($scope.createNewView) {
          $scope.instance.addView(
            $scope.selectedView.name,
            viewXML,
            function () {
              $scope.changesSaved = true;
              loadViews();
            }
          );
        } else {
          if ($scope.selectedView.name != $scope.selectedView.originalName) {
            if ($scope.instance.onViewRename) {
              $scope.instance.onViewRename(
                $scope.selectedView.originalName,
                $scope.selectedView.name
              );
            }

            $scope.selectedView.originalName = $scope.selectedView.name;
          }

          $scope.instance.updateView(
            $scope.selectedView.name,
            viewXML,
            function () {
              $scope.changesSaved = true;
              loadViews();
            }
          );
        }

        hidePopup("#" + $scope.popupId);
      };

      $scope.onViewSelect = function (withoutColReset) {
        for (var i = 0; i < $scope.views.length; i++) {
          if ($scope.views[i].name == $scope.selectedView.originalName) {
            copyView($scope.selectedView, $scope.views[i]);

            if (!withoutColReset) reset($scope.selectedView.selectedColumn);

            $scope.selectedView.originalName = $scope.views[i].name;

            if ($scope.selectedView.columns) {
              /* console.error($scope.type);
                    var newColumnsArray = [];
                    for (let d = 0; d < $scope.selectedView.columns.length; d++) {
                        newColumnsArray.push($scope.selectedView.columns[d].class);
                    }
                    console.error(JSON.stringify(newColumnsArray));
                    console.error("==="); */
              for (var c = 0; c < $scope.selectedView.columns.length; c++) {
                var column = $scope.selectedView.columns[c];
                column.entryName = getColumnText(column);
              }
            }

            $scope.createNewView = false;

            $timeout(function () {
              window.dispatchEvent(new Event("resize"));
            });
            break;
          }
        }
      };

      $scope.onClose = function () {
        if (!$scope.changesSaved) {
          $rootScope.showConfirm(
            L.tsq("Warning"),
            L.tsq("Changes not saved. Do you want to save them?"),
            function (confirmed) {
              if (confirmed) {
                $scope.onSave();
              } else {
                hidePopup("#" + $scope.popupId);
              }
            }
          );
        } else {
          hidePopup("#" + $scope.popupId);
        }
      };

      $scope.onAddColumns = function (selectedItems) {
        for (var i = 0; i < selectedItems.length; i++) {
          var columnName = selectedItems[i];

          var column = getItem(allColumns, "class", columnName);
          if (!column) {
            console.error("Column '" + columnName + "' not found", allColumns);
            continue;
          }

          var newColumn = angular.copy(column);
          reset(newColumn);

          if (newColumn.columnType == columnTypes.wfSpecial.value) {
            newColumn.resultType = "WalkForwardOptimization";
            newColumn.subresult = columnTypes.wfSpecial.value;
          } else {
            newColumn.resultType = $scope.resultTypes.main;
            newColumn.subresult = columnTypes.wf.value;
          }

          newColumn.columnName = newColumn.name;
          newColumn.entryName = getColumnText(newColumn);

          $scope.selectedView.columns.push(newColumn);

          var conditionExistsInRecent = false;
          for (let j = 0; j < $scope.recentItems.length; j++) {
            if ($scope.recentItems[j].class == columnName) {
              $scope.recentItems[j].weight = $scope.recentItems[j].weight + 1;
              conditionExistsInRecent = true;
            }
          }
          if (!conditionExistsInRecent) {
            $scope.recentItems.push({
              name: column.name,
              class: columnName,
              weight: 11,
            });
          }
        }

        $scope.recentItems
          .sort(function (x, y) {
            if (x.weight < y.weight) {
              return -1;
            }
            if (x.weight > y.weight) {
              return 1;
            }
            return 0;
          })
          .reverse();

        $scope.recentItems = $scope.recentItems.slice(0, 20);

        AppService.saveSetting(
          $scope.recentlyUsedKey,
          JSON.stringify($scope.recentItems),
          function () {}
        );

        $scope.columnsChooser.loadRecentItems($scope.recentItems);

        $scope.changesSaved = false;

        return true;
      };

      $scope.onSelectColumn = function (column) {
        $scope.selectedView.selectedColumn = column;

        $scope.columnSettings.onlyISOOS($scope.type == "wfresults");
        $scope.columnSettings.setSettings(column);

        showPopup("#" + $scope.columnSettingsModalId);

        viewColumnSelected = true;
      };

      $scope.onColumnSettingsChange = function () {
        if ($scope.isDefaultViewSelected()) {
          return;
        }

        var column = $scope.selectedView.selectedColumn;
        if (!column) {
          return;
        }

        var settings = $scope.columnSettings.getSettings();

        if (
          column.sampleType != settings.sampleType ||
          column.direction != settings.direction ||
          column.plType != settings.plType ||
          column.resultType != settings.resultType ||
          column.confidenceLevel != settings.confidenceLevel ||
          column.market != settings.market ||
          column.subresult != settings.subresult ||
          column.showMainResult != settings.showMainResult
        ) {
          $scope.changesSaved = false;
        }

        column.sampleType = settings.sampleType;
        column.direction = settings.direction;
        column.plType = settings.plType;
        column.resultType = settings.resultType;

        column.confidenceLevel = settings.confidenceLevel;
        column.market = settings.market;
        column.subresult = settings.subresult;

        column.showMainResult = settings.showMainResult;

        column.entryName = getColumnText(column);
      };

      $scope.instance.selectView = function (viewName) {
        $scope.selectedView.originalName = viewName;
        $scope.onViewSelect();
      };

      function reset(column) {
        column.direction = $scope.directions.both;
        column.sampleType =
          $scope.type == "wfresults"
            ? $scope.sampleTypes.in
            : $scope.sampleTypes.full;
        column.plType = $scope.plTypes.money;
        column.resultType = $scope.resultTypes.main;

        column.confidenceLevel = 50;
        column.market = 1;
        column.subresult = columnTypes.wf.value;
        column.showMainResult = true;
      }

      $scope.instance.reloadViews = loadViews;

      $scope.instance.showDialog = function () {
        showPopup("#" + $scope.popupId);
      };

      $scope.displayColumnSettings = function () {
        return $scope.type == "Databank" || $scope.type == "wfresults";
      };

      $scope.isDefaultViewSelected = function () {
        if ($scope.type == "Databank") {
          return (
            $scope.selectedView.name == defaultDatabankViews.main ||
            $scope.selectedView.name == defaultDatabankViews.portfolio
          );
        }

        return $scope.selectedView.name == "Default";
      };

      //- Initialization --------------------------------------------------------------
      var allColumns = [];
      var viewColumnSelected = false; //indicates if some column is selected, if so, any settings changes will be saved to the column object

      $scope.changesSaved = true;

      $scope.createNewView = false; //if true, xmlConfig sent to backend will be treated as a new added view

      $scope.sampleTypes = SQConstants.getConstants().sampleTypes;
      $scope.directions = SQConstants.getConstants().directions;
      $scope.plTypes = SQConstants.getConstants().plTypes;
      $scope.resultTypes = SQConstants.getConstants().resultTypes;

      var columnTypes = SQConstants.getConstants().databankColumnTypes;
      var columns = SQConstants.getColumnsByType([
        columnTypes.general,
        columnTypes.wfSpecial,
      ]);

      $scope.views = [];

      $scope.selectedView = {
        columns: [],
        selectedColumn: {},
      };

      $scope.columnsChooser = {
        afterInit: function () {
          itemsChooserDeferred.resolve();
        },
      };

      $scope.columnSettings = {};

      $scope.recentItems = [];

      $scope.popupId = "manageViews" + $scope.type;
      $scope.columnSettingsModalId = "columnSettingsModal" + $scope.type;
      $scope.recentlyUsedKey = "recentlyUsedViewsColumns-" + $scope.type;

      var itemsChooserDeferred = $q.defer();

      var defaultItems = undefined;

      $timeout(init);
    }
  );
