import { h, Host, } from "@stencil/core";
import translate from "../../global/translations";
import { applyRemoteImagesPolicy, containsRemoteImages } from "./remote-images";
import { splitEmailAddressList } from "./split-email-address-list";
import { formatBytes } from "../../util/format-bytes";
/**
 * This is a private component, used to render `.eml` files inside
 * `limel-file-viewer`.
 *
 * :::note
 * If `bodyHtml` is provided, it will be rendered using `innerHTML`.
 * Consumers should pre-sanitize `bodyHtml` before passing it to the component.
 * :::
 *
 * @exampleComponent limel-example-email-viewer-plain-text
 * @exampleComponent limel-example-email-viewer-inline-image
 * @exampleComponent limel-example-email-viewer-remote-image-policy
 *
 * @private
 */
export class EmailViewer {
    constructor() {
        /**
         * Defines the localization for translations.
         */
        this.language = 'en';
        this.allowRemoteImagesState = false;
        this.renderAttachment = (attachment, index) => {
            var _a, _b;
            const filename = ((_a = attachment.filename) === null || _a === void 0 ? void 0 : _a.trim()) ||
                this.getTranslation('file-viewer.email.attachment.unnamed');
            const mimeType = ((_b = attachment.mimeType) === null || _b === void 0 ? void 0 : _b.trim()) || '';
            return (h("li", { key: `attachment-${index}` }, h("span", { class: "attachment-filename" }, filename), h("span", { class: "attachment-mime-type" }, " ", mimeType), this.renderSizeBadge(attachment.size)));
        };
        this.renderSizeBadge = (size) => {
            if (typeof size !== 'number') {
                return;
            }
            return (h("limel-badge", { class: "attachment-size", label: formatBytes(size) }));
        };
        this.onEnableRemoteImagesClick = (event) => {
            var _a;
            (_a = event === null || event === void 0 ? void 0 : event.stopPropagation) === null || _a === void 0 ? void 0 : _a.call(event);
            this.enableRemoteImages();
        };
        this.enableRemoteImages = () => {
            if (this.allowRemoteImages !== undefined) {
                this.allowRemoteImagesChange.emit(true);
                return;
            }
            this.allowRemoteImagesState = true;
        };
    }
    resetAllowRemoteImages(newEmail, oldEmail) {
        if (!newEmail) {
            this.allowRemoteImagesState = false;
            return;
        }
        if (newEmail.from !== (oldEmail === null || oldEmail === void 0 ? void 0 : oldEmail.from)) {
            this.allowRemoteImagesState = false;
        }
    }
    render() {
        return (h(Host, { key: 'a004af12989a477f4a9404ee86e0429bc5c2d427' }, h("div", { key: 'fc3bdeb81d823ff1cd39b4f6d52b4a88d9326392', class: "email", part: "email" }, this.renderHeaders(), this.renderRemoteImageBanner(), h("section", { key: '6fdd1cfe50cc4b41f7e70413541dc5950d7c44fa' }, this.renderAttachments(), this.renderBody()))));
    }
    renderHeaders() {
        const headerFields = [
            'subject',
            'from',
            'to',
            'cc',
            'date',
        ];
        return (h("div", { class: "email-headers", part: "email-headers" }, headerFields.map((type) => {
            var _a;
            return this.renderEmailHeader(type, this.getTranslation(`file-viewer.email.${type}`), (_a = this.email) === null || _a === void 0 ? void 0 : _a[type]);
        })));
    }
    renderBody() {
        return (this.renderBodyHtml() ||
            this.renderBodyText() ||
            this.renderFallbackUrl() || h("slot", { name: "fallback" }));
    }
    renderBodyHtml() {
        var _a;
        const bodyHtml = (_a = this.email) === null || _a === void 0 ? void 0 : _a.bodyHtml;
        if (!bodyHtml) {
            return;
        }
        const innerHtml = applyRemoteImagesPolicy(bodyHtml, this.getAllowRemoteImages());
        return h("div", { class: "body", innerHTML: innerHtml, part: "email-body" });
    }
    renderBodyText() {
        var _a;
        const bodyText = (_a = this.email) === null || _a === void 0 ? void 0 : _a.bodyText;
        if (!bodyText) {
            return;
        }
        return (h("pre", { class: "body plain-text", part: "email-body" }, bodyText));
    }
    renderFallbackUrl() {
        if (!this.fallbackUrl) {
            return;
        }
        return (h("object", { data: this.fallbackUrl, type: "text/plain" }, h("slot", { name: "fallback" })));
    }
    renderEmailHeader(type, label, value) {
        if (!value) {
            return;
        }
        const values = this.getHeaderValues(type, value);
        return (h("dl", { class: `headers ${type}` }, h("dt", null, label), values.map((headerValue, index) => (h("dd", { key: `${type}-${index}` }, headerValue)))));
    }
    getHeaderValues(type, value) {
        if (type === 'to' || type === 'cc') {
            return splitEmailAddressList(value);
        }
        return [value];
    }
    renderAttachments() {
        var _a;
        const attachments = (_a = this.email) === null || _a === void 0 ? void 0 : _a.attachments;
        if (!(attachments === null || attachments === void 0 ? void 0 : attachments.length)) {
            return;
        }
        const label = this.getTranslation('file-viewer.email.attachments');
        return (h("div", { class: "attachments" }, h("span", null, label), h("ul", null, attachments.map((attachment, index) => this.renderAttachment(attachment, index)))));
    }
    getTranslation(key) {
        return translate.get(key, this.language);
    }
    shouldShowRemoteImagesBanner() {
        var _a;
        const bodyHtml = (_a = this.email) === null || _a === void 0 ? void 0 : _a.bodyHtml;
        if (!bodyHtml || this.getAllowRemoteImages()) {
            return false;
        }
        return containsRemoteImages(bodyHtml);
    }
    renderRemoteImageBanner() {
        if (!this.shouldShowRemoteImagesBanner()) {
            return;
        }
        const icon = {
            name: 'warning_shield',
            color: 'rgb(var(--color-orange-default))',
        };
        const heading = this.getTranslation('file-viewer.email.remote-images.warning');
        const description = this.getTranslation('file-viewer.email.remote-images.warning.description');
        const buttonLabel = this.getTranslation('file-viewer.email.remote-images.load');
        return (h("limel-collapsible-section", { header: heading, icon: icon, language: this.language }, h("button", { type: "button", class: "load-images", slot: "header", onClick: this.onEnableRemoteImagesClick }, buttonLabel), h("limel-markdown", { value: description })));
    }
    getAllowRemoteImages() {
        var _a;
        return (_a = this.allowRemoteImages) !== null && _a !== void 0 ? _a : this.allowRemoteImagesState;
    }
    static get is() { return "limel-email-viewer"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["email-viewer.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["email-viewer.css"]
        };
    }
    static get properties() {
        return {
            "email": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Email",
                    "resolved": "Email",
                    "references": {
                        "Email": {
                            "location": "import",
                            "path": "./email-viewer.types",
                            "id": "src/components/email-viewer/email-viewer.types.ts::Email",
                            "referenceLocation": "Email"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The email message to display.\n\nIf `email.bodyHtml` is set directly, consumers must provide sanitized\nHTML."
                },
                "getter": false,
                "setter": false
            },
            "fallbackUrl": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Optional URL to render as a final fallback using an `<object type=\"text/plain\">`."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "fallback-url"
            },
            "language": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "Languages",
                    "resolved": "\"da\" | \"de\" | \"en\" | \"fi\" | \"fr\" | \"nb\" | \"nl\" | \"no\" | \"sv\"",
                    "references": {
                        "Languages": {
                            "location": "import",
                            "path": "../date-picker/date.types",
                            "id": "src/components/date-picker/date.types.ts::Languages",
                            "referenceLocation": "Languages"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Defines the localization for translations."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "language",
                "defaultValue": "'en'"
            },
            "allowRemoteImages": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Controls whether remote images (http/https) are loaded.\n\nIf omitted, the component treats this as a per-email setting.\nConsumers that want to remember the choice (per session/global) can\nprovide this prop and listen for `allowRemoteImagesChange`."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "allow-remote-images"
            }
        };
    }
    static get states() {
        return {
            "allowRemoteImagesState": {}
        };
    }
    static get events() {
        return [{
                "method": "allowRemoteImagesChange",
                "name": "allowRemoteImagesChange",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }],
                    "text": "Emitted when the user requests remote images to be loaded."
                },
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                }
            }];
    }
    static get watchers() {
        return [{
                "propName": "email",
                "methodName": "resetAllowRemoteImages"
            }];
    }
}
