/*-
 * ~~~~~~licensing~~~~~~
 * entaxy-cicd-plugin
 * ==========
 * Copyright (C) 2020 - 2025 EmDev LLC
 * ==========
 * You may not use this file except in accordance with the License Terms of the Copyright
 * Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
 * rights to the Software and any copies are the property of the Copyright Holder. Unless
 * it is explicitly allowed the Copyright Holder, the User is prohibited from using the
 * Software for commercial purposes to provide services to third parties.
 * 
 * The Copyright Holder hereby declares that the Software is provided on an "AS IS".
 * Under no circumstances does the Copyright Holder guarantee or promise that the
 * Software provided by him will be suitable or not suitable for the specific purposes
 * of the User, that the Software will meet all commercial and personal subjective
 * expectations of the User, that the Software will work properly, without technical
 * errors, quickly and uninterruptedly.
 * 
 * Under no circumstances shall the Copyright Holder or its Affiliates is not liable
 * to the User for any direct or indirect losses of the User, his expenses or actual
 * damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
 * or damage to data, property, etc.
 * ~~~~~~/licensing~~~~~~
 */

var EntaxyCICD;
(function (EntaxyCICD) {
    EntaxyCICD._module.component('entaxyCiCdConfiguration', {
        bindings: {
            configurationId: '<',
            configured: '<',
            isDirty: '='
        },
        template:
        `
          <div class="entaxy-cicd-header-container">
            <h2>
              Configuration: {{$ctrl.configurationId}}
            </h2>
          </div>
          
          <div class="entaxy-cicd-subtitle-info-container">
            <span>Configured Id: {{$ctrl.configuredId}}</span>
            <span>Configured Type: {{$ctrl.configuredType}}</span>
          </div>
          
          <pf-toolbar class="entaxy-toolbar" config="$ctrl.toolbarConfig"></pf-toolbar>
          <form name="entaxyObjectForm" class="form-horizontal">
            <div class="entaxy-table-with-inputs" ng-if="$ctrl.viewedItems && $ctrl.viewedItems.length > 0">
              <table datatable="ng" dt-options="$ctrl.dtOptions"
                    class="table-view-container table table-striped table-bordered table-hover dataTable no-footer">
                <thead>
                  <tr role="row">
                    <th>Name</th>
                    <th>Display Name</th>
                    <th>Imported Value</th>
                    <th>Local Value</th>
                  </tr>
                </thead>
                <tbody>
                  <tr role="row" ng-repeat="field in $ctrl.viewedItems">
                    <td ng-class="{'red': field.isRed, 'green': field.isGreen, 'bold': field.importedValue !== field.originValue}">
                      {{ field.name }}
                    </td>
                    <td>{{ field.displayName }}</td>
                    <td class="field-input-cell" ng-class="{'field-input-checkbox-cell': field.type === 'checkbox'}"
                            ng-if="$ctrl.configured">
                      <input type="{{field.type}}" ng-class="{'form-control': field.type !== 'checkbox'}"
                            ng-model="field.importedValue" ng-change="$ctrl.checkDirtiness()"/>
                    </td>
                    <td ng-if="!$ctrl.configured">{{ field.importedValue }}</td>
                    <td>{{ field.localValue }}</td>
                  </tr>
                </tbody>
              </table>
            </div>
          </form>
          <pf-empty-state ng-if="!$ctrl.viewedItems || $ctrl.viewedItems.length == 0"></pf-empty-state>
        `,
        controller: EntaxyCICDConfigurationController
    })
        .name;

    function EntaxyCICDConfigurationController(workspace, $scope, $location, entaxyCICDService, entaxyService,
                                               entaxyHotkeysService) {
        'ngInject';

        let ctrl = this;

        ctrl.dtOptions = {
            autoWidth: false,
            destroy: true,
            order: [[0, "asc"]],
            dom: "t",
            paging: false
        };

        ctrl.toolbarConfig = {
            filterConfig: {
                fields: [
                    {
                        id: 'displayName',
                        title: 'Display Name',
                        placeholder: 'Filter by Display Name...',
                        filterType: 'text'
                    },
                    {
                        id: 'name',
                        title: 'Name',
                        placeholder: 'Filter by Name...',
                        filterType: 'text'
                    }
                ],
                inlineResults: true,
                appliedFilters: [],
                onFilterChange: filterChange
            },
            isTableView: true
        };

        function filterChange(filters) {
            ctrl.viewedItems = Entaxy.applyFilters(ctrl.items, filters, matchesFilter);
            ctrl.toolbarConfig.filterConfig.resultsCount = ctrl.viewedItems.length;
        };

        function matchesFilter(item, filter) {
            let match = true;
            if (filter.id === 'name') {
                match = item.name.toLowerCase().match(filter.value.toLowerCase()) !== null;
            } else if (filter.id === 'displayName') {
                match = item.displayName.toLowerCase().match(filter.value.toLowerCase()) !== null;
            }
            return match;
        };

        ctrl.checkDirtiness = function () {
            if ($scope.entaxyObjectForm.$dirty) {
                let isDirty = false;
                for (let i = 0; i < ctrl.items.length; i++) {
                    if (ctrl.items[i].importedValue !== ctrl.items[i].originValue) {
                        isDirty = true;
                        break;
                    }
                }
                if (!isDirty) {
                    $scope.entaxyObjectForm.$setPristine();
                }
            }
        }

        setTimeout( function () {
            ctrl.activeTabIndex = entaxyService.getActiveTabIndex();
        });

        $scope.$on("$locationChangeStart", function(event) {
            if ($scope.entaxyObjectForm.$dirty && !confirm(Entaxy.CONFIRMATION.UNSAVED_CHANGES)) {
                event.preventDefault();
                ctrl.isTreeOrTabSelectionUpdateNeeded = true;
            }
        });

        $scope.$watch('$ctrl.isTreeOrTabSelectionUpdateNeeded', function (newValue) {
            if (newValue) {
                setTimeout(function () {
                    entaxyService.updateTabSelection(ctrl.activeTabIndex);
                });
                Jmx.updateTreeSelectionFromURL($location, $(entaxyCICDTreeElementId));
                ctrl.isTreeOrTabSelectionUpdateNeeded = false;
            }
        });

        ctrl.$onInit = function() {
            entaxyHotkeysService.setHotkeys($scope, getHotkeysConfigs());

            if (ctrl.configured) {
                let primaryActions = [
                    { name: 'Clear Changes', actionFn: clearChanges },
                    { name: 'Copy Local Values', actionFn: useLocalValues },
                    { name: 'Save Changes', actionFn: save }
                ];

                ctrl.toolbarConfig.actionsConfig = {
                    primaryActions: primaryActions
                };
            }
        }

        const storage = EntaxyCICD.getStorage(workspace.selection);
        const application = EntaxyCICD.getProjectOrApplication(workspace.selection);
        const version = EntaxyCICD.getVersion(workspace.selection);
        const revision = workspace.selection.title.split(' ')[0];

        $scope.$watch('entaxyObjectForm.$dirty', function () {
            ctrl.isDirty = $scope.entaxyObjectForm.$dirty;
        });

        $scope.$watch('$ctrl.configurationId', function () {
            $scope.entaxyObjectForm.$setPristine();
            populateTable();
        });

        function populateTable() {

            entaxyCICDService.executeOperation('readRevisionConfiguration',
                [storage, application, version, revision, ctrl.configurationId])
            .then(result => {
                let config = JSON.parse(result);

                ctrl.configuredId = config.id;
                ctrl.configuredType = config.type;

                let fields = config.fields;
                ctrl.items = fields.length === 0 ? [] : fields.map(field => {
                    field.type = Entaxy.convertToHtmlInputType(field.type);
                    if (field.importedValue === "" || field.importedValue === null) {
                        field.isRed = true;
                    } else if (field.localValue === "" || field.localValue === null) {
                        field.isGreen = true;
                    }
                    if (field.type === 'number') {
                        field.importedValue = field.importedValue !== null ? JSON.parse(field.importedValue) : null;
                    }
                    field.originValue = field.importedValue;
                    return field;
                });
                filterChange(ctrl.toolbarConfig.filterConfig.appliedFilters);
            }).catch(error => {
                Entaxy.notificationError('Can not read configuration: ' + error);
                EntaxyCICD.log.error(error);
            });
        }

        function clearChanges() {
            if ($scope.entaxyObjectForm.$dirty) {
                ctrl.items = ctrl.items.map(item => {
                    item.importedValue = item.originValue;
                    return item;
                });
                filterChange(ctrl.toolbarConfig.filterConfig.appliedFilters);
                $scope.entaxyObjectForm.$setPristine();
            }
        }

        function useLocalValues() {
            ctrl.items = ctrl.items.map(item => {
                item.importedValue = item.localValue;
                return item;
            });
            if (!$scope.entaxyObjectForm.$dirty) {
                $scope.entaxyObjectForm.$setDirty();
            } else {
                ctrl.checkDirtiness();
            }
        }

        function save() {
            if ($scope.entaxyObjectForm.$dirty) {
                let properties = getProperties();

                entaxyCICDService.executeOperation('saveRevisionConfiguration',
                    [storage, application, version, revision, ctrl.configurationId, properties])
                .then(result => {
                    Entaxy.notificationSuccess(result);
                    $scope.entaxyObjectForm.$setPristine();
                    populateTable();
                }).catch(error => {
                    Entaxy.notificationError(error);
                    EntaxyCICD.log.error(error);
                });
            }
        }

        function getProperties() {
            let filteredFields = ctrl.items.filter(field => field.importedValue !== field.originValue);

            if (filteredFields && filteredFields.length > 0) {
                return filteredFields.reduce((obj, cur) => ({ ...obj, [cur.name] : cur.importedValue }), {});
            }
        }

        function getHotkeysConfigs() {
            return [
                {
                    ...Entaxy.getSaveHotkeyDescription(),
                    callback: function (event) {
                        event.preventDefault();
                        save();
                    }
                }
            ];
        }
    }
    EntaxyCICDConfigurationController.$inject = ['workspace', '$scope', '$location', 'entaxyCICDService',
        'entaxyService', 'entaxyHotkeysService'];

})(EntaxyCICD || (EntaxyCICD = {}));
