import { h, Host } from "@stencil/core";
import { PlatformServiceName, } from "@limetech/lime-web-components";
/**
 * Feed item
 *
 * @private
 */
export class FeedTimelineItem {
    constructor() {
        /**
         * Defines the visualization and features of the feed item.
         */
        this.ui = 'standard';
        /**
         * @inheritdoc
         */
        this.hasError = false;
        /**
         * A bundled item is a feed item that is created
         * by the same author as the previous item, but in a
         * very close time proximity as the previous item.
         * Bundled items display less visual details.
         */
        this.isBundled = false;
        /**
         * Set to true, when the "show more" buttons is clicked,
         * and the markdown content in the body of the
         * feed item is expanded.
         */
        this.headingCanExpand = false;
        /**
         * Will be toggled, when the "More" / "Less" button in the "header" is clicked.
         */
        this.isHeadingExpanded = false;
        /**
         * Will be toggled when the "Show more" / "Show less" button is clicked.
         */
        this.showMore = false;
        /**
         * Will be set to true, when the markdown content in the body of the
         * feed item is taller than the specified `maxHeight` threshold.
         * The result will be then used to render a "Show more / less" button,
         * as well as adding certain visual effects.
         */
        this.isTall = false;
        this.collapsibleButtonId = 'a' + crypto.randomUUID();
        this.setHeaderCollapsible = () => {
            if (this.headingParagraphElement) {
                this.headingCanExpand = this.isTextTruncated(this.headingParagraphElement);
            }
        };
        this.bodyTextTall = (entries) => {
            if (!this.bodyTextElement || !(entries === null || entries === void 0 ? void 0 : entries.length)) {
                return;
            }
            const width = entries[0].contentRect.width;
            // Only re-evaluate when the container width changes.
            // Height-only changes are caused by our own CSS (the collapse/expand
            // animation via `grid-template-rows`), and reacting to them would
            // either cause an infinite loop or disrupt the transition.
            if (width === this.lastMeasuredWidth) {
                return;
            }
            this.lastMeasuredWidth = width;
            // Temporarily remove `min-height` to measure the natural content height.
            // The `.is-tall` CSS sets a `min-height` (~164px) on this element,
            // which inflates `scrollHeight` and would prevent `isTall` from ever
            // becoming `false` again. We use `scrollHeight` instead of
            // `contentRect.height`, because the latter reflects the
            // CSS-constrained size (e.g. `grid-template-rows: 0fr`).
            this.bodyTextElement.style.minHeight = '0';
            const height = this.bodyTextElement.scrollHeight;
            this.bodyTextElement.style.removeProperty('min-height');
            const maxHeight = this.isThreadMessage ? 48 : 160;
            this.isTall = height > maxHeight;
            if (this.bodyTextHeight === undefined) {
                this.bodyTextHeight = height;
            }
        };
        this.renderHeader = () => {
            if ((this.isBundled && !this.item.heading) ||
                (!this.item.author && !this.item.heading)) {
                return;
            }
            return (h("div", { class: "header" }, this.renderAuthor(), this.renderHeading(), this.renderExpandCollapseHeadingButton()));
        };
        this.renderRelations = () => {
            var _a, _b, _c;
            if (!((_b = (_a = this.item) === null || _a === void 0 ? void 0 : _a.relations) === null || _b === void 0 ? void 0 : _b.length)) {
                return;
            }
            return h("limel-chip-set", { value: (_c = this.item) === null || _c === void 0 ? void 0 : _c.relations });
        };
        this.renderExpandCollapseHeadingButton = () => {
            var _a, _b;
            if (!this.item.heading) {
                return;
            }
            if (this.headingCanExpand && !this.isHeadingExpanded) {
                return [
                    h("button", { onClick: this.toggleHeadingExpansion, class: "expand-heading" }, (_a = this.translator) === null || _a === void 0 ? void 0 : _a.get('webclient.more')),
                ];
            }
            if (this.isHeadingExpanded) {
                return [
                    h("button", { onClick: this.toggleHeadingExpansion, id: this.collapsibleButtonId, class: "collapse-heading" }, h("limel-icon", { name: "angle_up" })),
                    h("limel-tooltip", { elementId: this.collapsibleButtonId, label: (_b = this.translator) === null || _b === void 0 ? void 0 : _b.get('webclient.show-less'), openDirection: "top-end" }),
                ];
            }
        };
        this.renderThumbnailCard = (thumbnail) => {
            const { href, image, filename } = thumbnail;
            if (!image && !filename) {
                return;
            }
            const id = 'thumb-' + crypto.randomUUID();
            return [
                h("a", { class: "thumbnail-card-link", id: id, key: id, href: href || undefined }, h("limel-card", { image: image, clickable: !!href }, h("limebb-feed-item-thumbnail-file-info", { slot: "component", description: filename })), this.showThumbnailTooltip(thumbnail, id)),
            ];
        };
        this.setBodyTextElement = (element) => {
            this.bodyTextElement = element;
        };
        this.toggleShowMore = () => {
            this.showMore = !this.showMore;
            // Scroll to the top of the feed item when collapsed
            if (!this.showMore) {
                const feedItemHeight = this.el.offsetHeight;
                const viewportHeight = window.innerHeight;
                if (feedItemHeight >= viewportHeight) {
                    this.el.scrollIntoView({ behavior: 'auto' });
                }
            }
        };
        this.toggleHeadingExpansion = () => {
            this.isHeadingExpanded = !this.isHeadingExpanded;
        };
        this.createMenuItem = (action) => {
            var _a, _b;
            if ('separator' in action) {
                return action;
            }
            return {
                value: action,
                text: (_a = action.label) !== null && _a !== void 0 ? _a : '',
                secondaryText: action.description,
                disabled: action.disabled,
                icon: (_b = action.icon) !== null && _b !== void 0 ? _b : '',
            };
        };
        this.createActionBarItem = (action) => {
            var _a, _b;
            if ('separator' in action) {
                return action;
            }
            let item = {
                value: action,
                text: (_a = action.label) !== null && _a !== void 0 ? _a : '',
                secondaryText: action.description,
                disabled: action.disabled,
            };
            if (!action.label && action.icon) {
                item = Object.assign(Object.assign({}, item), { icon: action.icon, text: (_b = action.description) !== null && _b !== void 0 ? _b : item.text, iconOnly: true });
            }
            else if (action.icon) {
                item = Object.assign(Object.assign({}, item), { icon: action.icon });
            }
            return item;
        };
        this.handleMenuItemSelect = (event) => {
            var _a;
            event.stopPropagation();
            const command = (_a = event.detail.value) === null || _a === void 0 ? void 0 : _a.command;
            if (command) {
                this.commandbus.handle(command);
            }
        };
        this.handleActionBarItemSelect = (event) => {
            var _a;
            event.stopPropagation();
            const command = (_a = event.detail.value) === null || _a === void 0 ? void 0 : _a.command;
            if (command) {
                this.commandbus.handle(command);
            }
        };
    }
    componentDidLoad() {
        var _a, _b;
        const headingElement = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.heading');
        this.headingParagraphElement =
            (_b = headingElement === null || headingElement === void 0 ? void 0 : headingElement.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('p');
        if (this.headingParagraphElement) {
            this.headingResizeObserver = new ResizeObserver(this.setHeaderCollapsible);
            this.headingResizeObserver.observe(this.headingParagraphElement);
        }
        if (this.bodyTextElement) {
            this.bodyResizeObserver = new ResizeObserver(this.bodyTextTall);
            this.bodyResizeObserver.observe(this.bodyTextElement);
        }
    }
    disconnectedCallback() {
        var _a;
        (_a = this.bodyResizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
    }
    render() {
        var _a, _b;
        const helperTextId = `helper-text-${this.item.id}`;
        return (h(Host, { key: 'ddc74b89e09e4bd56f2ce64ef2f9ddca011b7acb', id: this.item.id, class: {
                'has-unpromoted-actions': !!((_a = this.item.unpromotedActions) === null || _a === void 0 ? void 0 : _a.length),
                'has-author-picture': !!((_b = this.item.author) === null || _b === void 0 ? void 0 : _b.picture),
                'shows-less': !this.showMore,
                'expanded-heading': this.isHeadingExpanded,
                'shows-more': this.showMore,
                'is-tall': this.isTall,
            }, style: {
                '--body-text-height': `${this.bodyTextHeight}`,
                '--color-code': `${this.item.color}`,
            }, "aria-describedby": this.helperText ? helperTextId : undefined, tabindex: "-1" }, this.renderBadgeAndTimestamp(), this.renderContent(helperTextId)));
    }
    renderBadgeAndTimestamp() {
        return (h("div", { class: "left" }, h("div", { class: "info" }, this.renderAuthorPicture(), this.renderIcon(), h("span", { class: "timestamp" }, this.renderTimestamp()))));
    }
    renderIcon() {
        var _a, _b, _c;
        if (this.isBundled) {
            return;
        }
        if (!this.item.icon && ((_a = this.item.author) === null || _a === void 0 ? void 0 : _a.picture)) {
            return;
        }
        return (h("limel-icon", { class: "icon", badge: true, name: this.getIconName(), style: {
                color: `${(_b = this.item.icon) === null || _b === void 0 ? void 0 : _b.color}`,
                'background-color': `${(_c = this.item.icon) === null || _c === void 0 ? void 0 : _c.backgroundColor}`,
            } }));
    }
    getIconName() {
        const { ui, icon } = this.item;
        if (ui === 'error-message') {
            return 'error';
        }
        return (icon === null || icon === void 0 ? void 0 : icon.name) || 'dot_circle';
    }
    renderContent(helperTextId) {
        return (h("div", { class: "right" }, h("div", { class: "content" }, this.renderThreadEffects(), this.renderHeader(), this.renderUnpromotedActionsMenu(), this.renderValue(), this.renderThumbnails(), this.renderRelations(), this.renderHelperText(helperTextId)), this.renderPromotedActions()));
    }
    renderThreadEffects() {
        if (!this.isThreadMessage) {
            return;
        }
        return h("div", { class: "thread-effects", role: "presentation" });
    }
    renderHelperText(helperTextId) {
        if (!this.helperText) {
            return;
        }
        return (h("span", { class: "helper-text", id: helperTextId }, this.helperText));
    }
    renderAuthor() {
        if (!this.item.author || (this.isBundled && !this.item.heading)) {
            return;
        }
        if (typeof this.item.author.name === 'string') {
            return h("span", { class: "author" }, this.item.author.name);
        }
        if (typeof this.item.author.name === 'object') {
            const { href, title, text } = this.item.author.name;
            return (h("a", { class: "author", href: href, title: title }, text));
        }
    }
    renderAuthorPicture() {
        var _a;
        if (!((_a = this.item.author) === null || _a === void 0 ? void 0 : _a.picture)) {
            return;
        }
        if (this.isBundled) {
            return;
        }
        const { author } = this.item;
        const authorName = this.getAuthorName(author);
        const linkToAuthor = this.createLinkToAuthor(author);
        return (h("limebb-summary-popover", { image: { src: this.item.author.picture, alt: `${authorName}` }, heading: authorName, value: linkToAuthor }, h("img", { slot: "trigger", loading: "lazy", src: this.item.author.picture })));
    }
    renderHeading() {
        if (!this.item.heading) {
            return;
        }
        return [
            h("limel-markdown", { class: {
                    heading: true,
                    'expanded-heading': this.isHeadingExpanded,
                    'truncate-paragraphs': !this.isHeadingExpanded,
                }, value: this.item.heading, adaptColorContrast: true }),
        ];
    }
    renderValue() {
        var _a;
        if (!this.item.value) {
            return;
        }
        return [
            h("div", { class: "markdown-container" }, h("limel-markdown", { class: {
                    'body-text': true,
                    opened: this.showMore,
                    'no-table-styles': !((_a = this.item) === null || _a === void 0 ? void 0 : _a.hasDefaultTableStyles),
                    'reset-img-height': true,
                }, value: this.item.value, lazyLoadImages: true, ref: this.setBodyTextElement, adaptColorContrast: true, whitelist: [
                    {
                        tagName: 'limebb-mention',
                        attributes: ['limetype', 'objectid'],
                    },
                ] }), this.renderShowMoreButton()),
        ];
    }
    renderThumbnails() {
        var _a;
        const thumbnails = (_a = this.item) === null || _a === void 0 ? void 0 : _a.thumbnails;
        if (!(thumbnails === null || thumbnails === void 0 ? void 0 : thumbnails.length)) {
            return;
        }
        return (h("limel-masonry-layout", { role: "group" }, thumbnails.map(this.renderThumbnailCard)));
    }
    showThumbnailTooltip(thumbnail, elementId) {
        var _a;
        const { href, filename } = thumbnail;
        if (!href) {
            return;
        }
        return (h("limel-tooltip", { elementId: elementId, label: ((_a = this.translator) === null || _a === void 0 ? void 0 : _a.get('webclient.go-to-context-label', {
                context: filename,
            })) || filename }));
    }
    getAuthorName(author) {
        if (typeof author.name === 'string') {
            return author.name;
        }
        return author.name.text;
    }
    createLinkToAuthor(author) {
        if (typeof author.name !== 'object') {
            return;
        }
        const { href, title, text } = author.name;
        const linkText = this.translator.get('webclient.actions.goto-object', {
            limetype: ': <br><b>' + text + '</b>',
        });
        return `<a class="author" href="${href}" title="${title}">${linkText}</a>`;
    }
    isTextTruncated(element) {
        return element.offsetWidth < element.scrollWidth;
    }
    renderShowMoreButton() {
        if (!this.isTall) {
            return;
        }
        return [
            h("button", { id: "show-more-button", type: "button", onClick: this.toggleShowMore }, h("limel-icon", { name: "angle_down" })),
            h("limel-tooltip", { label: this.toggleShowMoreLabel(), elementId: "show-more-button", openDirection: "top" }),
        ];
    }
    toggleShowMoreLabel() {
        var _a, _b;
        if (this.showMore) {
            return (_a = this.translator) === null || _a === void 0 ? void 0 : _a.get('webclient.show-less');
        }
        return (_b = this.translator) === null || _b === void 0 ? void 0 : _b.get('webclient.show-more');
    }
    renderUnpromotedActionsMenu() {
        var _a, _b;
        if (!((_a = this.item.unpromotedActions) === null || _a === void 0 ? void 0 : _a.length)) {
            return;
        }
        const items = this.item.unpromotedActions.map(this.createMenuItem);
        return (h("limel-menu", { class: "unpromoted-actions-menu", items: items, openDirection: "bottom-end", onSelect: this.handleMenuItemSelect }, h("limel-icon-button", { icon: "menu_2", slot: "trigger", label: (_b = this.translator) === null || _b === void 0 ? void 0 : _b.get('webclient.more-actions') })));
    }
    renderPromotedActions() {
        var _a;
        if (!((_a = this.item.promotedActions) === null || _a === void 0 ? void 0 : _a.length)) {
            return;
        }
        const actions = this.item.promotedActions.map(this.createActionBarItem);
        return (h("div", { class: "action-bar" }, h("div", { class: "action-bar-hider" }, h("limel-action-bar", { accessibleLabel: "Action bar", actions: actions, layout: "fullWidth", onItemSelected: this.handleActionBarItemSelect }))));
    }
    renderTimestamp() {
        const timestamp = this.item.timestamp;
        if (!timestamp) {
            return;
        }
        return this.dateTimeFormatter.format(timestamp, 'timeofday');
    }
    get dateTimeFormatter() {
        return this.platform.get(PlatformServiceName.DateTimeFormatter);
    }
    get translator() {
        var _a;
        return (_a = this.platform) === null || _a === void 0 ? void 0 : _a.get(PlatformServiceName.Translate);
    }
    get commandbus() {
        var _a;
        return (_a = this.platform) === null || _a === void 0 ? void 0 : _a.get(PlatformServiceName.CommandBus);
    }
    get isThreadMessage() {
        return this.ui === 'thread-message';
    }
    static get is() { return "limebb-feed-timeline-item"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["feed-timeline-item.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["feed-timeline-item.css"]
        };
    }
    static get properties() {
        return {
            "platform": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "LimeWebComponentPlatform",
                    "resolved": "LimeWebComponentPlatform",
                    "references": {
                        "LimeWebComponentPlatform": {
                            "location": "import",
                            "path": "@limetech/lime-web-components",
                            "id": "node_modules::LimeWebComponentPlatform",
                            "referenceLocation": "LimeWebComponentPlatform"
                        }
                    }
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "inheritdoc",
                            "text": undefined
                        }],
                    "text": "Reference to the platform service container.\n\nUse this to access all platform services like repositories, HTTP client,\ncommand bus, navigator, and more. The platform instance is shared across\nall components in the same application context."
                },
                "getter": false,
                "setter": false
            },
            "context": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "LimeWebComponentContext",
                    "resolved": "LimeWebComponentContext",
                    "references": {
                        "LimeWebComponentContext": {
                            "location": "import",
                            "path": "@limetech/lime-web-components",
                            "id": "node_modules::LimeWebComponentContext",
                            "referenceLocation": "LimeWebComponentContext"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "inheritdoc",
                            "text": undefined
                        }],
                    "text": "The context describing where this component is running.\n\nThe context provides information about the current limetype and record ID\n(if viewing/editing a specific record). Components can use this to load\nrelevant data and understand their operating environment."
                },
                "getter": false,
                "setter": false
            },
            "item": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "FeedItem",
                    "resolved": "FeedItem",
                    "references": {
                        "FeedItem": {
                            "location": "import",
                            "path": "./feed-item.types",
                            "id": "src/components/feed/feed-item/feed-item.types.ts::FeedItem",
                            "referenceLocation": "FeedItem"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The item to display in the feed."
                },
                "getter": false,
                "setter": false
            },
            "ui": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Defines the visualization and features of the feed item."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "ui",
                "defaultValue": "'standard'"
            },
            "helperText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "inheritdoc",
                            "text": undefined
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "helper-text"
            },
            "hasError": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "inheritdoc",
                            "text": undefined
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "has-error",
                "defaultValue": "false"
            },
            "isBundled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "A bundled item is a feed item that is created\nby the same author as the previous item, but in a\nvery close time proximity as the previous item.\nBundled items display less visual details."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "is-bundled",
                "defaultValue": "false"
            }
        };
    }
    static get states() {
        return {
            "headingCanExpand": {},
            "isHeadingExpanded": {},
            "showMore": {},
            "isTall": {}
        };
    }
    static get elementRef() { return "el"; }
}
