/*-
 * ~~~~~~licensing~~~~~~
 * entaxy-management-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 Entaxy;
(function (Entaxy) {
    Entaxy._module
    .component('entaxySelect', {
        bindings: {
            type: '<',
            filter: '<',
            model: '=',
            readonly: '<',
            updateParent: '<',
            updateParentFn: '<',
            options: '=',
            creationEnabled: '<',
            isEmptyIncluded: '<',
            formController: '<'
        },
        template:
        `
          <div class="custom-select" ng-if="!$ctrl.readonly">
            <button type="button" class="btn-select form-control dropdown-toggle" id="filter"
                    data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
              <span class="selected-option">{{$ctrl.selectedOption.displayName}}</span>
              <span class="caret"></span>
            </button>
            <ul class="dropdown-menu">
              <li ng-repeat="option in $ctrl.options" id="option.name" ng-click="$ctrl.changeSelection(option)">
                {{ option.displayName }}
              </li>
              <li id="addItem" class="dropdown-option-new" ng-click="$ctrl.showModal()" ng-if="$ctrl.creationEnabled">
                <span class="pficon pficon-add-circle-o"></span>
                {{$ctrl.createObjectOptionTitle}}
              </li>
            </ul>
          </div>
          <input type="text" class="form-control" ng-model="$ctrl.selectedOption.displayName"
            ng-if="$ctrl.readonly" readonly>
        `,
        controller: entaxySelectController
    })
    .name;

    function entaxySelectController(workspace, jolokiaService, jolokia, $q, $uibModal, entaxyService) {
        'ngInject';

        let ctrl = this;
        let emptyValue;

        ctrl.$onInit = function() {

            if (!ctrl.readonly) {

                ctrl.itemType = Entaxy.getItemTypeFromRuntimeType(ctrl.type);

                if (ctrl.creationEnabled) {
                    ctrl.createObjectOptionTitle = 'New private ' + ctrl.itemType + '...';
                }

                populateOptions();
            } else {
                let domain = entaxyService.getDomainFolder();
                entaxyService.getAllChildMBeansByRuntimeType(domain, ctrl.type).then((mbeans) => {

                    let mbean = mbeans.find(mbean => mbean.attributes.Name === ctrl.model);

                    ctrl.selectedOption = mbean ? createOptionFromMbean(mbean) : { displayName: ctrl.model };
                });
            }
        }

        function populateOptions() {
            if (!ctrl.options) {

                let emptyOptionName = '--No ' + ctrl.itemType + ' selected--';
                emptyValue = {name: emptyOptionName, displayName: emptyOptionName};

                let domain = entaxyService.getDomainFolder();
                if (ctrl.filter) {
                    entaxyService.findObjectsByFilter(ctrl.filter).then(result => {
                        let objectFullIds = JSON.parse(result);

                        entaxyService.getMBeansByObjectFullIds(objectFullIds).then((mbeans) => {
                            populateOptionsFromMbeans(mbeans
                                .filter(mbean => mbean.attributes.RuntimeType === ctrl.type));
                        });
                    }).catch(error => {
                        Entaxy.notificationError(error);
                        Entaxy.log.error(error);
                    });
                } else {
                    entaxyService.getAllChildMBeansByRuntimeType(domain, ctrl.type).then((mbeans) => {
                        populateOptionsFromMbeans(mbeans);
                    });
                }
            } else {
                if (ctrl.isEmptyIncluded) {
                    emptyValue = ctrl.options[0];
                }
                ctrl.selectedOption = getOptionByModel();
            }
        }

        function populateOptionsFromMbeans(mbeans) {
            let items = mbeans.map(mbean => createOptionFromMbean(mbean));

            if (items && items.length > 0) {
                ctrl.options = items.sort(Entaxy.compareBy('displayName'));

                if (ctrl.isEmptyIncluded) {
                    ctrl.options.unshift(emptyValue);
                }

                ctrl.changeSelection(ctrl.model ? getOptionByModel() : items[0]);
            } else {
                ctrl.options = [];
                let notificationType = ctrl.creationEnabled ?
                    Entaxy.NOTIFICATION_TYPE.WARNING : Entaxy.NOTIFICATION_TYPE.DANGER;
                Core.notification(notificationType, 'There is no suitable ' + ctrl.itemType.toLowerCase(),
                    Entaxy.configuration[Entaxy.CONFIGURATION_KEYS.NOTIFICATION_TIMEOUT_ERROR]);
                // todo close the modal if creation is disabled
            }
        }

        function createOptionFromMbean(mbean) {
            let displayName = mbean.attributes.DisplayName;
            let name = mbean.attributes.Name;

            return {
                name: name,
                displayName: createDisplayName(displayName, name),
                mbeanName: mbean.mbean.objectName
            };
        }

        function createDisplayName(displayName, name) {
            return displayName && displayName !== name ? displayName + ' [' + name + ']' : name;
        }

        function getOptionByModel() {
            return ctrl.options.find((option) => option.name === ctrl.model || option.value === ctrl.model);
        }

        ctrl.changeSelection = function (option) {
            if (ctrl.selectedOption !== option) {
                let previousOption = ctrl.selectedOption;
                ctrl.selectedOption = option;
                ctrl.model = option.name === emptyValue.name ? undefined : (option.value ? option.value : option.name);

                if (previousOption && ctrl.formController && !ctrl.formController.$dirty) {
                    ctrl.formController.$setDirty();
                }

                if (ctrl.updateParent) {
                    if (previousOption) {
                        Entaxy.changingFieldValueNotification(ctrl.itemType);
                    }
                    ctrl.updateParentFn(previousOption, option);
                }
            }
        }

        ctrl.showModal = function() {
            $uibModal.open({
                component: 'entaxyModal',
                resolve: {
                    mode: () => Entaxy.MODAL_MODES.ADD,
                    itemType: () => Entaxy.capitalize(ctrl.itemType),
                    factories: entaxyService.getFactoriesByType(ctrl.type, ctrl.filter).then(factories => factories)
                },
                size: 'xl',
                backdrop: 'static',
                windowTopClass: 'modal-top-margin-override'
            })
            .result.then(args => {
                addItem(args);
            },
            reason => {
                if (reason) {
                    Entaxy.notificationError(reason);
                }
            });
        }

        function addItem(args) {

            let factoryId = args.factoryId.name;

            let objectId = args.fields.find((field) => field.name === 'objectId').value;

            let fields = objectId ? args.fields.filter((field) => field.name !== 'objectId') : args.fields;

            let properties = fields.reduce((obj, cur) => ({ ...obj, [cur.name] : cur.value }), {});

            let newObjectProperties = {
                factoryId: factoryId,
                objectId: objectId,
                scope: 'private',
                properties: properties
            };

            let newObjectOption = {
                name: objectId ? objectId : ('private-' + ctrl.itemType),
                value: newObjectProperties
            };

            ctrl.options.push(newObjectOption);
            ctrl.changeSelection(newObjectOption);
        }
    }
    entaxySelectController.$inject = ['workspace', 'jolokiaService', 'jolokia', '$q', '$uibModal', 'entaxyService'];

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