import * as i0 from '@angular/core';
import { InjectionToken, Component, Inject, Input, EventEmitter, NgModule } from '@angular/core';
import * as i3 from '@c8y/ngx-components';
import { gettext, CoreModule, CommonModule } from '@c8y/ngx-components';
import * as i1 from 'ngx-bootstrap/modal';
import * as i2 from '@angular/platform-browser';
import { takeUntil, first } from 'rxjs/operators';
import { Subject } from 'rxjs';
import * as i4 from '@angular/common';

const PRODUCT_EXPERIENCE_FILE_PREVIEW = {
    EVENTS: {
        FILE_PREVIEW: 'filePreview'
    },
    COMPONENTS: {
        FILE_PREVIEW_COMPONENT: 'file-preview'
    },
    ACTIONS: {
        OPEN_PREVIEW: 'openPreview'
    }
};

/**
 * Provides InjectionToken used in FilePreviewModule. This token is used to inject EventEmitter instance, that is
 * shared among all instances of FilePreviewComponent. These components communicate between each other using this
 * emitter, which enables them to clear downloaded files from memory, if other instance of FilePreviewComponent
 * started downloading different file. Value emitted by this EventEmitter is ID of downloaded file.
 */
const DOWNLOAD_EMITTER = new InjectionToken('downloadEmitter');

/**
 * A component which shows a button that opens a modal with the preview of a binary managed object.
 * This component requires CSP 'blob:' rule for img-src and media-src to be set.
 *
 * ```html
 * <c8y-file-preview [mo]="managedObject">
 *     <button customButton>Preview</button>
 * </c8y-file-preview>
 * ```
 * If no custom button provided, the component will use the default search icon button instead.
 *
 */
class FilePreviewComponent {
    set _mo(mo) {
        this.mo = mo;
        this.setContentType();
    }
    constructor(downloadEmitter, modalRef, modalService, sanitizer, filesService, alertService, gainsightService) {
        this.downloadEmitter = downloadEmitter;
        this.modalRef = modalRef;
        this.modalService = modalService;
        this.sanitizer = sanitizer;
        this.filesService = filesService;
        this.alertService = alertService;
        this.gainsightService = gainsightService;
        this.contentType = 'unsupported';
        this.BUFFERING_STATUS_TEXT = gettext('{{speed}}/s - {{bufferedBytes}} of {{totalBytes}} buffered ({{percentage}}%)');
        this.destroy$ = new Subject();
        downloadEmitter.pipe(takeUntil(this.destroy$)).subscribe(id => {
            if (this.dataUrl && this.mo.id !== id) {
                this.removeDownloadedFile();
            }
        });
    }
    ngOnDestroy() {
        this.removeDownloadedFile();
        this.destroy$.next(true);
        this.destroy$.complete();
    }
    async openModal(template) {
        this.modalRef = this.modalService.show(template, {
            ariaDescribedby: 'modal-body',
            ariaLabelledBy: 'modal-title',
            ignoreBackdropClick: true
        });
        this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_FILE_PREVIEW.EVENTS.FILE_PREVIEW, {
            component: PRODUCT_EXPERIENCE_FILE_PREVIEW.COMPONENTS.FILE_PREVIEW_COMPONENT,
            action: PRODUCT_EXPERIENCE_FILE_PREVIEW.ACTIONS.OPEN_PREVIEW
        });
        if (this.dataUrl) {
            return;
        }
        this.downloadEmitter.emit(this.mo.id);
        const subscription = this.filesService
            .fetchFileWithProgress$(this.mo)
            .pipe(takeUntil(this.destroy$))
            .subscribe(progress => {
            this.progress = progress;
            if (this.progress.blob) {
                this.dataUrl = URL.createObjectURL(progress.blob);
                this.safeDataUrl = this.sanitizer.bypassSecurityTrustUrl(this.dataUrl);
            }
        }, e => {
            this.modalRef.hide();
            this.alertService.addServerFailure(e);
        });
        this.modalRef.onHide.pipe(first(), takeUntil(this.destroy$)).subscribe(() => {
            subscription.unsubscribe();
        });
    }
    removeDownloadedFile() {
        URL.revokeObjectURL(this.dataUrl);
        delete this.dataUrl;
        delete this.safeDataUrl;
    }
    setContentType() {
        if (!this.mo || !this.mo.hasOwnProperty('c8y_IsBinary')) {
            // eslint-disable-next-line no-console
            console.warn('Provided Managed object is not binary');
            this.contentType = 'unsupported';
            return;
        }
        if (this.mo.contentType.startsWith('image/')) {
            this.contentType = 'image';
        }
        else if (this.mo.contentType.startsWith('video/')) {
            this.contentType = 'video';
        }
        else if (this.mo.contentType.startsWith('text/')) {
            // @TODO: Implement in future
            this.contentType = 'unsupported';
        }
        else if (this.mo.contentType.startsWith('application/json')) {
            // @TODO: Implement in future
            this.contentType = 'unsupported';
        }
        else {
            this.contentType = 'unsupported';
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: FilePreviewComponent, deps: [{ token: DOWNLOAD_EMITTER }, { token: i1.BsModalRef }, { token: i1.BsModalService }, { token: i2.DomSanitizer }, { token: i3.FilesService }, { token: i3.AlertService }, { token: i3.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: FilePreviewComponent, selector: "c8y-file-preview", inputs: { _mo: ["mo", "_mo"] }, ngImport: i0, template: "<div\n  class=\"d-inline-block\"\n  *ngIf=\"contentType !== 'unsupported'\"\n  (click)=\"openModal(modalTemplate)\"\n>\n  <div #customButtonRef>\n    <ng-content select=\"[customButton]\"></ng-content>\n  </div>\n\n  <ng-container *ngIf=\"!customButtonRef.children.length\">\n    <button [title]=\"'Preview file' | translate\" type=\"button\" class=\"btn btn-default btn-icon\">\n      <i c8yIcon=\"search\"></i>\n    </button>\n  </ng-container>\n</div>\n\n<ng-template #modalTemplate>\n  <c8y-modal\n    [title]=\"mo.name\"\n    [customFooter]=\"false\"\n    (onClose)=\"modalRef.hide()\"\n    (onDismiss)=\"modalRef.hide()\"\n    [labels]=\"{ cancel: '', ok: 'Close' | translate }\"\n    class=\"text-break-word\"\n  >\n    <div class=\"text-center d-block\" *ngIf=\"!dataUrl\">\n      <c8y-loading layout=\"application\" [progress]=\"progress.percentage\"></c8y-loading>\n      {{\n        BUFFERING_STATUS_TEXT\n          | translate\n            : {\n                totalBytes: progress.totalBytes | bytes,\n                bufferedBytes: progress.bufferedBytes | bytes,\n                percentage: progress.percentage,\n                speed: progress.bytesPerSecond | bytes\n              }\n      }}\n    </div>\n\n    <ng-container *ngIf=\"dataUrl\" [ngSwitch]=\"contentType\" id=\"modal-body\">\n      <ng-container *ngSwitchCase=\"'image'\">\n        <img class=\"fit-w\" alt=\"safeDataUrl\" [src]=\"safeDataUrl\" />\n      </ng-container>\n\n      <ng-container *ngSwitchCase=\"'video'\">\n        <video controls autoplay class=\"fit-w\">\n          <source [src]=\"safeDataUrl\" />\n          {{ 'Your browser does not support the video tag.' | translate }}\n        </video>\n      </ng-container>\n\n      <ng-container *ngSwitchCase=\"'text'\">\n        <!--        @TODO: Implement text viewer-->\n        text\n      </ng-container>\n\n      <ng-container *ngSwitchCase=\"'json'\">\n        <!--        @TODO: Implement json viewer-->\n        json\n      </ng-container>\n\n      <ng-container *ngSwitchDefault></ng-container>\n    </ng-container>\n  </c8y-modal>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i4.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i4.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: i3.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: i3.ModalComponent, selector: "c8y-modal", inputs: ["disabled", "close", "dismiss", "title", "body", "customFooter", "headerClasses", "labels"], outputs: ["onDismiss", "onClose"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3.BytesPipe, name: "bytes" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: FilePreviewComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-file-preview', template: "<div\n  class=\"d-inline-block\"\n  *ngIf=\"contentType !== 'unsupported'\"\n  (click)=\"openModal(modalTemplate)\"\n>\n  <div #customButtonRef>\n    <ng-content select=\"[customButton]\"></ng-content>\n  </div>\n\n  <ng-container *ngIf=\"!customButtonRef.children.length\">\n    <button [title]=\"'Preview file' | translate\" type=\"button\" class=\"btn btn-default btn-icon\">\n      <i c8yIcon=\"search\"></i>\n    </button>\n  </ng-container>\n</div>\n\n<ng-template #modalTemplate>\n  <c8y-modal\n    [title]=\"mo.name\"\n    [customFooter]=\"false\"\n    (onClose)=\"modalRef.hide()\"\n    (onDismiss)=\"modalRef.hide()\"\n    [labels]=\"{ cancel: '', ok: 'Close' | translate }\"\n    class=\"text-break-word\"\n  >\n    <div class=\"text-center d-block\" *ngIf=\"!dataUrl\">\n      <c8y-loading layout=\"application\" [progress]=\"progress.percentage\"></c8y-loading>\n      {{\n        BUFFERING_STATUS_TEXT\n          | translate\n            : {\n                totalBytes: progress.totalBytes | bytes,\n                bufferedBytes: progress.bufferedBytes | bytes,\n                percentage: progress.percentage,\n                speed: progress.bytesPerSecond | bytes\n              }\n      }}\n    </div>\n\n    <ng-container *ngIf=\"dataUrl\" [ngSwitch]=\"contentType\" id=\"modal-body\">\n      <ng-container *ngSwitchCase=\"'image'\">\n        <img class=\"fit-w\" alt=\"safeDataUrl\" [src]=\"safeDataUrl\" />\n      </ng-container>\n\n      <ng-container *ngSwitchCase=\"'video'\">\n        <video controls autoplay class=\"fit-w\">\n          <source [src]=\"safeDataUrl\" />\n          {{ 'Your browser does not support the video tag.' | translate }}\n        </video>\n      </ng-container>\n\n      <ng-container *ngSwitchCase=\"'text'\">\n        <!--        @TODO: Implement text viewer-->\n        text\n      </ng-container>\n\n      <ng-container *ngSwitchCase=\"'json'\">\n        <!--        @TODO: Implement json viewer-->\n        json\n      </ng-container>\n\n      <ng-container *ngSwitchDefault></ng-container>\n    </ng-container>\n  </c8y-modal>\n</ng-template>\n" }]
        }], ctorParameters: () => [{ type: i0.EventEmitter, decorators: [{
                    type: Inject,
                    args: [DOWNLOAD_EMITTER]
                }] }, { type: i1.BsModalRef }, { type: i1.BsModalService }, { type: i2.DomSanitizer }, { type: i3.FilesService }, { type: i3.AlertService }, { type: i3.GainsightService }], propDecorators: { _mo: [{
                type: Input,
                args: ['mo']
            }] } });

const downloadEmitter = new EventEmitter();
class FilePreviewModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: FilePreviewModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.9", ngImport: i0, type: FilePreviewModule, declarations: [FilePreviewComponent], imports: [CoreModule, CommonModule], exports: [FilePreviewComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: FilePreviewModule, providers: [
            {
                provide: DOWNLOAD_EMITTER,
                useValue: downloadEmitter
            }
        ], imports: [CoreModule, CommonModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: FilePreviewModule, decorators: [{
            type: NgModule,
            args: [{
                    declarations: [FilePreviewComponent],
                    imports: [CoreModule, CommonModule],
                    exports: [FilePreviewComponent],
                    providers: [
                        {
                            provide: DOWNLOAD_EMITTER,
                            useValue: downloadEmitter
                        }
                    ]
                }]
        }] });

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

export { FilePreviewComponent, FilePreviewModule };
//# sourceMappingURL=c8y-ngx-components-file-preview.mjs.map
