angular.module('app').controller('ConditionsGridCtrl', function ($scope, $rootScope, $timeout, $interval, $q, ConditionsGridService, SQConstants, UniqueIdGenerator, AppService, L) {
    console.log("ConditionsGridCtrl initialized");

    function init() {
        conditionsObj = createConditionsElem();
        intervalPromise = $interval(tryInitGrid, 50, false);

        var defaultItemsPure = SQConstants.getColumns().recentColumns;

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

    function tryInitGrid() {
        var element = angular.element('#' + $scope.gridId);
        if (element[0] && typeof $scope.columnSettings.onlyMainData === 'function') {
            $interval.cancel(intervalPromise);
            initGrid();
        }
    }

    function createConditionsElem() {
        var xmlDoc = AppService.xmlDoc;
        if (!xmlDoc) return;

        return xmlDoc.createElement('Conditions');
    }

    function initEditChooser() {
        var editColumns = angular.copy($scope.columns);
        editColumns.splice(0, 0, {
            name: 'Number',
            class: 'Number',
            value: 'Number',
            category: L.tsq('Constants')
        });

        for (var i = 0; i < $scope.recentConditions.length; i++) {
            var recentCondition = $scope.recentConditions[i];

            var columnObj = getItem($scope.columns, 'class', recentCondition);
            if (!columnObj) {
                continue;
            }

            editColumns.splice(i, 0, {
                name: columnObj.name,
                class: columnObj.class,
                value: columnObj.class,
                columnType: columnObj.columnType,
                type: columnObj.type,
                category: L.tsq('Recent')
            });
        }

        $scope.editConditionChooser.init(editColumns, onEditColumnChange);
    }

    function initGrid() {
        grid = new sqGrid($scope.gridId);

        var columns = [
            // { title: L.tsq('Use'), type: "text", sort: 'text' },
            {
                title: L.tsq('Left value'),
                type: "text",
                sort: 'text'
            },
            {
                title: '<>=',
                type: "text",
                sort: 'text'
            },
            {
                title: L.tsq('Right value'),
                type: "text",
                sort: 'text'
            },
            {
                title: '',
                type: "text",
                sort: 'text'
            }
        ];

        var widths = ['*', 40, '*', 20];

        grid.setFirstColumnAsId(false);
        grid.setColumns(columns, !!grid);
        grid.setWidths(widths, !!grid);
        grid.setEmptyGridText(L.tsq('No conditions defined.'));
        grid.disableSorting();
        grid.enableCheckboxes(true);

        // grid.defineWidget('checkboxWidget', sqGridCheckbox);
        grid.defineWidget('selectWidget', sqGridSelect);

        grid.cellEventHandler = function (rowIndex, cellIndex, eventName, args) {
            switch (eventName) {
                case "selectUpdated":
                    onModifyCondition(rowIndex, 2);
                    break;
                case "removeCondition":
                    onRemoveCondition(rowIndex);
                    break;
            }
        };

        grid.onCellDoubleClick = function (rowIndex, cellIndex) {
            if (!grid.isRowChecked(rowIndex)) {
                return;
            }

            if (cellIndex == 1 || cellIndex == 3) {
                onModifyCondition(rowIndex, cellIndex);
            }
        };

        grid.onSelectionChanged = function () {
            if (loading) return;

            for (var i = 0; i < grid.rows.length; i++) {
                onModifyCondition(i, 0, true);
            }

            load();
        };

        autoGridHeight();
        grid.headerRedraw();

        if ($scope.afterInit) {
            itemsChooserDeferred.promise.then(function () {
                $scope.afterInit();
            });
        }
    }

    function onModifyCondition(rowIndex, colIndex, dontReloadGrid) {
        lastRowIndex = rowIndex
        lastColIndex = colIndex;

        switch (colIndex) {
            case 0:
                ConditionsGridService.updateCondition(conditionsObj, lastRowIndex, lastColIndex, grid.isRowChecked(rowIndex), dontReloadGrid ? null : load);
                break;
            case 2:
                ConditionsGridService.updateCondition(conditionsObj, lastRowIndex, lastColIndex, sqGridSelectValueGet(grid, rowIndex, 1), dontReloadGrid ? null : load);
                break;
            case 1:
            case 3:
                showEditPopup();
                break;
        }
    }

    function showEditPopup() {
        $scope.conditionDetails = ConditionsGridService.getConditionDetails(conditionsObj, lastRowIndex, lastColIndex, $scope.columns);

        if ($scope.onEdit) $scope.onEdit($scope.conditionDetails, lastRowIndex, lastColIndex);

        if ($scope.conditionDetails.valueType == $scope.valueTypes.column) {
            $scope.editConditionChooser.selectItem($scope.conditionDetails.column);
        } else {
            $scope.editConditionChooser.selectItem('Number');
            $scope.conditionsValueStep = $scope.conditionDetails.valueType == ConditionsGridService.columnValueTypes.Integer ? 1 : 0.1;
        }

        if (lastColIndex == 3) {
            $scope.editConditionLabel = grid.getCellValue(lastRowIndex, 0) + " " + sqGridSelectValueGet(grid, lastRowIndex, 1) + " " + L.tsq("this");
        } else {
            $scope.editConditionLabel = L.tsq("this") + " " + sqGridSelectValueGet(grid, lastRowIndex, 1) + " " + grid.getCellValue(lastRowIndex, 2);
        }

        $scope.columnSettings.setSettings($scope.conditionDetails);

        try {
            $scope.$digest();
        } catch (err) { }

        showPopup('#' + $scope.editConditionsModal);
    }

    function onRemoveCondition(rowIndex) {
        var condition = grid.getCellValue(rowIndex, 1) + ' ' + sqGridSelectValueGet(grid, rowIndex, 1) + ' ' + grid.getCellValue(rowIndex, 3);
        ConditionsGridService.removeCondition(conditionsObj, rowIndex, load);
    }

    function onEditColumnChange() {
        var selectedItems = $scope.editConditionChooser.getSelectedItems();

        if (selectedItems && selectedItems[0]) {
            $scope.conditionDetails.columnName = selectedItems[0];

            var column = getItem($scope.columns, 'class', selectedItems[0]);
            if (column) {
                $scope.conditionDetails.category = column.category;
                $scope.conditionDetails.column = column.class;
                $scope.conditionDetails.valueType = column.type;
            }

            if ($scope.conditionDetails.columnName == 'Number') {
                $scope.conditionDetails.valueType = $scope.valueTypes.numeric;
            }
            else {
                $scope.conditionDetails.valueType = $scope.valueTypes.column;
            }

            $scope.columnSettings.columnChanged($scope.conditionDetails.column);

            $scope.$evalAsync();
        }
    }

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

            var column = getItem($scope.columns, 'class', condition);
            var value = ConditionsGridService.formatNumber('0', column ? column.type : null);

            grid.addRow([condition, getComparatorCellValue('>'), value, createActionLink('<i class="fa fa-times" aria-hidden="true"></i>', "action-link", "removeCondition")], true);
            grid.setRowChecked(i, true);

            ConditionsGridService.addCondition(conditionsObj, true, condition, '>', '0', $scope.columns, sampleTypeDef, $scope.name);

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

        grid.bodyRedraw();

        ConditionsGridService.updateRecentConditions($scope.recentItems, function (data) {
            //setRecentColumns(data.recentColumns);
            initEditChooser();
            load();
            $scope.conditionsChooser.loadRecentItems($scope.recentItems, defaultItems);
        });

        return true;
    }

    $scope.onSaveCondition = function () {
        if ($scope.conditionDetails.valueType == $scope.valueTypes.numeric && checkDoubleValue($scope.conditionDetails.numericValue) == null) {
            $rootScope.showError(L.tsq("Value '%s' has invalid number format.", [$scope.conditionDetails.numericValue]));
            return;
        }

        hidePopup('#' + $scope.editConditionsModal);

        ConditionsGridService.updateCondition(conditionsObj, lastRowIndex, lastColIndex, $scope.conditionDetails, function () {
            load();
        });
    }

    function setRecentColumns(recentColumns) {
        if (!recentColumns) {
            recentColumns = [];
        }

        $scope.recentConditions.length = 0;

        for (var i = 0; i < recentColumns.length; i++) {
            if ($scope.recentConditions.length == 8) {
                break;
            }

            var recentColumn = recentColumns[i];

            var columnObj = getItem($scope.columns, 'class', recentColumn);
            if (!columnObj) {
                continue;
            }

            if (!$scope.recentConditions.includes(recentColumn)) {
                $scope.recentConditions.push(recentColumn);
            }
        }
    }

    function load(doNotNotify) {
        loading = true;

        grid.removeAllRows(true, true);
        grid.bodyRedraw();

        if (conditionsObj) {
            var conditions = getChildElements(conditionsObj, "Condition");

            if (conditions) {
                var conditionsChecked = 0;
                for (var i = 0; i < conditions.length; i++) {
                    var condition = conditions[i];

                    var leftSideObj = getChildElement(condition, "Left-Side");
                    var comparatorObj = getChildElement(condition, "Comparator");
                    var rightSideObj = getChildElement(condition, "Right-Side");

                    var use = getAttrBooleanValue(condition, 'use', false);
                    var passed = getAttrBooleanValue(condition, 'passed', false);

                    var value1 = ConditionsGridService.getConditionValue(leftSideObj);
                    var comparator = comparatorObj ? (correctAttrValue(comparatorObj.attributes['value']) || null) : null;
                    var value2 = ConditionsGridService.getConditionValue(rightSideObj);

                    grid.addRow([value1, getComparatorCellValue(comparator), value2, createActionLink('<i class="fa fa-times" aria-hidden="true"></i>', "action-link", "removeCondition")], true);
                    grid.setUserData(i, "passed", passed);
                    grid.setRowChecked(i, use, false, true);
                    grid.setCellCustomData(i, 1, "cellsDisabled", !use)
                    // sqGridCheckboxSetValue(grid, i, 0, use, true);

                    if (!use) {
                        grid.setRowClass(i, "unused");
                        grid.setCellDisabled(i, 2, true, true);
                    } else {
                        conditionsChecked++;
                    }
                }

                if (conditionsChecked == conditions.length) {
                    grid.checkedAll = true;
                    grid.headerRedraw();
                }
            }
        }

        autoGridHeight();
        grid.bodyRedraw();

        if ($scope.onRefresh && !doNotNotify) {
            $scope.onRefresh(grid);
        }

        loading = false;

    }

    function autoGridHeight() {
        if ($scope.autoHeight) {
            var totalHeight = (grid.rows.length + 3) * grid.rowHeight;
            $("#" + $scope.gridId).css("height", totalHeight + "px");
        }
    }

    function getComparatorCellValue(value) {
        return getSimpleSelectCellValue(['>', '<', '=', '>=', '<=', '<>'], value);
    }

    function getSimpleSelectCellValue(options, value) {
        var text = "{{selectWidget options='{";

        for (var i = 0; i < options.length; i++) {
            var option = options[i];
            text += (i ? "," : "") + "\"" + option + "\":\"" + option + "\"";
        }

        return text + "}' value='" + value + "'}}";
    }

    $scope.instance.setData = function (columns, recentColumns) {
        if(!columns || !columns.length){
            $scope.columns.length = 0;
        }
        else {
            loadToArray($scope.columns, columns);
        }
        // setRecentColumns(recentColumns);

        $scope.conditionsChooser.init($scope.columns);

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

        $scope.conditionsChooser.loadRecentItems($scope.recentItems, defaultItems);

        initEditChooser();

        if ($scope.columns.length > 0) {
            $scope.conditionDetails.column = $scope.columns[0].class;
        }
    }

    $scope.instance.setConditionsObj = function (obj, doNotNotify) {
        if (obj && obj.nodeName == 'Conditions') {
            conditionsObj = obj;
        } else {
            conditionsObj = createConditionsElem();
        }

        load(doNotNotify);
    }

    $scope.instance.getConditionsObj = function () {
        return conditionsObj;
    }

    $scope.instance.getAddChooser = function () {
        return $scope.conditionsChooser;
    }

    $scope.instance.getEditChooser = function () {
        return $scope.editConditionChooser
    }

    $scope.instance.getGrid = function () {
        return grid;
    }

    $scope.instance.onlyMainData = function () {
        $scope.columnSettings.onlyMainData();
    }

    $scope.instance.size = function () {
        return grid.rows.length;
    }

    $scope.$on("$destroy", function () {
        UniqueIdGenerator.removeId($scope.gridId);
        UniqueIdGenerator.removeId($scope.editConditionsModal);
    });

    $scope.onColumnSettingsChange = function () {
        var settings = $scope.columnSettings.getSettings();

        $scope.conditionDetails.sampleType = settings.sampleType;
        $scope.conditionDetails.direction = settings.direction;
        $scope.conditionDetails.plType = settings.plType;
        $scope.conditionDetails.resultType = settings.resultType;

        $scope.conditionDetails.confidenceLevel = settings.confidenceLevel;
        $scope.conditionDetails.market = settings.market;
        $scope.conditionDetails.subresult = settings.subresult;
    }

    $scope.saveConditions = function () {
        var extension = {
            name: 'xml',
            description: L.tsq('XML Files')
        };

        $rootScope.saveFile("Choose target file", extension, "saveFilters", "filters", null, function (filePath) {
            var data = {
                file: filePath,
                xml: new XMLSerializer().serializeToString(conditionsObj)
            }

            ConditionsGridService.saveConditions(data, function (result) {
                $rootScope.showSuccess(L.tsq("Filters saved."));
                window.parent.hidePopup("#saveFileDialog");
            });
        });
    }

    $scope.loadConditions = function () {
        var fileExtension = {
            name: 'xml',
            description: L.tsq('XML Files')
        };

        $rootScope.showFilePicker(L.tsq("Select file"), "loadFilters", true, false, null, fileExtension, null, function (paths) {
            if (paths) {
                var data = {
                    file: paths[0],
                }

                ConditionsGridService.loadConditions(data, function (result) {
                    var conditionsObj = xmlToObject(result.xml).find("Conditions")[0];

                    $scope.instance.setConditionsObj(conditionsObj);

                    $rootScope.showSuccess(L.tsq("Filters loaded."));
                });
            }
        });
    }

    $scope.afterItemsChooserModalInit = function () {
        itemsChooserDeferred.resolve();
    }

    var grid;
    var lastRowIndex, lastColIndex;

    var itemsChooserDeferred = $q.defer();

    var intervalPromise = null;

    var loading = false;

    $scope.conditionsChooser = {};
    $scope.editConditionChooser = {};

    $scope.gridId = $scope.customId ? 'grid-'+$scope.customId : UniqueIdGenerator.generateId();
    $scope.editConditionsModal = UniqueIdGenerator.generateId(); //$scope.customId ? 'modal-'+$scope.customId : UniqueIdGenerator.generateId(); - sposobovalo chybu pri editaci - duplicitne modal ID

    $scope.conditionsValueStep = 1;

    $scope.resultTypes = ConditionsGridService.resultTypes;
    $scope.resultTypesList = ConditionsGridService.resultTypesList;

    $scope.directions = ConditionsGridService.directions;
    $scope.sampleTypes = ConditionsGridService.sampleTypes;
    $scope.plTypes = ConditionsGridService.plTypes;
    $scope.valueTypes = ConditionsGridService.getValueTypes();

    var columnTypes = SQConstants.getConstants().databankColumnTypes;
    var wfSubresultsList = ConditionsGridService.wfSubresultsList;

    $scope.recentConditions = [];

    $scope.conditionDetails = {
        valueType: $scope.valueTypes.numeric,
        numericValue: 0,
        column: null,
        resultType: $scope.resultTypes.main,
        sampleType: $scope.sampleTypes.full,
        direction: $scope.directions.both,
        plType: $scope.plTypes.money,
        confidenceLevel: 50,
        market: 1,
        subresult: wfSubresultsList[0].value
    }

    var conditionsObj = null;

    $scope.columnSettings = {};

    var sampleTypeDef = $scope.sampleTypes.full;

    $scope.instance.setDefaultSampleType = function (type) {
        sampleTypeDef = type;
    }

    $scope.changeValueLinkDisabled = false;

    $scope.columns = [];
    $scope.recentItems = [];

    var defaultItems = [];

    init();

});