/*-
 * ~~~~~~licensing~~~~~~
 * entaxy-management-plugin
 * ==========
 * Copyright (C) 2020 - 2023 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 Entaxy;
(function (Entaxy) {
    Entaxy._module
    .component('entaxyProperties', {
        bindings: {
            itemName: '@',
            useGrandParentMbean: '<'
        },
        template:
        `
          <div class="properties-header-container">
            <h2>
              {{$ctrl.title}}
            </h2>
            
            <button type="submit" class="btn btn-primary" ng-click="$ctrl.save()">
              {{$ctrl.submitBtnTitle}}
            </button>
          </div>
          
          <div class="properties-container">
            <entaxy-modal-group-fields groups="$ctrl.groups" fields="$ctrl.formFields"
                  use-form-dirty="true" is-form-dirty="$ctrl.isFormDirty" errors="$ctrl.errors"
                  mode="$ctrl.mode" ng-if="$ctrl.groups && $ctrl.formFields"></entaxy-modal-group-fields>
          </div>
        `,
        controller: entaxyPropertiesController
    })
    .name;

    function entaxyPropertiesController($scope, workspace, operationsService, entaxyService, jolokia, $location) {
        'ngInject';

        let ctrl = this;

        ctrl.$onInit = function() {

            ctrl.mode = Entaxy.MODAL_MODES.EDIT;

            let selectedMbean = workspace.getSelectedMBean();
            ctrl.title = 'Properties of ' + selectedMbean.title;
            ctrl.submitBtnTitle = Entaxy.getButtonTitleByMode(ctrl.mode);
            let itemName = jolokia.getAttribute(selectedMbean.objectName, 'Name');

            let mbeanName = selectedMbean.parent.objectName;
            if (ctrl.useGrandParentMbean === true) {
                mbeanName = selectedMbean.parent.parent.objectName;
            }

            operationsService
            .executeOperation(mbeanName, { name: 'get' + ctrl.itemName + 'Config' }, [ itemName ])
            .then(result => {
                ctrl.itemInfo = JSON.parse(result);
                let properties = Object.entries(ctrl.itemInfo.properties);
                ctrl.properties = properties.map(property => { return { name: property[0], value: property[1] }; });

                let factory = entaxyService.getDomainFolder()
                    .findDescendant(child => child.title === ctrl.itemInfo.factoryId);
                ctrl.factories = [{ name: factory.title, mbeanName: factory.objectName }];

                makeFormFieldsAndGroups();
            }).catch(error => {
                Core.notification('danger', error, 5000);
                Entaxy.log.error(error);
            });
        }

        function makeFormFieldsAndGroups() {

            ctrl.formFields = [];

            ctrl.formFields.push({
                label: 'Factory Id',
                name: 'factoryId',
                type: 'java.lang.String',
                helpText: null,
                value: ctrl.factories[0].name,
                readOnly: true,
                required: true,
                group: 'general'
            });

            let mbeanName = ctrl.factories[0].mbeanName;

            operationsService.executeOperation(mbeanName, { name: 'getFields' }, [ 'init' ])
            .then((response) => {

                let groups = new Set();
                groups.add('general');

                _.forEach(JSON.parse(response), (field) => {

                    let formField = entaxyService.makeFormField(field, ctrl.itemInfo['objectId'], ctrl.properties, ctrl.mode);
                    if (formField) {
                        ctrl.formFields.push(formField);
                        groups.add(formField.group);
                    }
                });

                ctrl.formFields.forEach(formField => formField.type = Entaxy.convertToHtmlInputType(formField.type));

                processDependencies();

                ctrl.groups = Array.from(groups).map((group) => { return { name: group, displayName: group }; });
            });
        }

        function processDependencies() {
            let dependentFormFields = entaxyService.getDependentFormFields(ctrl.formFields);
            ctrl.definingFormFields = entaxyService.getDefiningFormFields(dependentFormFields, ctrl.formFields);

            for (let i = 0; i < ctrl.definingFormFields.length; i++) {
                if (ctrl.definingFormFields[i].value) {
                    let dependentFormFieldsWithListType = dependentFormFields
                            .filter(field => (field.typeInfo && field.typeInfo.type === 'list'));
                    entaxyService.processDependencies(dependentFormFieldsWithListType,
                                                      ctrl.definingFormFields,
                                                      ctrl.definingFormFields[i].name,
                                                      ctrl.definingFormFields[i].value,
                                                      undefined);
                }
                $scope.$watch('$ctrl.definingFormFields[' + i + '].value', function(newValue, oldValue) {
                    if (newValue !== oldValue) {
                        entaxyService.processDependencies(dependentFormFields,
                                                          ctrl.definingFormFields,
                                                          ctrl.definingFormFields[i].name,
                                                          newValue,
                                                          oldValue);
                    }
                });
            }
        }

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

        $scope.$on("$locationChangeStart", function(event) {
            if (ctrl.isFormDirty && !confirm('You have unsaved changes. Do you want to leave the page anyway?')) {
                event.preventDefault();
                ctrl.isTreeOrTabSelectionUpdateNeeded = true;
            }
        });

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

        ctrl.save = function() {
            entaxyService.requestConfirmationForSavingIfNeededAndProceed(!ctrl.isFormDirty, save);
        }

        function save() {
            let fields = JSON.parse(JSON.stringify(ctrl.formFields));

            entaxyService.validateFields(fields, ctrl.factories[0], ctrl.itemName)
            .then(errors => {
                ctrl.errors = errors;

                if (Object.keys(ctrl.errors).length === 0) {
                    let args = entaxyService.getArguments(fields, ctrl.factories);
                    entaxyService.saveItem(args);
                    ctrl.isFormDirty = false;
                }
            });
        }
    }
    entaxyPropertiesController.$inject = ['$scope', 'workspace', 'operationsService', 'entaxyService', 'jolokia', '$location'];

})(Entaxy || (Entaxy = {}));
