/*-
 * ~~~~~~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('entaxyFormFields', {
        bindings: {
            items: '<',
            setFocusOn: '<',
            errors: '<',
            mode: '<',
            formController: '<',
            updateFieldsAfterSelectionChangeFn: '<'
        },
        template:
        `                      
            <div class="form-group"
                  ng-class="{'has-error': ($ctrl.errors[formField.name] || formField.error) && formField.type !== 'list'}"
                  ng-repeat="formField in $ctrl.items" ng-if="!formField.isBackRef && !formField.isHidden">
              <entaxy-form-field-extra-info class="col-sm-12"
                type="formField.ui.fieldExtraInfo.type" message="formField.ui.fieldExtraInfo.message"
                ng-if="formField.ui && formField.ui.fieldExtraInfo && formField.ui.fieldExtraInfo.displayOnMode === $ctrl.mode">
              </entaxy-form-field-extra-info>
              <div class="col-sm-4 label-col" ng-if="!formField.excludeLabel">
                <label class="control-label" ng-class="{'required-pf': formField.required}" for="{{formField.name}}">
                  {{formField.label}}
                </label>
                <button type="button" class="btn btn-link label-description-popover"
                        popover-placement="auto top-left" popover-trigger="'outsideClick'"
                        uib-popover-html="formField.description" ng-if="formField.description">
                  <span class="pficon pficon-help"></span>
                </button>
              </div>
              <div ng-class="{'col-sm-7': !formField.excludeLabel, 'col-sm-12': formField.excludeLabel}">
                <input type="{{formField.type}}" id="{{formField.name}}" placeholder="{{formField.placeholder}}"
                  ng-class="{'form-control': formField.type !== 'checkbox'}" ng-model="formField.value"
                  ng-readonly="formField.readOnly" ng-disabled="formField.type === 'checkbox' && formField.readOnly"
                  ng-if="$ctrl.isSimpleInput(formField)" ng-keydown="$ctrl.handleEnter($event)"
                  set-focused="$ctrl.setFocusOn === formField.name">
                <textarea id="{{formField.name}}" class="form-control" ng-model="formField.value"
                  ng-readonly="formField.readOnly" ng-if="$ctrl.isTextarea(formField)"
                  set-focused="$ctrl.setFocusOn === formField.name"></textarea>
                <entaxy-password-input id="{{formField.name}}" name="formField.name" model="formField.value"
                  confirmation-model="formField.confirmationValue" readonly="formField.readOnly"
                  ignore-confirmation-value="formField.ignoreConfirmationValue" errors="$ctrl.errors"
                  ng-if="$ctrl.isPassword(formField)"
                  set-focused="$ctrl.setFocusOn === formField.name"></entaxy-password-input>
                <entaxy-url-input id="{{formField.name}}" model="formField.value" config="formField.typeInfo"
                  readonly="formField.readOnly" ng-if="$ctrl.isUrl(formField)" form-controller="$ctrl.formController"
                  set-focused="$ctrl.setFocusOn === formField.name"></entaxy-url-input>
                <entaxy-select type="formField.type" id="{{formField.name}}" filter="formField.filter"
                  model="formField.value" options="formField.options" readonly="formField.readOnly"
                  update-parent-fn="$ctrl.updateFieldsAfterSelectionChangeFn"
                  update-parent="formField.typeInfo ? formField.typeInfo.updateParentFields : false"
                  creation-enabled="formField.typeInfo && formField.typeInfo.enablePrivateObjectCreation"
                  is-empty-included="formField.typeInfo ? formField.typeInfo.isEmptyIncluded : false"
                  ng-if="$ctrl.isEntaxySelect(formField)" form-controller="$ctrl.formController"></entaxy-select>
                <entaxy-select-from-enum id="{{formField.name}}" values="formField.typeInfo.values"
                  model="formField.value" readonly="formField.readOnly" multiple="formField.typeInfo.multiple"
                  is-empty-included="formField.typeInfo.isEmptyIncluded"
                  empty-option-name="formField.typeInfo.emptyOptionName" ng-if="$ctrl.isSelectFromEnum(formField)"
                  set-focused="$ctrl.setFocusOn === formField.name"></entaxy-select-from-enum>
                <entaxy-xml id="{{formField.name}}" ng-model="formField.value" mode="$ctrl.localMode"
                  ng-if="$ctrl.isXml(formField)" readonly="formField.readOnly"
                  form-controller="$ctrl.formController" set-focused="$ctrl.setFocusOn === formField.name"></entaxy-xml>
                <entaxy-list-input id="{{formField.name}}" items="formField.value" ng-if="$ctrl.isList(formField)"
                  creation-enabled="formField.typeInfo && formField.typeInfo.enablePrivateObjectCreation"
                  creation-types="formField.typeInfo ? formField.typeInfo.privateObjectTypes : undefined"
                  item-factory-filter="formField.itemFactoryFilter" mode="$ctrl.mode"
                  readonly="formField.readOnly" validation="formField.validation"
                  item-title-template="formField.typeInfo ? formField.typeInfo.itemTitle : undefined"
                  errors="$ctrl.errors[formField.name]" form-controller="$ctrl.formController"></entaxy-list-input>
                <entaxy-resource-input id="{{formField.name}}" name="{{formField.name}}" model="formField.value"
                  ng-if="$ctrl.isResourceInput(formField)"></entaxy-resource-input>
                <entaxy-inner-object-input id="{{formField.name}}" readonly="formField.readOnly"
                  model="formField.value" mode="$ctrl.mode" type="formField.type" form-controller="$ctrl.formController"
                  object-factory-filter="formField.objectFactoryFilter" field-name="formField.label"
                  ng-if="$ctrl.isInnerObjectInput(formField)"
                  set-focused="$ctrl.setFocusOn === formField.name"></entaxy-inner-object-input>
                <entaxy-map-input id="{{formField.name}}" model="formField.value" items="formField.mapItems"
                  duplicate-keys="formField.duplicateKeys" has-errors="formField.hasErrors" readonly="formField.readOnly"
                  ng-if="$ctrl.isMapInput(formField)" form-controller="$ctrl.formController"
                  set-focused="$ctrl.setFocusOn === formField.name"></entaxy-map-input>
                <span class="help-block" ng-show="$ctrl.errors[formField.name] && formField.type !== 'list'">
                  {{$ctrl.errors[formField.name]}}
                </span>
                <span class="help-block"
                        ng-show="formField.error && !$ctrl.errors[formField.name] && formField.type !== 'list'">
                  {{formField.error}}
                </span>
              </div>
              <div class="extra-actions" ng-class="{'col-sm-1': !formField.excludeLabel}"
                    ng-if="$ctrl.shouldShowReset(formField)">
                <span class="pficon pficon-history reset-button" data-toggle="tooltip" title="Reset"
                  ng-click="$ctrl.reset(formField)"></span>
              </div>
            </div>
        `,
        controller: entaxyFormFieldsController
    })
    .name;

    function entaxyFormFieldsController(entaxyService) {
        'ngInject';
        let ctrl = this;

        ctrl.$onInit = function() {
            ctrl.localMode = ctrl.mode === Entaxy.MODAL_MODES.ADD ? Entaxy.MODAL_MODES.EDIT : ctrl.mode;
        }

        const TYPES = {
            PASSWORD: 'password',
            ENUM: 'enum',
            LIST: 'list',
            URL: 'url',
            XML_ROUTE: 'xml:route',
            RESOURCE: 'resource',
            MAP: 'map'
        };

        ctrl.isSimpleInput = function (formField) {
            return !isRuntimeTyped(formField.type)
                && formField.type !== TYPES.PASSWORD
                && formField.type !== TYPES.LIST
                && formField.type !== TYPES.XML_ROUTE
                && formField.type !== TYPES.RESOURCE
                && formField.type !== TYPES.MAP
                && (!formField.typeInfo || (formField.typeInfo && formField.typeInfo.type === 'String'))
                && !formField.useTextarea;
        }

        ctrl.isTextarea = function (formField) {
            return formField.type === 'text' && formField.useTextarea;
        }

        ctrl.isPassword = function (formField) {
            return formField.type === TYPES.PASSWORD;
        }

        ctrl.isUrl = function (formField) {
            return formField.type === TYPES.URL && formField.typeInfo;
        }

        ctrl.isEntaxySelect = function (formField) {
            return isRuntimeTyped(formField.type) && !formField.innerObject;
        }

        ctrl.isInnerObjectInput = function (formField) {
            return isRuntimeTyped(formField.type) && formField.innerObject;
        }

        ctrl.isSelectFromEnum = function (formField) {
            return formField.typeInfo
                && (formField.typeInfo.type === TYPES.ENUM || formField.typeInfo.type === TYPES.LIST)
                && (formField.typeInfo.values || (!formField.typeInfo.values && formField.readOnly));
        }

        ctrl.isXml = function (formField) {
            return formField.type === TYPES.XML_ROUTE;
        }

        ctrl.isList = function (formField) {
            return formField.type === TYPES.LIST;
        }

        ctrl.isResourceInput = function (formField) {
            return formField.type === TYPES.RESOURCE;
        }

        ctrl.isMapInput = function (formField) {
            return formField.type === TYPES.MAP;
        }

        function isRuntimeTyped(formFieldType) {
            return formFieldType.startsWith(Entaxy.RUNTIME_TYPE_PREFIX) ||
                formFieldType.startsWith(Entaxy.RUNTIME_TYPE_SECURITY_PREFIX);
        }

        ctrl.handleEnter = function (event) {
            if (event.keyCode == 13) {
                event.preventDefault();
            }
        }

        ctrl.shouldShowReset = function (formField) {
            return ctrl.isXml(formField) && !formField.readOnly && formField.dependsOn;
        }

        ctrl.reset = function (formField) {
            let title = 'Confirm Reset';
            let message = 'Do you want to reset value of ' + formField.label + ' field to its default value?';

            entaxyService.openConfirmationWindow(title, message).then(() => {
                let definingFormFields = entaxyService.getDefiningFormFields([formField], ctrl.items);
                entaxyService.computeDependentFormFieldValue(formField, definingFormFields);
                setDirty();
            });
        }

        function setDirty() {
            if (ctrl.formController && !ctrl.formController.$dirty) {
                ctrl.formController.$setDirty();
            }
        }
    }
    entaxyFormFieldsController.$inject = ['entaxyService'];
})(Entaxy || (Entaxy = {}));
