import * as i0 from '@angular/core';
import { Directive, Input, EventEmitter, Component, Output, ContentChildren, ViewChild, NgModule } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import * as i2 from '@c8y/ngx-components';
import { gettext, Status, C8yStepper, CoreModule } from '@c8y/ngx-components';
import * as i1 from '@c8y/ngx-components/operations/bulk-operations-service';
import * as i6 from '@c8y/ngx-components/operations/create-bulk-operation-details';
import { CreateBulkOperationDetailsComponent, CreateBulkOperationDetailsModule } from '@c8y/ngx-components/operations/create-bulk-operation-details';
import { BULK_OPERATION_EVENT } from '@c8y/ngx-components/operations/product-experience';
import { get } from 'lodash-es';
import * as i3 from '@angular/common';
import * as i4 from '@angular/cdk/stepper';
import * as i5 from '@c8y/ngx-components/operations/device-selector';
import { DeviceSelectorModule } from '@c8y/ngx-components/operations/device-selector';
import * as i7 from '@c8y/ngx-components/operations/operation-summary';
import { OperationSummaryModule } from '@c8y/ngx-components/operations/operation-summary';

class CustomStep {
    constructor(templateRef) {
        this.templateRef = templateRef;
        this.buttonsDisabled = false;
        this.onNext = ({ stepper, step }) => {
            // steps without own `onNext` handler, e.g. preview steps need to mark themselves as `completed`,
            // otherwise stepper will not allow to move forth from them as soon as the user navigates back
            // and the `c8y-stepper-buttons` component marks the step as incomplete.
            step.completed = true;
            stepper.next();
        };
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: CustomStep, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.9", type: CustomStep, selector: "[customStep]", inputs: { label: ["customStep", "label"], completed: ["customStepCompleted", "completed"], buttonsDisabled: ["customStepButtonsDisabled", "buttonsDisabled"], onNext: ["customStepOnNext", "onNext"] }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: CustomStep, decorators: [{
            type: Directive,
            args: [{ selector: '[customStep]' }]
        }], ctorParameters: () => [{ type: i0.TemplateRef }], propDecorators: { label: [{
                type: Input,
                args: ['customStep']
            }], completed: [{
                type: Input,
                args: ['customStepCompleted']
            }], buttonsDisabled: [{
                type: Input,
                args: ['customStepButtonsDisabled']
            }], onNext: [{
                type: Input,
                args: ['customStepOnNext']
            }] } });

class BulkOperationStepper {
    constructor(bulkOperationService, modal, alert) {
        this.bulkOperationService = bulkOperationService;
        this.modal = modal;
        this.alert = alert;
        this.BULK_OPERATION_EVENT = BULK_OPERATION_EVENT;
        this.selectionChange = new EventEmitter();
        this.steps = [];
        this.showStepper = false;
        this.showButtons = false;
        this.stepperButtonsLabels = { custom: gettext('Schedule') };
        this.deviceTypesSubject$ = new Subject();
        this.endSubscriptions = new Subject();
        this.deviceTypes$ = this.deviceTypesSubject$.asObservable();
    }
    ngAfterViewInit() {
        setTimeout(() => {
            // wait for the next event loop turn as `steps` has already been checked in this CD cycle
            this.steps = this.customSteps.toArray();
            this.showStepper = true;
            setTimeout(() => {
                // postpone rendering of buttons for custom steps to the point where custom steps have already been rendered
                this.showButtons = true;
                if (this.stepper) {
                    this.stepper.selectionChange.pipe(takeUntil(this.endSubscriptions)).subscribe(event => {
                        this.selectionChange.next(event);
                    });
                    this.operationDetailsForm =
                        this.createBulkOperationDetailsComponent.fgOperationDescription;
                }
            });
        });
    }
    changeDeviceTypes(deviceTypes) {
        if (deviceTypes) {
            this.deviceTypesSubject$.next(Array.isArray(deviceTypes) ? deviceTypes : [deviceTypes]);
        }
        else {
            this.deviceTypesSubject$.next([]);
        }
    }
    async confirmDeviceSelection($event) {
        if (!this.deviceQueryString) {
            try {
                await this.modal.confirm(gettext('All devices selected'), gettext('You are about to schedule the bulk operation to be executed for all devices. Do you want to proceed?'), Status.WARNING, { ok: gettext('Schedule for all devices'), cancel: gettext('Cancel and select devices') });
                $event.step.completed = true;
                $event.stepper.next();
                this.operationDetails = this.retrieveOperationDetails
                    ? await this.retrieveOperationDetails()
                    : undefined;
            }
            catch (ex) {
                // Intentionally empty
            }
        }
        else {
            $event.step.completed = true;
            $event.stepper.next();
            this.operationDetails = this.retrieveOperationDetails
                ? await this.retrieveOperationDetails()
                : undefined;
        }
        this.bulkOperationType = this.bulkOperationService.retrieveBulkOperationType(get(this.operationDetails, 'prototype'));
        if (this.operationDetailsForm &&
            get(this.operationDetailsForm, 'controls.description.pristine') &&
            this.operationDetails) {
            this.operationDetailsForm.patchValue({
                description: get(this.operationDetails, 'prototype.description')
            });
        }
    }
    cancel() {
        this.close();
    }
    async scheduleBulkOperation() {
        this.pendingStatus = true;
        try {
            this.operationDetails.prototype.description = get(this.operationDetailsForm, 'controls.description.value');
            this.operationDetails.note = get(this.operationDetailsForm, 'controls.note.value');
            this.operationDetails.schedule = get(this.operationDetailsForm, 'controls.schedule.value');
            await this.bulkOperationService.scheduleBulkOperation(this.deviceQueryString, this.operationDetails);
            this.alert.success(gettext('New bulk operation scheduled.'));
            this.close();
        }
        catch (ex) {
            this.alert.addServerFailure(ex);
        }
        this.pendingStatus = false;
    }
    ngOnDestroy() {
        this.endSubscriptions.next();
        this.endSubscriptions.complete();
    }
    close() {
        this.stepper.reset();
        this.bulkOperationService.returnToBulkOperationOverview();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: BulkOperationStepper, deps: [{ token: i1.BulkOperationsService }, { token: i2.ModalService }, { token: i2.AlertService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: BulkOperationStepper, selector: "c8y-bulk-operation-stepper", inputs: { type: "type" }, outputs: { selectionChange: "selectionChange" }, queries: [{ propertyName: "customSteps", predicate: CustomStep }], viewQueries: [{ propertyName: "stepper", first: true, predicate: C8yStepper, descendants: true }, { propertyName: "createBulkOperationDetailsComponent", first: true, predicate: CreateBulkOperationDetailsComponent, descendants: true }], ngImport: i0, template: "<div class=\"fit-h\">\n  <c8y-stepper\n    class=\"d-col no-align-items fit-h c8y-stepper--no-btns a-i-center\"\n    linear\n    [disableDefaultIcons]=\"{ edit: true, done: false }\"\n    [customClasses]=\"['col-xs-10', 'col-sm-8', 'm-t-24', 'm-b-40', 'p-0', 'flex-no-shrink']\"\n    *ngIf=\"showStepper\"\n    c8yProductExperience\n    [actionName]=\"BULK_OPERATION_EVENT\"\n    [actionData]=\"{ bulkOperationType: type }\"\n  >\n    <!-- CUSTOM STEPS 1 to N-2 -->\n    <cdk-step\n      *ngFor=\"let step of steps\"\n      [label]=\"step.label | translate\"\n      [completed]=\"step.completed\"\n    >\n      <ng-container *ngTemplateOutlet=\"step.templateRef\"></ng-container>\n      <c8y-stepper-buttons\n        class=\"d-block card-footer p-24 separator fit-w sticky-bottom bg-level-0\"\n        *ngIf=\"showButtons\"\n        [disabled]=\"step.buttonsDisabled\"\n        (onNext)=\"step.onNext($event)\"\n        (onCancel)=\"cancel()\"\n      ></c8y-stepper-buttons>\n    </cdk-step>\n    <!-- STEP N-1 - Data-grid -->\n    <cdk-step [label]=\"'Filter target devices' | translate\">\n      <div class=\"card-block p-b-0 p-t-0 flex-no-shrink separator-bottom col-xs-12\">\n        <div class=\"d-flex j-c-center p-b-8 p-t-4\">\n          <div class=\"col-xs-12 col-sm-6\">\n            <h4 class=\"text-center text-normal m-b-16\">\n              {{ 'Filter target devices' | translate }}\n            </h4>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"col-xs-12 flex-grow no-gutter\">\n        <c8y-device-selector\n          [deviceTypes]=\"deviceTypes$\"\n          (onDeviceQueryStringChange)=\"deviceQueryString = $event\"\n        ></c8y-device-selector>\n      </div>\n      <c8y-stepper-buttons\n        class=\"d-block card-footer p-24 separator fit-w sticky-bottom bg-level-0\"\n        *ngIf=\"showButtons\"\n        (onNext)=\"confirmDeviceSelection($event)\"\n        (onCancel)=\"cancel()\"\n      ></c8y-stepper-buttons>\n    </cdk-step>\n\n    <!-- STEP N - Scheduler -->\n    <cdk-step [label]=\"'Confirm and schedule bulk operation' | translate\">\n      <div class=\"card-block flex-no-shrink p-b-0 p-t-0 separator-bottom col-xs-12\">\n        <div class=\"d-flex j-c-center p-b-8 p-t-4\">\n          <div class=\"col-xs-12 col-sm-6\">\n            <h4 class=\"text-center text-normal m-b-16\">\n              {{ 'Confirm and schedule bulk operation' | translate }}\n            </h4>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"col-xs-12 flex-grow no-gutter\">\n        <div class=\"card-inner-scroll fit-h\">\n          <div class=\"card-block p-b-0\">\n            <div class=\"d-flex j-c-center p-t-8 p-b-8\">\n              <div class=\"col-xs-12 col-sm-6\">\n                <c8y-operation-summary\n                  [name]=\"operationDetails?.name | translate\"\n                  [description]=\"operationDetails?.description | translate\"\n                  [deviceQueryString]=\"deviceQueryString\"\n                ></c8y-operation-summary>\n              </div>\n            </div>\n            <div class=\"d-flex j-c-center\">\n              <div class=\"col-xs-12 col-sm-6\">\n                <c8y-create-bulk-operation-details\n                  [bulkOperationType]=\"bulkOperationType\"\n                ></c8y-create-bulk-operation-details>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <c8y-stepper-buttons\n        class=\"d-block card-footer p-24 separator fit-w sticky-bottom bg-level-0\"\n        *ngIf=\"showButtons\"\n        [labels]=\"stepperButtonsLabels\"\n        [pending]=\"pendingStatus\"\n        [disabled]=\"operationDetailsForm?.invalid\"\n        (onCancel)=\"cancel()\"\n        (onCustom)=\"scheduleBulkOperation()\"\n      ></c8y-stepper-buttons>\n    </cdk-step>\n  </c8y-stepper>\n</div>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2.C8yStepper, selector: "c8y-stepper", inputs: ["disableDefaultIcons", "disableProgressButtons", "customClasses", "hideStepProgress", "useStepLabelsAsTitlesOnly"], outputs: ["onStepChange"] }, { kind: "component", type: i4.CdkStep, selector: "cdk-step", inputs: ["stepControl", "label", "errorMessage", "aria-label", "aria-labelledby", "state", "editable", "optional", "completed", "hasError"], outputs: ["interacted"], exportAs: ["cdkStep"] }, { kind: "component", type: i2.C8yStepperButtons, selector: "c8y-stepper-buttons", inputs: ["labels", "pending", "disabled", "showButtons"], outputs: ["onCancel", "onNext", "onBack", "onCustom"] }, { kind: "directive", type: i2.ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "component", type: i5.DeviceSelectorComponent, selector: "c8y-device-selector", inputs: ["deviceTypes"], outputs: ["onDeviceQueryStringChange"] }, { kind: "component", type: i6.CreateBulkOperationDetailsComponent, selector: "c8y-create-bulk-operation-details", inputs: ["bulkOperationType"] }, { kind: "component", type: i7.OperationSummaryComponent, selector: "c8y-operation-summary", inputs: ["name", "description", "deviceQueryString"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: BulkOperationStepper, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-bulk-operation-stepper', template: "<div class=\"fit-h\">\n  <c8y-stepper\n    class=\"d-col no-align-items fit-h c8y-stepper--no-btns a-i-center\"\n    linear\n    [disableDefaultIcons]=\"{ edit: true, done: false }\"\n    [customClasses]=\"['col-xs-10', 'col-sm-8', 'm-t-24', 'm-b-40', 'p-0', 'flex-no-shrink']\"\n    *ngIf=\"showStepper\"\n    c8yProductExperience\n    [actionName]=\"BULK_OPERATION_EVENT\"\n    [actionData]=\"{ bulkOperationType: type }\"\n  >\n    <!-- CUSTOM STEPS 1 to N-2 -->\n    <cdk-step\n      *ngFor=\"let step of steps\"\n      [label]=\"step.label | translate\"\n      [completed]=\"step.completed\"\n    >\n      <ng-container *ngTemplateOutlet=\"step.templateRef\"></ng-container>\n      <c8y-stepper-buttons\n        class=\"d-block card-footer p-24 separator fit-w sticky-bottom bg-level-0\"\n        *ngIf=\"showButtons\"\n        [disabled]=\"step.buttonsDisabled\"\n        (onNext)=\"step.onNext($event)\"\n        (onCancel)=\"cancel()\"\n      ></c8y-stepper-buttons>\n    </cdk-step>\n    <!-- STEP N-1 - Data-grid -->\n    <cdk-step [label]=\"'Filter target devices' | translate\">\n      <div class=\"card-block p-b-0 p-t-0 flex-no-shrink separator-bottom col-xs-12\">\n        <div class=\"d-flex j-c-center p-b-8 p-t-4\">\n          <div class=\"col-xs-12 col-sm-6\">\n            <h4 class=\"text-center text-normal m-b-16\">\n              {{ 'Filter target devices' | translate }}\n            </h4>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"col-xs-12 flex-grow no-gutter\">\n        <c8y-device-selector\n          [deviceTypes]=\"deviceTypes$\"\n          (onDeviceQueryStringChange)=\"deviceQueryString = $event\"\n        ></c8y-device-selector>\n      </div>\n      <c8y-stepper-buttons\n        class=\"d-block card-footer p-24 separator fit-w sticky-bottom bg-level-0\"\n        *ngIf=\"showButtons\"\n        (onNext)=\"confirmDeviceSelection($event)\"\n        (onCancel)=\"cancel()\"\n      ></c8y-stepper-buttons>\n    </cdk-step>\n\n    <!-- STEP N - Scheduler -->\n    <cdk-step [label]=\"'Confirm and schedule bulk operation' | translate\">\n      <div class=\"card-block flex-no-shrink p-b-0 p-t-0 separator-bottom col-xs-12\">\n        <div class=\"d-flex j-c-center p-b-8 p-t-4\">\n          <div class=\"col-xs-12 col-sm-6\">\n            <h4 class=\"text-center text-normal m-b-16\">\n              {{ 'Confirm and schedule bulk operation' | translate }}\n            </h4>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"col-xs-12 flex-grow no-gutter\">\n        <div class=\"card-inner-scroll fit-h\">\n          <div class=\"card-block p-b-0\">\n            <div class=\"d-flex j-c-center p-t-8 p-b-8\">\n              <div class=\"col-xs-12 col-sm-6\">\n                <c8y-operation-summary\n                  [name]=\"operationDetails?.name | translate\"\n                  [description]=\"operationDetails?.description | translate\"\n                  [deviceQueryString]=\"deviceQueryString\"\n                ></c8y-operation-summary>\n              </div>\n            </div>\n            <div class=\"d-flex j-c-center\">\n              <div class=\"col-xs-12 col-sm-6\">\n                <c8y-create-bulk-operation-details\n                  [bulkOperationType]=\"bulkOperationType\"\n                ></c8y-create-bulk-operation-details>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <c8y-stepper-buttons\n        class=\"d-block card-footer p-24 separator fit-w sticky-bottom bg-level-0\"\n        *ngIf=\"showButtons\"\n        [labels]=\"stepperButtonsLabels\"\n        [pending]=\"pendingStatus\"\n        [disabled]=\"operationDetailsForm?.invalid\"\n        (onCancel)=\"cancel()\"\n        (onCustom)=\"scheduleBulkOperation()\"\n      ></c8y-stepper-buttons>\n    </cdk-step>\n  </c8y-stepper>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1.BulkOperationsService }, { type: i2.ModalService }, { type: i2.AlertService }], propDecorators: { type: [{
                type: Input
            }], selectionChange: [{
                type: Output
            }], customSteps: [{
                type: ContentChildren,
                args: [CustomStep]
            }], stepper: [{
                type: ViewChild,
                args: [C8yStepper, { static: false }]
            }], createBulkOperationDetailsComponent: [{
                type: ViewChild,
                args: [CreateBulkOperationDetailsComponent, { static: false }]
            }] } });

class BaseStepperComponent {
    constructor() {
        /**
         * A map holding step data. The order of properties need to match the order of
         * the steps they hold data for as the index of the property is used to clear
         * step data when navigating forth after changing data at an earlier step.
         */
        this.stepData = {};
        this.endSubscriptions = new Subject();
    }
    set deviceTypes(deviceTypes) {
        if (this.operationStepper) {
            this.operationStepper.changeDeviceTypes(deviceTypes);
        }
    }
    ngOnInit() {
        this.operationStepper.retrieveOperationDetails = this.retrieveOperationPrototype.bind(this);
        this.operationStepper.selectionChange
            .pipe(takeUntil(this.endSubscriptions))
            .subscribe(this.onSelectionChange.bind(this));
    }
    ngOnDestroy() {
        this.endSubscriptions.next();
        this.endSubscriptions.complete();
    }
    onSelectionChange(event) {
        const { selectedIndex, previouslySelectedIndex } = event;
        if (selectedIndex > previouslySelectedIndex &&
            selectedIndex < Object.keys(this.stepData).length) {
            // TODO clear step data only if previous step is "dirty"
            this.stepData[this.getStepDataKeyByIndex(selectedIndex)] = undefined;
        }
    }
    getStepDataKeyByIndex(index) {
        return Object.keys(this.stepData)[index];
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: BaseStepperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: BaseStepperComponent, selector: "c8y-base-stepper", viewQueries: [{ propertyName: "operationStepper", first: true, predicate: BulkOperationStepper, descendants: true, static: true }], ngImport: i0, template: '', isInline: true }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: BaseStepperComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'c8y-base-stepper',
                    template: ''
                }]
        }], propDecorators: { operationStepper: [{
                type: ViewChild,
                args: [BulkOperationStepper, { static: true }]
            }] } });

/**
 * This module provides base stepper class and stepper wrapper component.
 */
class BulkOperationStepperModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: BulkOperationStepperModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.9", ngImport: i0, type: BulkOperationStepperModule, declarations: [BulkOperationStepper, CustomStep], imports: [CoreModule,
            DeviceSelectorModule,
            CreateBulkOperationDetailsModule,
            OperationSummaryModule], exports: [BulkOperationStepper, CustomStep] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: BulkOperationStepperModule, imports: [CoreModule,
            DeviceSelectorModule,
            CreateBulkOperationDetailsModule,
            OperationSummaryModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: BulkOperationStepperModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [
                        CoreModule,
                        DeviceSelectorModule,
                        CreateBulkOperationDetailsModule,
                        OperationSummaryModule
                    ],
                    declarations: [BulkOperationStepper, CustomStep],
                    exports: [BulkOperationStepper, CustomStep]
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { BaseStepperComponent, BulkOperationStepper, BulkOperationStepperModule, CustomStep };
//# sourceMappingURL=c8y-ngx-components-operations-bulk-operation-stepper.mjs.map
