import { r as registerInstance, g as getElement, h } from './index-BIwHMk6j.js';
import { g as getIcon } from './limetype-DvPoeXt-.js';
import { f as findParentElement } from './dom-B95D7tDb.js';
import { j as jt, b as n } from './index.esm-CMeGYws2.js';

const logger = jt('object-resolver');
/**
 * Build the navigation URL for a Lime CRM object.
 * @param limetype
 * @param objectid
 */
function getObjectUrl(limetype, objectid) {
    return `object/${limetype}/${objectid}`;
}
/**
 * Resolves platform, limetype metadata, and object data for a given
 * limetype + objectid pair.
 *
 * Designed to be used by Stencil components: pass an `onStateChange`
 * callback that updates a `@State()` property to trigger re-renders.
 */
class ObjectResolver {
    constructor(onStateChange) {
        this.onStateChange = onStateChange;
        this.state = { loadFailed: false };
        this.hasPendingLoad = false;
        this.isDisconnected = false;
    }
    /**
     * The resolved platform instance, if any.
     */
    get resolvedPlatform() {
        return this._platform;
    }
    /**
     * Initialize the resolver. Call from `connectedCallback()`.
     *
     * @param limetype - name of the limetype
     * @param objectid - id of the object
     * @param hostElement - the component's host element (for DOM-walking fallback)
     * @param platform - optional platform prop (skips DOM walk if provided)
     */
    connect(limetype, objectid, hostElement, platform) {
        this.limetype = limetype;
        this.objectid = objectid;
        this.isDisconnected = false;
        this.hasPendingLoad = false;
        this._platform = platform || this.findPlatform(hostElement);
        if (!this._platform) {
            logger.error(`No platform found. Pass "platform" prop or place the component inside a parent that exposes "platform". limetype=${limetype}, objectid=${objectid}`);
            return;
        }
        this.resolveLimeType();
        this.loadLimeObject();
    }
    /**
     * Handle prop changes. Call from `@Watch` handlers.
     *
     * Debounces via `queueMicrotask` so that simultaneous changes to
     * both `limetype` and `objectid` result in a single load.
     * @param limetype
     * @param objectid
     */
    update(limetype, objectid) {
        this.limetype = limetype;
        this.objectid = objectid;
        this.updateState({
            limeobject: undefined,
            limetypeData: undefined,
            loadFailed: false,
        });
        if (this.hasPendingLoad) {
            return;
        }
        this.hasPendingLoad = true;
        queueMicrotask(() => {
            this.hasPendingLoad = false;
            if (this.isDisconnected) {
                return;
            }
            if (!this._platform) {
                this.updateState({ loadFailed: true });
                logger.warn(`Cannot update: no platform available. limetype=${this.limetype}, objectid=${this.objectid}`);
                return;
            }
            this.resolveLimeType();
            this.loadLimeObject();
        });
    }
    /**
     * Prevent stale updates after the component disconnects.
     * Call from `disconnectedCallback()`.
     */
    disconnect() {
        this.isDisconnected = true;
    }
    findPlatform(hostElement) {
        const element = findParentElement(hostElement, this.hasPlatformProp);
        return element === null || element === void 0 ? void 0 : element.platform;
    }
    hasPlatformProp(element) {
        if (!('platform' in element)) {
            return false;
        }
        if (!element.platform) {
            return false;
        }
        return typeof element.platform === 'object';
    }
    resolveLimeType() {
        const repository = this._platform.get(n.LimeTypeRepository);
        this.updateState({
            limetypeData: repository.getLimeType(this.limetype),
        });
    }
    async loadLimeObject() {
        const limetype = this.limetype;
        const objectid = this.objectid;
        const repository = this._platform.get(n.LimeObjectRepository);
        const cached = repository.getObject(limetype, objectid);
        if (cached) {
            this.updateState({ limeobject: cached });
            return;
        }
        try {
            await repository.loadObject(limetype, objectid);
        }
        catch (error) {
            if (this.isStale(limetype, objectid)) {
                return;
            }
            this.updateState({ loadFailed: true });
            logger.error(`Failed to load ${limetype}/${objectid}`, error);
            return;
        }
        if (this.isStale(limetype, objectid)) {
            return;
        }
        this.updateState({
            limeobject: repository.getObject(limetype, objectid),
        });
    }
    isStale(limetype, objectid) {
        return (this.isDisconnected ||
            this.limetype !== limetype ||
            this.objectid !== objectid);
    }
    updateState(partial) {
        this.state = Object.assign(Object.assign({}, this.state), partial);
        if (!this.isDisconnected) {
            this.onStateChange(this.state);
        }
    }
}

const objectChipCss = () => `:host{display:inline-block;vertical-align:baseline}`;

const ObjectChip = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        /**
         * Platform instance. If not provided, the component will
         * walk the DOM to find a parent with a platform.
         *
         * :::note
         * The platform must be available when the component connects to
         * the DOM, either as a prop or via a parent element. Changing
         * the platform after the component has connected is not supported.
         * :::
         */
        /**
         * Defines the size of the chip.
         */
        this.size = 'default';
        this.data = { loadFailed: false };
        this.resolver = new ObjectResolver((data) => {
            this.data = data;
        });
    }
    connectedCallback() {
        this.resolver.connect(this.limetype, this.objectid, getElement(this), this.platform);
    }
    disconnectedCallback() {
        this.resolver.disconnect();
    }
    handlePropChange() {
        this.resolver.update(this.limetype, this.objectid);
    }
    render() {
        if (!this.resolver.resolvedPlatform) {
            return;
        }
        const icon = getIcon(this.data.limetypeData);
        return (h("limel-chip", { text: this.getChipText(), icon: icon, size: this.size, link: { href: getObjectUrl(this.limetype, this.objectid) }, loading: !this.data.limeobject && !this.data.loadFailed }));
    }
    getChipText() {
        var _a;
        if ((_a = this.data.limeobject) === null || _a === void 0 ? void 0 : _a.descriptive) {
            return this.data.limeobject.descriptive;
        }
        if (this.data.loadFailed) {
            return this.getErrorText();
        }
        return '';
    }
    getErrorText() {
        if (!this.resolver.resolvedPlatform) {
            return 'loading failed';
        }
        try {
            const translator = this.resolver.resolvedPlatform.get(n.Translate);
            return translator.get('webclient.limeobject.errors.load-failed');
        }
        catch (_a) {
            return 'loading failed';
        }
    }
    static get watchers() { return {
        "limetype": [{
                "handlePropChange": 0
            }],
        "objectid": [{
                "handlePropChange": 0
            }]
    }; }
};
ObjectChip.style = objectChipCss();

export { ObjectChip as limebb_object_chip };
