import { r as registerInstance, h } from './index-BIwHMk6j.js';
import { b as n } from './index.esm-CMeGYws2.js';
import { c as createRandomString } from './random-string-C2JP2nLw.js';

const SECOND = 1000;
const MINUTE = 60 * SECOND;
const HOUR = 60 * MINUTE;
const DAY = 24 * HOUR;
const WEEK = 7 * DAY;
const MONTH = 30 * DAY;
const YEAR = 365 * DAY;
const units = [
    { unit: 'year', ms: YEAR },
    { unit: 'month', ms: MONTH },
    { unit: 'week', ms: WEEK },
    { unit: 'day', ms: DAY },
    { unit: 'hour', ms: HOUR },
    { unit: 'minute', ms: MINUTE },
    { unit: 'second', ms: SECOND },
];
/**
 * Formats a date as a localized relative time expression,
 * e.g. "3 days ago" or "in 2 months".
 *
 * Uses the browser's native `Intl.RelativeTimeFormat` API.
 * @param date
 * @param language
 */
function formatRelativeDate(date, language) {
    var _a;
    const diff = date.getTime() - Date.now();
    const { unit, ms } = (_a = units.find((u) => Math.abs(diff) >= u.ms)) !== null && _a !== void 0 ? _a : units.at(-1);
    return new Intl.RelativeTimeFormat(language, { style: 'long' }).format(Math.round(diff / ms), unit);
}

const dataCellsCss = () => `@charset "UTF-8";*,*:before,*:after{box-sizing:border-box;min-width:0;min-height:0}:host(limebb-data-cells){box-sizing:border-box;display:flex;flex-direction:column;gap:0.5rem;padding:var(--limebb-data-cells-padding)}div{display:flex;flex-direction:column}dl{display:flex;flex-wrap:wrap;gap:0.75rem 1rem;margin:0;padding:0;list-style:none}dd,dt{display:flex;align-items:center}dd span,dt span{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}dd{margin:0;font-size:var(--limel-theme-default-font-size);line-height:1.25rem;height:1.25rem;font-weight:500;color:rgb(var(--contrast-1100))}dd a{text-decoration:none;border-radius:1.25rem}dd a:focus{outline:none}dd a:focus-visible{outline:none;box-shadow:var(--shadow-depth-8-focused)}dd a:not(.belongs-to){position:relative;cursor:pointer;transition:color 0.2s ease;color:rgb(var(--color-blue-default))}dd a:not(.belongs-to):before{transition:opacity 0.2s ease, transform 0.3s ease-out;content:"";position:absolute;inset:auto 0 0 0;width:calc(100% - 0.5rem);margin:auto;height:0.125rem;border-radius:1rem;background-color:currentColor;opacity:0;transform:scale(0.6)}dd a:not(.belongs-to):hover{color:rgb(var(--color-blue-default))}dd a:not(.belongs-to):hover:before{opacity:0.3;transform:scale(1)}dd a.belongs-to{transition:color var(--limel-clickable-transition-speed, 0.4s) ease, background-color var(--limel-clickable-transition-speed, 0.4s) ease, box-shadow var(--limel-clickable-transform-speed, 0.4s) ease, transform var(--limel-clickable-transform-speed, 0.4s) var(--limel-clickable-transform-timing-function, ease);color:inherit;background-color:rgb(var(--contrast-400));padding:1px 0.375rem}dd a.belongs-to:hover,dd a.belongs-to:focus-visible{color:rgb(var(--color-white));background-color:rgb(var(--color-sky-default))}dd:has(.belongs-to){transform:translateX(-0.375rem)}dt{order:1;transition:color 0.2s ease;font-size:0.65rem;color:rgb(var(--contrast-800))}:host(:hover) dt,:host(:focus-within) dt{color:rgb(var(--contrast-900))}.primary+.secondary{padding-top:0.5rem;border-top:1px dashed rgb(var(--contrast-500))}.secondary dd{font-size:0.75rem;font-weight:400;line-height:1rem;height:1rem}div.image-cell{flex-shrink:0}div.image-cell img{display:block;width:2.5rem;height:2.5rem;border-radius:var(--data-cells-image-border-radius, 50%);object-fit:var(--data-cells-image-object-fit, cover);background-color:rgb(var(--color-white));box-shadow:0 0 0 1px rgb(var(--contrast-800), 0.25)}`;

const DataCells = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        /**
         * 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(n.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(n.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,
        });
    }
};
DataCells.style = dataCellsCss();

export { DataCells as limebb_data_cells };
