import { h } from "@stencil/core";
import { PlatformServiceName, } from "@limetech/lime-web-components";
import { formatRelativeDate } from "../../util/format-relative-date";
import { createRandomString } from "../../util/random-string";
/**
 * Renders a list of key-value data cells in two visual groups:
 * primary (prominent) and secondary (less dominant).
 *
 * Optionally accepts a leading image (e.g. a profile picture or
 * company favicon).
 *
 * @exampleComponent limebb-example-data-cells-basic
 * @exampleComponent limebb-example-data-cells-primary-secondary
 * @exampleComponent limebb-example-data-cells-typed-values
 * @exampleComponent limebb-example-data-cells-relative-dates
 * @exampleComponent limebb-example-data-cells-empty-values
 * @exampleComponent limebb-example-data-cells-with-favicon
 * @exampleComponent limebb-example-data-cells-with-profile-picture
 *
 * @beta
 */
export class DataCells {
    constructor() {
        /**
         * The data cells to render.
         */
        this.items = [];
        /**
         * When `true` (default), date and time values are displayed as relative
         * time expressions (e.g. "3 days ago"), with the absolute date shown in
         * a tooltip. Set to `false` to display the absolute date directly.
         */
        this.relativeDates = true;
        this.renderCell = (item) => (h("div", null, h("dt", null, h("span", null, item.label)), h("dd", null, h("span", null, this.renderValue(item)))));
    }
    render() {
        const hasPrimary = this.items.some((item) => !item.secondary);
        return [
            this.renderPrimary(hasPrimary),
            this.renderSecondary(hasPrimary),
        ];
    }
    renderPrimary(hasPrimary) {
        if (!hasPrimary) {
            return;
        }
        const items = this.items.filter((item) => !item.secondary);
        return (h("dl", { class: "primary" }, this.renderImageCell(), items.map(this.renderCell)));
    }
    renderSecondary(hasPrimary) {
        const items = this.items.filter((item) => item.secondary);
        if (items.length === 0) {
            return;
        }
        return (h("dl", { class: "secondary" }, !hasPrimary && this.renderImageCell(), items.map(this.renderCell)));
    }
    renderImageCell() {
        var _a;
        if (!this.image) {
            return;
        }
        // Wrapped so the <dl>'s direct children stay <dt>/<dd>-style cells
        // (per the HTML spec) instead of a stray <img>.
        return (h("div", { class: "image-cell" }, h("img", { src: this.image.src, alt: this.image.alt, loading: (_a = this.image.loading) !== null && _a !== void 0 ? _a : 'lazy' })));
    }
    renderValue(item) {
        if (item.value == null || item.value === '') {
            return '–';
        }
        if (item.type === 'belongsto') {
            const href = this.getBelongsToHref(item.field);
            if (!href) {
                return item.value;
            }
            return (h("a", { class: "belongs-to", href: href }, item.value));
        }
        if (item.type === 'phone') {
            return h("a", { href: this.toTelUri(item.value) }, item.value);
        }
        if (item.type === 'email') {
            return h("a", { href: `mailto:${item.value}` }, item.value);
        }
        if (item.type === 'link') {
            return (h("a", { href: this.ensureUrlProtocol(item.value), target: "_blank", rel: "noopener" }, this.stripUrlPrefix(item.value)));
        }
        if (item.type === 'time' || item.type === 'date') {
            const date = new Date(item.value);
            if (Number.isNaN(date.getTime())) {
                return item.value;
            }
            if (!this.relativeDates) {
                return this.formatAbsoluteDate(date, item.type);
            }
            const id = createRandomString();
            return [
                h("span", { id: id }, formatRelativeDate(date, this.language)),
                h("limel-tooltip", { elementId: id, label: this.formatAbsoluteDate(date, item.type) }),
            ];
        }
        if (item.type === 'percent') {
            return (h("limebb-percentage-visualizer", { value: Number(item.value), multiplier: 100, displayPercentageColors: true, reducePresence: false }));
        }
        return item.value;
    }
    toTelUri(phoneNumber) {
        return `tel:${phoneNumber.replaceAll(' ', '')}`;
    }
    ensureUrlProtocol(url) {
        if (/^https?:\/\//i.test(url)) {
            return url;
        }
        return `https://${url}`;
    }
    stripUrlPrefix(url) {
        return url.replace(/^https?:\/\//, '').replace(/^www\./, '');
    }
    getBelongsToHref(field) {
        var _a;
        if (!this.limeobject || !field) {
            return undefined;
        }
        try {
            const relatedObject = this.limeobject.getValue(field);
            if (!relatedObject || typeof relatedObject !== 'object') {
                return undefined;
            }
            const limetype = (_a = relatedObject.getLimetype) === null || _a === void 0 ? void 0 : _a.call(relatedObject);
            if (!(limetype === null || limetype === void 0 ? void 0 : limetype.name) || !relatedObject.id) {
                return undefined;
            }
            return `object/${limetype.name}/${relatedObject.id}`;
        }
        catch (_b) {
            return undefined;
        }
    }
    get language() {
        var _a;
        try {
            return (_a = this.platform) === null || _a === void 0 ? void 0 : _a.get(PlatformServiceName.Application).getLanguage();
        }
        catch (_b) {
            return navigator.language;
        }
    }
    formatAbsoluteDate(date, type) {
        var _a;
        try {
            const formatter = (_a = this.platform) === null || _a === void 0 ? void 0 : _a.get(PlatformServiceName.DateTimeFormatter);
            if (formatter) {
                return formatter.format(date, type);
            }
        }
        catch (_b) {
            // Fall through to default formatting.
        }
        return date.toLocaleString(this.language, {
            dateStyle: 'long',
            timeStyle: type === 'time' ? 'short' : undefined,
        });
    }
    static get is() { return "limebb-data-cells"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["data-cells.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["data-cells.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": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "inheritdoc",
                            "text": undefined
                        }],
                    "text": ""
                },
                "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": ""
                },
                "getter": false,
                "setter": false
            },
            "limeobject": {
                "type": "any",
                "mutable": false,
                "complexType": {
                    "original": "any",
                    "resolved": "any",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The source LimeObject. Used by interactive cell types\nlike `belongsto` to resolve related objects."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "limeobject"
            },
            "items": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "DataCell[]",
                    "resolved": "DataCell[]",
                    "references": {
                        "DataCell": {
                            "location": "import",
                            "path": "./data-cells.types",
                            "id": "src/components/data-cells/data-cells.types.ts::DataCell",
                            "referenceLocation": "DataCell"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The data cells to render."
                },
                "getter": false,
                "setter": false,
                "defaultValue": "[]"
            },
            "image": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Image",
                    "resolved": "Image | undefined",
                    "references": {
                        "Image": {
                            "location": "import",
                            "path": "@limetech/lime-elements",
                            "id": "node_modules::Image",
                            "referenceLocation": "Image"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "An optional leading image (typically a profile picture or a\ncompany favicon). When set, rendered as the first cell of the\nprimary group, or of the secondary group when there are no\nprimary cells. When omitted, no image slot is reserved."
                },
                "getter": false,
                "setter": false
            },
            "relativeDates": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "When `true` (default), date and time values are displayed as relative\ntime expressions (e.g. \"3 days ago\"), with the absolute date shown in\na tooltip. Set to `false` to display the absolute date directly."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "relative-dates",
                "defaultValue": "true"
            }
        };
    }
}
