import { __decorate } from "tslib";
import { Component, EventEmitter, Output, ViewChildren } from '@angular/core';
import { gettext, ListItemRadioComponent, memoize } from '@c8y/ngx-components';
import { RepositoryService, RepositoryType } from '@c8y/ngx-components/repository';
import { TranslateService } from '@ngx-translate/core';
import { get, isEqual, property, uniqWith } from 'lodash-es';
import { BehaviorSubject, combineLatest, from } from 'rxjs';
import { debounceTime, distinctUntilChanged, shareReplay, switchMap } from 'rxjs/operators';
export class SelectSoftwareStepComponent {
    constructor(repositoryService, translate) {
        this.repositoryService = repositoryService;
        this.translate = translate;
        this.software = new EventEmitter();
        this.textFilter$ = new BehaviorSubject('');
        this.deviceType$ = new BehaviorSubject('');
        this.deviceTypes = [];
        this.selectedDeviceType = { name: '' };
        this.isLegacy = this.repositoryService.isLegacyEntry.bind(this.repositoryService);
        this.software$ = combineLatest(this.textFilter$, this.deviceType$).pipe(switchMap(([name, deviceType]) => this.getSoftware(name, deviceType)), shareReplay(1));
        this.NO_DEVICE_TYPE_AVAILABLE = gettext('No device type available');
        this.loadDeviceTypes();
    }
    getBaseVersionsCount$(software) {
        return this.repositoryService.getBaseVersionsCount$(software).pipe(shareReplay(1));
    }
    getVersions(software) {
        return this.repositoryService.listAllVersions(software);
    }
    getDeviceTypeTitle(software) {
        return get(software, 'c8y_Filter.type', this.translate.instant(this.NO_DEVICE_TYPE_AVAILABLE));
    }
    loadDeviceTypes() {
        this.deviceTypeSubscription = this.deviceType$
            .pipe(debounceTime(300), distinctUntilChanged(), switchMap(searchStr => {
            const query = { 'c8y_Filter.type': `*${searchStr}*` };
            return from(this.repositoryService.listRepositoryEntries(RepositoryType.SOFTWARE, { query }));
        }))
            .subscribe(result => {
            const { data } = result;
            this.deviceTypes = uniqWith(data.map(val => ({ name: val.c8y_Filter.type })), isEqual);
        });
    }
    ngOnDestroy() {
        this.deviceTypeSubscription.unsubscribe();
    }
    resetSelection() {
        this.radioButtons.map(radio => radio.reset());
    }
    selectSoftware({ option, software }) {
        software.selectedId = option.id;
        option.action = 'install';
        this.emitSoftware({ option, software });
    }
    emitSoftware({ option, software }) {
        const emitData = Object.assign({}, { software }, { version: option }, { action: option.action });
        this.software.emit(emitData);
    }
    getSoftware(name, deviceType) {
        const query = name ? { name: `*${name}*` } : {};
        if (deviceType) {
            query.__or = [{ 'c8y_Filter.type': deviceType }, { __not: { __has: `c8y_Filter.type` } }];
        }
        return this.repositoryService.listRepositoryEntries(RepositoryType.SOFTWARE, { query });
    }
}
SelectSoftwareStepComponent.decorators = [
    { type: Component, args: [{
                selector: 'c8y-select-software-step',
                template: "<div class=\"card-block p-t-0 overflow-visible flex-no-shrink separator-bottom col-xs-12\">\n  <div class=\"row p-b-16\">\n    <div class=\"col-md-8 col-md-offset-2 col-lg-6 col-lg-offset-3\">\n      <h4 class=\"text-center m-b-16\">{{ 'Select software' | translate }}</h4>\n      <div class=\"row\">\n        <div class=\"col-md-6\">\n          <div class=\"input-group input-group-search\">\n            <input\n              type=\"search\"\n              class=\"form-control\"\n              title=\"{{ 'Filter software\u2026' | translate }}\"\n              placeholder=\"{{ 'Filter software\u2026' | translate }}\"\n              [ngModel]=\"textFilter$ | async\"\n              (ngModelChange)=\"textFilter$.next($event)\"\n            />\n            <span class=\"input-group-addon\">\n              <i c8yIcon=\"filter\" *ngIf=\"(textFilter$ | async).length === 0\"></i>\n              <i\n                c8yIcon=\"times\"\n                class=\"text-muted\"\n                *ngIf=\"(textFilter$ | async).length > 0\"\n                (click)=\"textFilter$.next('')\"\n              ></i>\n            </span>\n          </div>\n        </div>\n        <div class=\"col-xs-12 p-b-8 visible-xs visible-sm\"></div>\n        <div class=\"col-md-6\">\n          <c8y-form-group class=\"m-0\">\n            <c8y-typeahead\n              name=\"deviceType\"\n              [(ngModel)]=\"selectedDeviceType\"\n              placeholder=\"{{ 'Type to filter device types\u2026' | translate }}\"\n              (onSearch)=\"deviceType$.next($event)\"\n              [allowFreeEntries]=\"false\"\n            >\n              <c8y-li\n                class=\"p-l-8 p-r-8 c8y-list__item--link\"\n                (click)=\"selectedDeviceType = {name: ''}; deviceType$.next('')\"\n              >\n                <span>{{'All device types' | translate }}</span>\n              </c8y-li>\n              <c8y-li\n              *ngFor=\"let deviceType of deviceTypes\"\n              class=\"p-l-8 p-r-8 c8y-list__item--link\"\n              (click)=\"selectedDeviceType = deviceType; deviceType$.next(deviceType.name)\"\n              [active]=\"selectedDeviceType === deviceType\"\n              >\n              <c8y-highlight\n              [text]=\"deviceType.name\"\n              [pattern]=\"deviceType$ | async\"\n              ></c8y-highlight>\n              </c8y-li>\n            </c8y-typeahead>\n            <c8y-messages\n            ><c8y-message\n              name=\"notExisting\"\n              [text]=\"'Select one of the existing device types.' | translate\"\n            ></c8y-message>\n            </c8y-messages>\n          </c8y-form-group>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n<div class=\"col-xs-12 flex-grow no-gutter\">\n  <div class=\"card-inner-scroll fit-h\">\n    <div class=\"card-block p-t-0 p-b-0\">\n      <c8y-list-group [ngClass]=\"{ 'dd-low': (software$ | async)?.data.length < 10 }\">\n        <c8y-li *c8yFor=\"let software of software$ | async; loadMore: 'auto'\">\n          <c8y-li-icon>\n            <i c8yIcon=\"c8y-tools\"></i>\n          </c8y-li-icon>\n          <c8y-li-body class=\"content-flex-60\">\n            <div class=\"col-5\">\n              <div class=\"text-truncate\" title=\"{{ software.name }}\">\n                {{ software.name }}\n              </div>\n            </div>\n            <div class=\"col-3\">\n              <div class=\"text-truncate\" title=\"{{ 'Device type' | translate }}: {{ getDeviceTypeTitle(software) }}\">\n                <span class=\"text-label-small m-r-8\" translate>\n                  Device type\n                </span>\n                <span *ngIf=\"software.c8y_Filter?.type; else noType\">\n                  {{ software.c8y_Filter?.type }}\n                </span>\n                <ng-template #noType>\n                  <small><em class=\"text-muted\" translate>Undefined`device type`</em></small>\n                </ng-template>\n              </div>\n            </div>\n            <div class=\"col-2\">\n              <span *ngIf=\"isLegacy(software)\" class=\"label label-warning flex-item-right-sm\">\n                <span translate>Legacy</span>\n              </span>\n              <span *ngIf=\"!isLegacy(software)\">\n                <span *ngIf=\"(getBaseVersionsCount$(software) | async) === null\">\n                  <span class=\"label label-info\">\n                    <i c8yIcon=\"circle-o-notch\" class=\"icon-spin\"></i>\n                  </span>\n                </span>\n                <span *ngIf=\"(getBaseVersionsCount$(software) | async) !== null\">\n                  <span [ngPlural]=\"getBaseVersionsCount$(software) | async\">\n                    <ng-template ngPluralCase=\"=0\">\n                      <span class=\"label label-default flex-item-right-sm\">\n                        <span translate>No versions</span>\n                      </span>\n                    </ng-template>\n                    <ng-template ngPluralCase=\"=1\">\n                      <span class=\"label label-info\"><span translate>1 version</span></span>\n                    </ng-template>\n                    <ng-template ngPluralCase=\"other\">\n                      <span class=\"label label-info\">\n                        <span\n                          ngNonBindable\n                          translate\n                          [translateParams]=\"{\n                            count: (getBaseVersionsCount$(software) | async) || ''\n                          }\"\n                          >{{ count }} versions</span\n                        >\n                      </span>\n                    </ng-template>\n                  </span>\n                </span>\n              </span>\n            </div>\n          </c8y-li-body>\n          <c8y-li-collapse>\n            <c8y-list-group>\n              <c8y-li *c8yFor=\"let option of getVersions(software) | async\">\n                <c8y-li-radio\n                  [name]=\"software.id\"\n                  (onSelect)=\"selectSoftware({ option: option, software: software })\"\n                ></c8y-li-radio>\n                <c8y-li-body class=\"content-flex-40 p-r-16\">\n                  <div class=\"col-4\">\n                    {{ option.c8y_Software.version }}\n                  </div>\n                  <div class=\"col-5\">\n                    <div class=\"text-truncate\" title=\"{{ option.c8y_Software.url }}\">\n                      <span class=\"text-label-small m-r-4\" translate> File </span>\n                      <span>{{ option.c8y_Software.url }}</span>\n                    </div>\n                  </div>\n                  <div class=\"col-3\" *ngIf=\"option.id === software.selectedId\">\n                    <div class=\"c8y-select-wrapper d-inline-block\" style=\"margin: -4px 0;\">\n                      <select\n                        id=\"action\"\n                        class=\"form-control input-sm\"\n                        [(ngModel)]=\"option.action\"\n                        (change)=\"emitSoftware({ option: option, software: software })\"\n                      >\n                        <option [ngValue]=\"'install'\">{{ 'Install/update`software`' | translate }}</option>\n                        <option [ngValue]=\"'delete'\">{{ 'Remove`software`' | translate }}</option>\n                      </select>\n                      <span></span>\n                    </div>\n                  </div>\n                </c8y-li-body>\n              </c8y-li>\n            </c8y-list-group>\n          </c8y-li-collapse>\n        </c8y-li>\n      </c8y-list-group>\n    </div>\n  </div>\n</div>\n"
            },] }
];
SelectSoftwareStepComponent.ctorParameters = () => [
    { type: RepositoryService },
    { type: TranslateService }
];
SelectSoftwareStepComponent.propDecorators = {
    software: [{ type: Output }],
    radioButtons: [{ type: ViewChildren, args: [ListItemRadioComponent,] }]
};
__decorate([
    memoize(property('id'))
], SelectSoftwareStepComponent.prototype, "getBaseVersionsCount$", null);
__decorate([
    memoize(property('id'))
], SelectSoftwareStepComponent.prototype, "getVersions", null);
//# sourceMappingURL=data:application/json;base64, 