/*-
 * ~~~~~~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('entaxyInnerObjectInputModal', {
        bindings: {
            modalInstance: '<',
            resolve: '<'
        },
        template:
        `
          <div class="entaxy-modal-container">
            <div class="modal-header">
              <button type="button" class="close" aria-label="Close" ng-click="$ctrl.cancel()">
                <span class="pficon pficon-close" aria-hidden="true"></span>
              </button>
              <h4 class="modal-title">{{$ctrl.modalTitle}}</h4>
            </div>
              <div class="modal-body-header">
                <h2>{{$ctrl.subTitle}}</h2>
              </div>
              <div class="modal-body">
                <form name="entaxyInnerObjectForm" class="form-horizontal">
                  <entaxy-form-fields items="$ctrl.viewedFormFields" errors="$ctrl.errors" mode="$ctrl.mode"
                          form-controller="entaxyInnerObjectForm"></entaxy-form-fields>
                </form>
              </div>
              <div class="modal-footer">
                <button type="submit" class="btn btn-primary" ng-click="$ctrl.save()">{{$ctrl.buttonTitle}}</button>
              </div>
          </div>
        `,
        controller: entaxyInnerObjectInputModalController
    })
        .name;

    function entaxyInnerObjectInputModalController($uibModal, $scope, workspace, entaxyService, entaxyHotkeysService) {
        'ngInject';

        let ctrl = this;

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

            ctrl.mode = ctrl.resolve.mode;
            ctrl.model = ctrl.resolve.model;
            let extraInfo = ctrl.resolve.fieldName ? ': ' + ctrl.resolve.fieldName : '';
            ctrl.modalTitle = ctrl.mode + ' Inner Object' + extraInfo;
            ctrl.subTitle = ctrl.model ?
                ctrl.mode + ' properties of inner object' + extraInfo : 'Fill in fields' + extraInfo;
            ctrl.buttonTitle = 'Ok';

            populateFormFields();
        }

        function populateFormFields() {
            let promise = ctrl.resolve.objectFactoryFilter ?
                entaxyService.getFactoriesByFilterSearch(ctrl.resolve.objectFactoryFilter) :
                entaxyService.getFactoriesByType(ctrl.resolve.type);

            promise.then(factories => {
                ctrl.factories = factories;
                let factoryId = ctrl.model ? ctrl.model.factoryId : factories[0].name;
                ctrl.populatedFactoriesFields = [factoryId];

                ctrl.formFields = [{
                    label: 'Factory',
                    name: 'factoryId',
                    type: 'text',
                    description: factories
                        .sort(Entaxy.compareBy('displayName'))
                        .map(factory => factory.displayName + ' - ' + factory.description)
                        .join('<br/>'),
                    value: factoryId,
                    readOnly: ctrl.mode === Entaxy.MODAL_MODES.VIEW ? true : false,
                    required: ctrl.mode === Entaxy.MODAL_MODES.VIEW ? false : true,
                    group: 'general',
                    typeInfo: {
                        type: 'enum',
                        values: factories
                            .map(factory => { return { displayValue: factory.displayName, value: factory.name };})
                            .sort(Entaxy.compareBy('displayValue')),
                        isEmptyIncluded: false
                    }
                }];

                createFormFields(factoryId);

                addWatcher();
            });
        }

        function createFormFields(factoryId) {
            let mbeanName = getFactoryById(factoryId).mbeanName;
            entaxyService.getFields(mbeanName)
            .then((response) => {
                let objectId = ctrl.model ? ctrl.model.objectId : undefined;
                let properties = ctrl.model ? ctrl.model.properties : undefined;
                let configurableOnly = false;

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

                    let formField = entaxyService
                        .makeFormField(field, objectId, properties, configurableOnly, ctrl.mode);
                    if (formField) {
                        formField.belongsToFactory = factoryId;
                        ctrl.formFields.push(formField);
                    }
                });

                filterFormFields(factoryId);
            });
        }

        function getFactoryById(factoryId) {
            return ctrl.factories.find(factory => factory.name === factoryId);
        }

        function addWatcher() {
            $scope.$watch('$ctrl.formFields[0].value', function (newValue, oldValue) {
                if (newValue !== oldValue) {
                    if (!ctrl.populatedFactoriesFields.includes(newValue)) {
                        createFormFields(newValue);
                        ctrl.populatedFactoriesFields.push(newValue);
                    } else {
                        filterFormFields(newValue);
                    }
                }
            });
        }

        function filterFormFields(factoryId) {
            ctrl.viewedFormFields = ctrl.formFields
                .filter(formField =>
                    formField.name === 'factoryId' || formField.belongsToFactory === factoryId);
        }

        ctrl.cancel = function(reason) {
            ctrl.modalInstance.dismiss(reason);
        }

        ctrl.save = function () {
            if (ctrl.mode === Entaxy.MODAL_MODES.VIEW) {
                ctrl.cancel();
            } else {

                let selectedFactory = ctrl.viewedFormFields.find(formField => formField.name === 'factoryId');

                entaxyService.validateFields(ctrl.viewedFormFields, selectedFactory)
                .then(errors => {
                    ctrl.errors = errors;

                    if (Object.keys(ctrl.errors).length === 0) {
                        if (ctrl.resolve.outerFormController && !ctrl.resolve.outerFormController.$dirty &&
                            $scope.entaxyInnerObjectForm && $scope.entaxyInnerObjectForm.$dirty) {
                            ctrl.resolve.outerFormController.$setDirty();
                        }

                        let args = entaxyService.getArguments(ctrl.viewedFormFields, ctrl.factories);

                        ctrl.modalInstance.close(args);
                    }
                });
            }
        }

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

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