import { h, Host, } from "@stencil/core";
import { getPreviewType } from "../limeobject/file-viewer/extension-mapping";
import { getFileExtension } from "../../util/file-extension";
import { getFileIcon } from "../../util/file-icon";
/**
 * Renders a list of document chips, each wrapped in a
 * `limebb-summary-popover` that shows a file preview on hover or
 * keyboard focus.
 *
 * Supports browser-previewable files (images, PDFs, video, audio, text).
 * Office file types show a fallback message instead of an unsupported preview.
 *
 * The component manages blob URL creation for local files internally
 * and cleans them up when files are removed or the component is destroyed.
 *
 * @exampleComponent limebb-example-document-chips-basic
 * @exampleComponent limebb-example-document-chips-upload-states
 *
 * @beta
 */
export class DocumentChips {
    constructor() {
        /**
         * The list of files to display as document chips.
         */
        this.files = [];
        this.blobUrls = new Map();
        this.handleRemove = (event) => {
            event.stopPropagation();
            const fileId = event.detail;
            this.revokeBlobUrl(fileId);
            this.removeFile.emit(fileId);
        };
    }
    onFilesChanged(newFiles, oldFiles) {
        const currentIds = new Set(newFiles.map((file) => file.id));
        for (const file of oldFiles) {
            if (!currentIds.has(file.id)) {
                this.revokeBlobUrl(file.id);
            }
        }
    }
    disconnectedCallback() {
        this.revokeAllBlobUrls();
    }
    render() {
        return (h(Host, { key: 'db1a1db2daeb513826e3fb8e03bc0a1fb223b7f6', role: "list", "aria-label": this.accessibleLabel }, this.files.map((file) => this.renderFile(file))));
    }
    renderFile(file) {
        const isReady = !file.uploadState || file.uploadState === 'done';
        const icon = this.getIcon(file);
        const chip = (h("limel-chip", { role: isReady ? undefined : 'listitem', slot: isReady ? 'trigger' : undefined, removable: true, identifier: file.id, text: file.filename, icon: icon, invalid: file.uploadState === 'failed', progress: file.uploadState === 'uploading'
                ? file.uploadProgress
                : undefined, loading: file.uploadState === 'added' ||
                file.uploadState === 'finalizing', onRemove: this.handleRemove }));
        if (!isReady) {
            return chip;
        }
        return (h("limebb-summary-popover", { role: "listitem", file: Object.assign(Object.assign({}, file), { href: this.getPreviewUrl(file) }), popoverMaxWidth: "32rem", popoverMaxHeight: "32rem", triggerDelay: 1000 }, chip));
    }
    getIcon(file) {
        if (file.icon) {
            return file.icon;
        }
        return getFileIcon(file.filename);
    }
    getPreviewUrl(file) {
        const extension = getFileExtension(file.filename);
        const previewType = getPreviewType(extension);
        if (previewType === 'sharepoint') {
            return undefined;
        }
        if (file.href) {
            return file.href;
        }
        if (file.fileContent) {
            if (!this.blobUrls.has(file.id)) {
                this.blobUrls.set(file.id, URL.createObjectURL(file.fileContent));
            }
            return this.blobUrls.get(file.id);
        }
    }
    revokeBlobUrl(fileId) {
        const url = this.blobUrls.get(fileId);
        if (url) {
            URL.revokeObjectURL(url);
            this.blobUrls.delete(fileId);
        }
    }
    revokeAllBlobUrls() {
        for (const url of this.blobUrls.values())
            URL.revokeObjectURL(url);
        this.blobUrls.clear();
    }
    static get is() { return "limebb-document-chips"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["document-chips.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["document-chips.css"]
        };
    }
    static get properties() {
        return {
            "accessibleLabel": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "A label used to describe the purpose of the list to users\nof assistive technologies, like screen readers."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "accessible-label"
            },
            "files": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "DocumentChipFile[]",
                    "resolved": "DocumentChipFile[]",
                    "references": {
                        "DocumentChipFile": {
                            "location": "import",
                            "path": "./document-chips.types",
                            "id": "src/components/document-chips/document-chips.types.ts::DocumentChipFile",
                            "referenceLocation": "DocumentChipFile"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The list of files to display as document chips."
                },
                "getter": false,
                "setter": false,
                "defaultValue": "[]"
            }
        };
    }
    static get events() {
        return [{
                "method": "removeFile",
                "name": "removeFile",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Fired when a document chip's remove button is clicked.\nThe event detail contains the file's `id`."
                },
                "complexType": {
                    "original": "string | number",
                    "resolved": "number | string",
                    "references": {}
                }
            }];
    }
    static get watchers() {
        return [{
                "propName": "files",
                "methodName": "onFilesChanged"
            }];
    }
}
