import { Component, EventEmitter, ElementRef, Input, Output, ChangeDetectionStrategy } from '@angular/core';
import { FormControl, Validators, FormBuilder } from '@angular/forms';
import { RULE_UPDATE_ENABLED_STATE, RULE_UPDATE_NAME, RULE_DELETE, RULE_RULE_ACTION_UPDATE_TYPE, RULE_RULE_ACTION_UPDATE_PARAMETER, V_RULE_UPDATE_EXPANDED_STATE, RULE_CONDITION_UPDATE_PARAMETER, RULE_CONDITION_UPDATE_OPERATOR, RULE_CONDITION_UPDATE_TYPE, RULE_RULE_ACTION_DELETE, RULE_RULE_ACTION_CREATE, RULE_CONDITION_GROUP_CREATE, RuleService } from './services/Rule';
import { I18nService } from './services/system/locale/I18n';
import { UserModel } from 'dotcms-js/dotcms-js';
import { ApiRoot } from 'dotcms-js/dotcms-js';
import { LoggerService } from 'dotcms-js/dotcms-js';
var I8N_BASE = 'api.sites.ruleengine';
// tslint:disable-next-line:no-unused-variable
var rsrc = {
    fireOn: {
        EVERY_PAGE: 'Every Page',
        EVERY_REQUEST: 'Every Request',
        ONCE_PER_VISIT: 'Once per visit',
        ONCE_PER_VISITOR: 'Once per visitor'
    }
};
var RuleComponent = (function () {
    function RuleComponent(_user, elementRef, resources, ruleService, apiRoot, fb, loggerService) {
        var _this = this;
        this._user = _user;
        this.elementRef = elementRef;
        this.resources = resources;
        this.ruleService = ruleService;
        this.apiRoot = apiRoot;
        this.loggerService = loggerService;
        this.ruleActionTypes = {};
        this.hidden = false;
        this.deleteRule = new EventEmitter(false);
        this.updateExpandedState = new EventEmitter(false);
        this.updateName = new EventEmitter(false);
        this.updateEnabledState = new EventEmitter(false);
        this.updateFireOn = new EventEmitter(false);
        this.createRuleAction = new EventEmitter(false);
        this.updateRuleActionType = new EventEmitter(false);
        this.updateRuleActionParameter = new EventEmitter(false);
        this.deleteRuleAction = new EventEmitter(false);
        this.updateConditionGroupOperator = new EventEmitter(false);
        this.createConditionGroup = new EventEmitter(false);
        this.createCondition = new EventEmitter(false);
        this.deleteCondition = new EventEmitter(false);
        this.updateConditionType = new EventEmitter(false);
        this.updateConditionParameter = new EventEmitter(false);
        this.updateConditionOperator = new EventEmitter(false);
        this._updateEnabledStateDelay = new EventEmitter(false);
        // tslint:disable-next-line:no-unused-variable
        this.showMoreMenu = false;
        // tslint:disable-next-line:no-unused-variable
        this.showAddToBundleDialog = false;
        // tslint:disable-next-line:no-unused-variable
        this.showPushPublishDialog = false;
        this.actionTypePlaceholder = '';
        this.conditionTypePlaceholder = '';
        this._rsrcCache = {};
        this.hideFireOn = apiRoot.hideFireOn;
        /* Need to delay the firing of the state change toggle, to give any blur events time to fire. */
        this._updateEnabledStateDelay.debounceTime(20).subscribe(function (event) {
            _this.updateEnabledState.emit(event);
        });
        this.fireOn = {
            options: [
                { label: this.rsrc('inputs.fireOn.options.EveryPage'), value: 'EVERY_PAGE' },
                { label: this.rsrc('inputs.fireOn.options.OncePerVisit'), value: 'ONCE_PER_VISIT' },
                {
                    label: this.rsrc('inputs.fireOn.options.OncePerVisitor'),
                    value: 'ONCE_PER_VISITOR'
                },
                { label: this.rsrc('inputs.fireOn.options.EveryRequest'), value: 'EVERY_REQUEST' }
            ],
            placeholder: this.rsrc('inputs.fireOn.placeholder', 'Select One'),
            value: 'EVERY_PAGE'
        };
        this.initFormModel(fb);
        this.resources
            .get('api.sites.ruleengine.rules.inputs.action.type.placeholder')
            .subscribe(function (label) {
            _this.actionTypePlaceholder = label;
        });
        this.resources
            .get('api.sites.ruleengine.rules.inputs.condition.type.placeholder')
            .subscribe(function (label) {
            _this.conditionTypePlaceholder = label;
        });
    }
    RuleComponent.prototype.initFormModel = function (fb) {
        var vFns = [];
        vFns.push(Validators.required);
        vFns.push(Validators.minLength(3));
        this.formModel = fb.group({
            name: new FormControl(this.rule ? this.rule.name : '', Validators.compose(vFns))
        });
    };
    RuleComponent.prototype.rsrc = function (subkey, defVal) {
        if (defVal === void 0) { defVal = '-missing-'; }
        var msgObserver = this._rsrcCache[subkey];
        if (!msgObserver) {
            msgObserver = this.resources.get(I8N_BASE + '.rules.' + subkey, defVal);
            this._rsrcCache[subkey] = msgObserver;
        }
        return msgObserver;
    };
    RuleComponent.prototype.ngOnChanges = function (change) {
        var _this = this;
        if (change.rule) {
            var rule = this.rule;
            var ctrl_1 = this.formModel.controls['name'];
            ctrl_1.patchValue(this.rule.name, {});
            ctrl_1.valueChanges.debounceTime(250).subscribe(function (name) {
                if (ctrl_1.valid) {
                    _this.updateName.emit({
                        payload: { rule: _this.rule, value: name },
                        type: RULE_UPDATE_NAME
                    });
                }
            });
            if (rule.isPersisted()) {
                this.fireOn.value = rule.fireOn;
            }
        }
    };
    RuleComponent.prototype.statusText = function (length) {
        if (length === void 0) { length = 0; }
        var t = '';
        if (this.saved) {
            t = 'All changes saved';
        }
        else if (this.saving) {
            t = 'Saving...';
        }
        else if (this.errors) {
            t = this.errors['invalid'] || this.errors['serverError'] || 'Unsaved changes...';
        }
        if (length) {
            t = t.substring(0, length) + '...';
        }
        return t;
    };
    RuleComponent.prototype.setRuleExpandedState = function (expanded) {
        this.updateExpandedState.emit({
            payload: { rule: this.rule, value: expanded },
            type: V_RULE_UPDATE_EXPANDED_STATE
        });
    };
    RuleComponent.prototype.setRuleEnabledState = function (enabled) {
        this._updateEnabledStateDelay.emit({
            payload: { rule: this.rule, value: enabled },
            type: RULE_UPDATE_ENABLED_STATE
        });
    };
    RuleComponent.prototype.onCreateRuleAction = function () {
        this.loggerService.info('RuleComponent', 'onCreateRuleAction');
        this.createRuleAction.emit({ payload: { rule: this.rule }, type: RULE_RULE_ACTION_CREATE });
    };
    RuleComponent.prototype.onDeleteCondition = function (event, conditionGroup) {
        Object.assign(event.payload, { conditionGroup: conditionGroup, rule: this.rule });
        this.deleteCondition.emit(event);
    };
    RuleComponent.prototype.onCreateConditionGroupClicked = function () {
        var len = this.rule._conditionGroups.length;
        var priority = len ? this.rule._conditionGroups[len - 1].priority : 1;
        this.createConditionGroup.emit({
            payload: { rule: this.rule, priority: priority },
            type: RULE_CONDITION_GROUP_CREATE
        });
    };
    RuleComponent.prototype.onCreateCondition = function (event) {
        this.loggerService.info('RuleComponent', 'onCreateCondition');
        Object.assign(event.payload, { rule: this.rule });
        this.createCondition.emit(event);
    };
    RuleComponent.prototype.onUpdateRuleActionType = function (event) {
        this.loggerService.info('RuleComponent', 'onUpdateRuleActionType');
        this.updateRuleActionType.emit({
            payload: Object.assign({ rule: this.rule }, event.payload),
            type: RULE_RULE_ACTION_UPDATE_TYPE
        });
    };
    RuleComponent.prototype.onUpdateRuleActionParameter = function (event) {
        this.loggerService.info('RuleComponent', 'onUpdateRuleActionParameter');
        this.updateRuleActionParameter.emit({
            payload: Object.assign({ rule: this.rule }, event.payload),
            type: RULE_RULE_ACTION_UPDATE_PARAMETER
        });
    };
    RuleComponent.prototype.onDeleteRuleAction = function (event) {
        this.loggerService.info('RuleComponent', 'onDeleteRuleAction');
        this.deleteRuleAction.emit({
            payload: Object.assign({ rule: this.rule }, event.payload),
            type: RULE_RULE_ACTION_DELETE
        });
    };
    RuleComponent.prototype.onUpdateConditionGroupOperator = function (event, conditionGroup) {
        this.updateConditionGroupOperator.emit({
            payload: Object.assign({ conditionGroup: conditionGroup, rule: this.rule }, event.payload),
            type: RULE_CONDITION_UPDATE_TYPE
        });
    };
    RuleComponent.prototype.onUpdateConditionType = function (event, conditionGroup) {
        this.loggerService.info('RuleComponent', 'onUpdateConditionType');
        this.updateConditionType.emit({
            payload: Object.assign({ conditionGroup: conditionGroup, rule: this.rule }, event.payload),
            type: RULE_CONDITION_UPDATE_TYPE
        });
    };
    RuleComponent.prototype.onUpdateConditionParameter = function (event, conditionGroup) {
        this.loggerService.info('RuleComponent', 'onUpdateConditionParameter');
        this.updateConditionParameter.emit({
            payload: Object.assign({ conditionGroup: conditionGroup, rule: this.rule }, event.payload),
            type: RULE_CONDITION_UPDATE_PARAMETER
        });
    };
    RuleComponent.prototype.onUpdateConditionOperator = function (event, conditionGroup) {
        this.loggerService.info('RuleComponent', 'onUpdateConditionOperator');
        this.updateConditionOperator.emit({
            payload: Object.assign({ conditionGroup: conditionGroup, rule: this.rule }, event.payload),
            type: RULE_CONDITION_UPDATE_OPERATOR
        });
    };
    RuleComponent.prototype.deleteRuleClicked = function (event) {
        event.stopPropagation();
        var noWarn = this._user.suppressAlerts || (event.altKey && event.shiftKey);
        if (!noWarn) {
            noWarn = this.ruleActions.length === 1 && !this.ruleActions[0].isPersisted();
            noWarn = noWarn && this.rule._conditionGroups.length === 1;
            if (noWarn) {
                var conditions = this.rule._conditionGroups[0].conditions;
                var keys = Object.keys(conditions);
                noWarn = noWarn && keys.length === 0;
            }
        }
        if (noWarn || confirm('Are you sure you want delete this rule?')) {
            this.deleteRule.emit({ payload: { rule: this.rule }, type: RULE_DELETE });
        }
    };
    return RuleComponent;
}());
RuleComponent.decorators = [
    { type: Component, args: [{
                changeDetection: ChangeDetectionStrategy.Default,
                selector: 'rule',
                template: "<form [formGroup]=\"formModel\" let rf=\"ngForm\">\n  <cw-add-to-bundle-dialog-container\n      [assetId]=\"rule.id || rule.key\"\n      [hidden]=\"!showAddToBundleDialog\"\n      (close)=\"showAddToBundleDialog = false; showMoreMenu = false\"></cw-add-to-bundle-dialog-container>\n  <cw-push-publish-dialog-container\n      [environmentStores]=\"environmentStores\"\n      [assetId]=\"rule.id || rule.key\"\n      [hidden]=\"!showPushPublishDialog\"\n      (close)=\"showPushPublishDialog = false; showMoreMenu = false\"></cw-push-publish-dialog-container>\n  <div class=\"cw-rule\" [class.cw-hidden]=\"hidden\" [class.cw-disabled]=\"!rule.enabled\"\n    [class.cw-saving]=\"saving\" [class.cw-saved]=\"saved\" [class.cw-out-of-sync]=\"!saved && !saving\">\n  <div flex layout=\"row\" class=\"cw-header\" *ngIf=\"!hidden\" (click)=\"setRuleExpandedState(!rule._expanded)\">\n    <div flex=\"70\" layout=\"row\" layout-align=\"start center\" class=\"cw-header-info\" >\n      <i flex=\"none\" class=\"caret icon cw-rule-caret large\" [class.right]=\"!rule._expanded\" [class.down]=\"rule._expanded\" aria-hidden=\"true\"></i>\n      <div flex=\"70\" layout=\"column\">\n      <cw-input-text class=\"cw-rule-name-input\"\n                     focused=\"{{rule.key == null}}\"\n                     placeholder=\"{{rsrc('inputs.name.placeholder') | async}}\"\n                     formControlName=\"name\"\n                     (click)=\"$event.stopPropagation()\">\n      </cw-input-text>\n      <div flex=\"50\" [hidden]=\"!formModel.controls['name'].touched || formModel.controls['name'].valid\"\n        class=\"name cw-warn basic label\">Name is required\n      </div>\n      </div>\n      <span class=\"cw-fire-on-label\" *ngIf=\"!hideFireOn\">{{rsrc('inputs.fireOn.label') | async}}</span>\n      <cw-input-dropdown flex=\"none\"\n                         *ngIf=\"!hideFireOn\"\n                         class=\"cw-fire-on-dropdown\"\n                         [value]=\"fireOn.value\"\n                         placeholder=\"{{fireOn.placeholder | async}}\"\n                         (onDropDownChange)=\"updateFireOn.emit({type: 'RULE_UPDATE_FIRE_ON', payload:{rule:rule, value:$event}})\"\n                         (click)=\"$event.stopPropagation()\">\n        <cw-input-option *ngFor=\"let opt of fireOn.options\"\n            [value]=\"opt.value\"\n            [label]=\"opt.label | async\"\n            icon=\"{{opt.icon}}\"></cw-input-option>\n      </cw-input-dropdown>\n    </div>\n    <div flex=\"30\" layout=\"row\" layout-align=\"end center\" class=\"cw-header-actions\" >\n      <span class=\"cw-rule-status-text\" title=\"{{statusText()}}\">{{statusText(30)}}</span>\n      <cw-toggle-input class=\"cw-input\"\n                       [disabled]=\"!saved\"\n                       [value]=\"rule.enabled\"\n                       (change)=\"setRuleEnabledState($event)\"\n                       (click)=\"$event.stopPropagation()\">\n      </cw-toggle-input>\n      <div class=\"cw-btn-group\">\n        <div class=\"ui basic icon buttons\">\n          <button class=\"ui button cw-delete-rule\" aria-label=\"More Actions\" (click)=\"showMoreMenu = !showMoreMenu; $event.stopPropagation()\">\n            <i class=\"ellipsis vertical icon\"></i>\n          </button>\n          <button class=\"ui button cw-add-group\" arial-label=\"Add Group\"\n            (click)=\"onCreateConditionGroupClicked(); setRuleExpandedState(true); $event.stopPropagation()\" [disabled]=\"!rule.isPersisted()\">\n\n            <i class=\"plus icon\" aria-hidden=\"true\"></i>\n          </button>\n        </div>\n      </div>\n      <div class=\"ui vertical menu\" *ngIf=\"showMoreMenu\">\n        <a class=\"item\" *ngIf=\"(rule.id || rule.key) &&  !apiRoot.hideRulePushOptions\"\n          (click)=\"showAddToBundleDialog = true; $event.stopPropagation()\">Add to bundle</a>\n\n        <a class=\"item\" *ngIf=\"environmentStores.length > 0 && (rule.id || rule.key) &&  !apiRoot.hideRulePushOptions\"\n          (click)=\"showPushPublishDialog = true; $event.stopPropagation()\">Push Publish</a>\n        <a class=\"item\" (click)=\"deleteRuleClicked($event)\">Delete rule</a>\n      </div>\n    </div>\n  </div>\n  <div class=\"cw-accordion-body\" *ngIf=\"rule._expanded\">\n    <condition-group *ngFor=\"let group of rule._conditionGroups; let i=index\"\n                     [group]=\"group\"\n                     [conditionTypes]=\"conditionTypes\"\n                     [groupIndex]=\"i\"\n                     [conditionTypePlaceholder]=\"conditionTypePlaceholder\"\n                     (createCondition)=\"onCreateCondition($event)\"\n                     (deleteCondition)=\"onDeleteCondition($event, group)\"\n                     (updateConditionGroupOperator)=\"onUpdateConditionGroupOperator($event, group)\"\n                     (updateConditionType)=\"onUpdateConditionType($event, group)\"\n                     (updateConditionParameter)=\"onUpdateConditionParameter($event, group)\"\n                     (updateConditionOperator)=\"onUpdateConditionOperator($event, group)\"\n                     ></condition-group>\n    <div class=\"cw-action-group\">\n      <div class=\"cw-action-separator\">\n        {{rsrc('inputs.action.firesActions') | async}}\n      </div>\n      <div flex layout=\"column\" class=\"cw-rule-actions\">\n        <div layout=\"row\" class=\"cw-action-row\" *ngFor=\"let ruleAction of ruleActions; let i=index\">\n          <rule-action flex layout=\"row\" [action]=\"ruleAction\" [index]=\"i\"\n              [actionTypePlaceholder]=\"actionTypePlaceholder\"\n              [ruleActionTypes]=\"ruleActionTypes\"\n              (updateRuleActionType)=\"onUpdateRuleActionType($event)\"\n               (updateRuleActionParameter)=\"onUpdateRuleActionParameter($event)\"\n              (deleteRuleAction)=\"onDeleteRuleAction($event)\"></rule-action>\n          <div class=\"cw-btn-group cw-add-btn\">\n            <div class=\"ui basic icon buttons\" *ngIf=\"i === (ruleActions.length - 1)\">\n              <button class=\"cw-button-add-item ui button\" arial-label=\"Add Action\"\n                (click)=\"onCreateRuleAction();\" [disabled]=\"!ruleAction.isPersisted()\">\n                <i class=\"plus icon\" aria-hidden=\"true\"></i>\n              </button>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n</form>\n"
            },] },
];
/** @nocollapse */
RuleComponent.ctorParameters = function () { return [
    { type: UserModel, },
    { type: ElementRef, },
    { type: I18nService, },
    { type: RuleService, },
    { type: ApiRoot, },
    { type: FormBuilder, },
    { type: LoggerService, },
]; };
RuleComponent.propDecorators = {
    'rule': [{ type: Input },],
    'saved': [{ type: Input },],
    'saving': [{ type: Input },],
    'errors': [{ type: Input },],
    'ruleActions': [{ type: Input },],
    'ruleActionTypes': [{ type: Input },],
    'conditionTypes': [{ type: Input },],
    'environmentStores': [{ type: Input },],
    'hidden': [{ type: Input },],
    'deleteRule': [{ type: Output },],
    'updateExpandedState': [{ type: Output },],
    'updateName': [{ type: Output },],
    'updateEnabledState': [{ type: Output },],
    'updateFireOn': [{ type: Output },],
    'createRuleAction': [{ type: Output },],
    'updateRuleActionType': [{ type: Output },],
    'updateRuleActionParameter': [{ type: Output },],
    'deleteRuleAction': [{ type: Output },],
    'updateConditionGroupOperator': [{ type: Output },],
    'createConditionGroup': [{ type: Output },],
    'createCondition': [{ type: Output },],
    'deleteCondition': [{ type: Output },],
    'updateConditionType': [{ type: Output },],
    'updateConditionParameter': [{ type: Output },],
    'updateConditionOperator': [{ type: Output },],
};
export { RuleComponent };
//# sourceMappingURL=rule-component.js.map