import * as i0 from '@angular/core';
import { Injectable, Component, Input, NgModule } from '@angular/core';
import * as i2$1 from '@c8y/client';
import * as i2 from '@c8y/ngx-components';
import { gettext, MarkdownToHtmlPipe, C8yValidators, CoreModule } from '@c8y/ngx-components';
import * as i3 from '@ngx-translate/core';
import * as i4 from '@angular/common';
import { AsyncPipe } from '@angular/common';
import * as i1 from '@angular/forms';
import { Validators, ReactiveFormsModule } from '@angular/forms';

class MarkdownWidgetService {
    constructor(fileService, inventory, binary, alert, translate) {
        this.fileService = fileService;
        this.inventory = inventory;
        this.binary = binary;
        this.alert = alert;
        this.translate = translate;
    }
    async getFile(markdownBinaryId) {
        if (!markdownBinaryId) {
            return null;
        }
        try {
            const { data: markdownBinaryMo } = await this.inventory.detail(markdownBinaryId);
            const file = await this.fileService.getFile(markdownBinaryMo);
            return file;
        }
        catch (e) {
            const text = this.translate.instant(gettext('Unable to retrieve binary with ID: {{ markdownBinaryId }}'), { markdownBinaryId });
            this.alert.danger(text, e?.data);
        }
        return null;
    }
    async uploadFile(file) {
        const { data: mo } = await this.binary.create(file);
        return mo.id;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MarkdownWidgetService, deps: [{ token: i2.FilesService }, { token: i2$1.InventoryService }, { token: i2$1.InventoryBinaryService }, { token: i2.AlertService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MarkdownWidgetService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MarkdownWidgetService, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'root' }]
        }], ctorParameters: () => [{ type: i2.FilesService }, { type: i2$1.InventoryService }, { type: i2$1.InventoryBinaryService }, { type: i2.AlertService }, { type: i3.TranslateService }] });

class MarkdownWidgetViewComponent {
    constructor(appState, client, markdownWidgetService) {
        this.appState = appState;
        this.client = client;
        this.markdownWidgetService = markdownWidgetService;
        this.headers = { 'Content-Type': 'text/markdown', responseType: 'blob' };
    }
    async ngOnInit() {
        this.contextPath = this.appState.getCurrentContextPath();
        if (this.config.markdownBinaryId) {
            const readmeContent = await (await this.markdownWidgetService.getFile(this.config.markdownBinaryId)).text();
            this.markdown = readmeContent;
        }
        else if (this.config.contentUrl?.toLowerCase() === '/readme.md') {
            this.markdown = await this.getReadmeFileContent();
        }
        else {
            this.setContentFromUrl(this.config.contentUrl);
        }
    }
    setContentFromUrl(url) {
        const req = new XMLHttpRequest();
        req.onreadystatechange = () => this.render(req);
        req.addEventListener('load', () => this.render(req));
        req.open('GET', url);
        req.responseType = 'text';
        req.setRequestHeader('Accept', 'text/html');
        req.send();
    }
    async render(req) {
        if (req.readyState === 4 && req.status === 200) {
            this.markdown = req.response;
        }
    }
    async getReadmeFileContent() {
        const readmeFile = await this.getReadmeFile();
        if (readmeFile.status === 200) {
            return await readmeFile.text();
        }
        return '';
    }
    async getReadmeFile() {
        const options = {
            method: 'GET',
            headers: this.headers
        };
        const result = await this.client.fetch(`/apps/${this.contextPath}${this.config.contentUrl}`, options);
        return result;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MarkdownWidgetViewComponent, deps: [{ token: i2.AppStateService }, { token: i2$1.FetchClient }, { token: MarkdownWidgetService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MarkdownWidgetViewComponent, isStandalone: true, selector: "c8y-markdown-widget-view", inputs: { config: "config" }, ngImport: i0, template: "<div id=\"helpContent\" class=\"p-16 p-t-0 markdown-content\" [innerHTML]=\"markdown | markdownToHtml | async\"></div>\n", dependencies: [{ kind: "pipe", type: MarkdownToHtmlPipe, name: "markdownToHtml" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MarkdownWidgetViewComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-markdown-widget-view', standalone: true, imports: [MarkdownToHtmlPipe, AsyncPipe], template: "<div id=\"helpContent\" class=\"p-16 p-t-0 markdown-content\" [innerHTML]=\"markdown | markdownToHtml | async\"></div>\n" }]
        }], ctorParameters: () => [{ type: i2.AppStateService }, { type: i2$1.FetchClient }, { type: MarkdownWidgetService }], propDecorators: { config: [{
                type: Input
            }] } });

class MarkdownWidgetConfigComponent {
    constructor(formBuilder, form, alert, markdownService) {
        this.formBuilder = formBuilder;
        this.form = form;
        this.alert = alert;
        this.markdownService = markdownService;
        this.uploadChoice = 'uploadUrl';
        this.loading = false;
    }
    async onBeforeSave(config) {
        if (this.formGroup.invalid) {
            return false;
        }
        if (this.uploadChoice === 'uploadUrl') {
            Object.assign(config, {
                contentUrl: this.formGroup.value.contentUrl,
                markdownBinaryId: null
            });
            return true;
        }
        const fileFromForm = this.getFileFromFormValue(this.formGroup.value);
        if (fileFromForm && fileFromForm !== this.fileFromConfig) {
            try {
                const markdownBinaryId = await this.markdownService.uploadFile(fileFromForm);
                Object.assign(config, { markdownBinaryId, contentUrl: null });
                return true;
            }
            catch (e) {
                this.alert.danger(gettext('Unable to upload Markdown file.'), e?.data);
                return false;
            }
        }
        if (!fileFromForm) {
            Object.assign(config, { contentUrl: '/readme.md', markdownBinaryId: null });
        }
        return true;
    }
    async ngOnInit() {
        this.initForm();
        if (this.config.markdownBinaryId) {
            this.uploadChoice = 'uploadBinary';
            this.fileFromConfig = await this.markdownService.getFile(this.config.markdownBinaryId);
            this.formGroup.patchValue({
                droppedFile: [{ file: this.fileFromConfig, name: this.fileFromConfig.name }]
            });
        }
    }
    onChange(value) {
        this.uploadChoice = value;
        this.formGroup.controls['uploadChoice'].patchValue(value);
    }
    getFileFromFormValue(formValue) {
        const binary = formValue?.droppedFile || [];
        return binary[0]?.file || null;
    }
    initForm() {
        this.formGroup = this.formBuilder.group({
            contentUrl: ['', [Validators.maxLength(2000)]],
            droppedFile: [
                null,
                [
                    Validators.minLength(1),
                    Validators.maxLength(1),
                    C8yValidators.filesValidator({ maximumFileSizeInKb: 1000 })
                ]
            ],
            uploadChoice: [this.config.markdownBinaryId ? 'uploadBinary' : 'uploadUrl', []]
        }, { validators: this.requireEitherBinaryOrUrl() });
        this.form.form.addControl('config', this.formGroup);
        this.formGroup.patchValue(this.config);
    }
    requireEitherBinaryOrUrl() {
        return (control) => {
            const url = control.get(`contentUrl`);
            const uploadBinary = control.get(`droppedFile`);
            const urlDefined = url && url.value !== undefined && url.value !== null;
            const uploadBinaryDefined = uploadBinary && uploadBinary.value !== undefined && uploadBinary.value !== null;
            const errors = {};
            if (this.uploadChoice === 'uploadBinary' && !uploadBinaryDefined) {
                // sets error
                const error = { required: true };
                uploadBinary.setErrors(Object.assign({}, uploadBinary.errors || {}, error));
                Object.assign(errors, error);
            }
            else {
                // remove previous error
                this.removeErrors(uploadBinary, ['required']);
            }
            if (this.uploadChoice === 'uploadUrl' && (!urlDefined || url.value === '')) {
                // sets error
                const error = { required: true };
                url.setErrors(Object.assign({}, url.errors || {}, error));
                Object.assign(errors, error);
            }
            else {
                // remove previous error
                this.removeErrors(url, ['required']);
            }
            return Object.keys(errors).length ? errors : null;
        };
    }
    removeErrors(control, errors) {
        if (!control || !control.errors) {
            return false;
        }
        let removedError = false;
        for (const error of errors) {
            if (control.errors[error]) {
                removedError = true;
                delete control.errors[error];
            }
        }
        if (removedError) {
            control.setErrors(Object.keys(control.errors).length ? Object.assign({}, control.errors) : null);
        }
        return removedError;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MarkdownWidgetConfigComponent, deps: [{ token: i1.FormBuilder }, { token: i1.NgForm }, { token: i2.AlertService }, { token: MarkdownWidgetService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MarkdownWidgetConfigComponent, isStandalone: true, selector: "c8y-markdown-widget-config", inputs: { config: "config" }, ngImport: i0, template: "<form [formGroup]=\"formGroup\" class=\"p-l-24 p-r-24 p-t-16\">\n  <div class=\"form-group\">\n    <label title=\"{{ 'Upload a binary' | translate }}\" class=\"c8y-radio radio-inline\">\n      <input\n        #radio\n        formControlName=\"uploadChoice\"\n        type=\"radio\"\n        value=\"uploadBinary\"\n        name=\"uploadChoice\"\n        (change)=\"onChange($event.target.value)\"\n      />\n      <span></span>\n      <span>{{ 'Upload a binary' | translate }}</span>\n    </label>\n    <label title=\"{{ 'Provide a file path' | translate }}\" class=\"c8y-radio radio-inline m-l-8\">\n      <input\n        #radio\n        formControlName=\"uploadChoice\"\n        type=\"radio\"\n        value=\"uploadUrl\"\n        name=\"uploadChoice\"\n        (change)=\"onChange($event.target.value)\"\n      />\n      <span></span>\n      <span>\n        {{ 'Provide a file path' | translate }}\n      </span>\n    </label>\n  </div>\n\n  <ng-container [ngSwitch]=\"uploadChoice\">\n    <div *ngSwitchCase=\"'uploadBinary'\">\n      <c8y-form-group class=\"m-0\">\n        <c8y-drop-area\n          formControlName=\"droppedFile\"\n          class=\"drop-area-sm\"\n          [title]=\"'Drop file or click to browse' | translate\"\n          [maxAllowedFiles]=\"1\"\n          [accept]=\"'md'\"\n        ></c8y-drop-area>\n      </c8y-form-group>\n    </div>\n    <div *ngSwitchCase=\"'uploadUrl'\">\n      <c8y-form-group class=\"m-0\">\n        <div class=\"m-b-4 p-b-8\">\n          <div class=\"input-group\">\n            <span class=\"input-group-addon\">\n              <i c8yIcon=\"globe\"></i>\n            </span>\n            <input\n              type=\"text\"\n              class=\"form-control\"\n              formControlName=\"contentUrl\"\n              placeholder=\"{{ 'e.g.' | translate }} http://example.com/binary.zip\"\n            />\n          </div>\n        </div>\n      </c8y-form-group>\n    </div>\n  </ng-container>\n</form>\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i4.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i4.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: i2.DropAreaComponent, selector: "c8y-drop-area", inputs: ["formControl", "title", "message", "icon", "loadingMessage", "forceHideList", "alwaysShow", "clickToOpen", "loading", "progress", "maxAllowedFiles", "files", "maxFileSizeInMegaBytes", "accept"], outputs: ["dropped"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i2.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i2.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MarkdownWidgetConfigComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-markdown-widget-config', standalone: true, imports: [CoreModule, ReactiveFormsModule], template: "<form [formGroup]=\"formGroup\" class=\"p-l-24 p-r-24 p-t-16\">\n  <div class=\"form-group\">\n    <label title=\"{{ 'Upload a binary' | translate }}\" class=\"c8y-radio radio-inline\">\n      <input\n        #radio\n        formControlName=\"uploadChoice\"\n        type=\"radio\"\n        value=\"uploadBinary\"\n        name=\"uploadChoice\"\n        (change)=\"onChange($event.target.value)\"\n      />\n      <span></span>\n      <span>{{ 'Upload a binary' | translate }}</span>\n    </label>\n    <label title=\"{{ 'Provide a file path' | translate }}\" class=\"c8y-radio radio-inline m-l-8\">\n      <input\n        #radio\n        formControlName=\"uploadChoice\"\n        type=\"radio\"\n        value=\"uploadUrl\"\n        name=\"uploadChoice\"\n        (change)=\"onChange($event.target.value)\"\n      />\n      <span></span>\n      <span>\n        {{ 'Provide a file path' | translate }}\n      </span>\n    </label>\n  </div>\n\n  <ng-container [ngSwitch]=\"uploadChoice\">\n    <div *ngSwitchCase=\"'uploadBinary'\">\n      <c8y-form-group class=\"m-0\">\n        <c8y-drop-area\n          formControlName=\"droppedFile\"\n          class=\"drop-area-sm\"\n          [title]=\"'Drop file or click to browse' | translate\"\n          [maxAllowedFiles]=\"1\"\n          [accept]=\"'md'\"\n        ></c8y-drop-area>\n      </c8y-form-group>\n    </div>\n    <div *ngSwitchCase=\"'uploadUrl'\">\n      <c8y-form-group class=\"m-0\">\n        <div class=\"m-b-4 p-b-8\">\n          <div class=\"input-group\">\n            <span class=\"input-group-addon\">\n              <i c8yIcon=\"globe\"></i>\n            </span>\n            <input\n              type=\"text\"\n              class=\"form-control\"\n              formControlName=\"contentUrl\"\n              placeholder=\"{{ 'e.g.' | translate }} http://example.com/binary.zip\"\n            />\n          </div>\n        </div>\n      </c8y-form-group>\n    </div>\n  </ng-container>\n</form>\n" }]
        }], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i1.NgForm }, { type: i2.AlertService }, { type: MarkdownWidgetService }], propDecorators: { config: [{
                type: Input
            }] } });

/**
 * @deprecated
 */
class MarkdownWidgetModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MarkdownWidgetModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: MarkdownWidgetModule, imports: [MarkdownWidgetViewComponent, MarkdownWidgetConfigComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MarkdownWidgetModule, imports: [MarkdownWidgetConfigComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MarkdownWidgetModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [MarkdownWidgetViewComponent, MarkdownWidgetConfigComponent]
                }]
        }] });

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

export { MarkdownWidgetConfigComponent, MarkdownWidgetModule, MarkdownWidgetService, MarkdownWidgetViewComponent };
//# sourceMappingURL=c8y-ngx-components-widgets-implementations-markdown.mjs.map
