import { Host, h } from "@stencil/core";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import "dayjs/locale/nl";
import { sensorInfo } from "../../utils/sensorInfo";
import { includes, isEmpty, isNil } from "lodash-es";
import { getStore } from "../../store";
import { getSafeRelativeTime } from "../../utils/safe-relative-time";
import { watchStoreLocale } from "../../utils/locale-state";
import { getStoreUnavailableError } from "../../utils/store-error";
export class LsStatusItem {
    constructor() {
        this.store = null;
        this.isComponentMounted = false;
        this.storeUnsubscribe = null;
        this.localeUnsubscribe = null;
        /**
         * Selects which label set to use for the sensor label.
         */
        this.labelType = "default";
        /**
         * Specifies the IDs and labels of the sensors that are allowed to be displayed.
         */
        this.allowedIds = "10,23,500,501,502,503,514,515,524,590";
        this.sensorsArray = this.allowedIds
            .split(",")
            .filter((id) => id.trim() !== "")
            .map((id) => parseInt(id.trim(), 10));
        /**
         * Centralized error state for tracking component errors
         */
        this.errorState = {
            hasError: false,
            messageKey: undefined,
            type: "",
        };
        this.updateData = (sensorData) => {
            var _a;
            // Don't update if component is unmounted
            if (!this.isComponentMounted)
                return;
            // Reset timer to prevent waiting on next timer tick
            this.clearTimer();
            this.setTimer();
            // If sensorData is empty, we don't need to update the data
            if (isEmpty(sensorData))
                return;
            // The sensor values of 501 and 514 and 515 are zero based, but we need to show them one based
            if (includes([501, 514, 515], this.sensorId) &&
                !isNaN(parseInt(sensorData.values[this.sensorId], 10))) {
                this.sensorData = sensorData.values[this.sensorId] + 1;
            }
            else {
                this.sensorData = sensorData.values[this.sensorId];
            }
            // Calculate relative timestamp
            this.timestamp = getSafeRelativeTime(sensorData.updated[this.sensorId], (_a = this.store) === null || _a === void 0 ? void 0 : _a.state.locale);
            this.updateErrorState();
        };
    }
    /**
     * Handles a change of the sensor ID
     */
    watchPropHandler() {
        // Clean up before reloading
        if (this.storeUnsubscribe !== null) {
            this.storeUnsubscribe();
            this.storeUnsubscribe = null;
        }
        if (this.localeUnsubscribe !== null) {
            this.localeUnsubscribe();
            this.localeUnsubscribe = null;
        }
        this.clearTimer();
        this.componentWillLoad();
    }
    get isValidSensorId() {
        return this.sensorsArray.includes(this.sensorId);
    }
    get dataLabel() {
        var _a, _b;
        if (this.sensorId === null || this.sensorId === undefined) {
            return "";
        }
        if (!this.isValidSensorId) {
            return this.store.t("ui:sensor.unknown_id");
        }
        const baseLabel = this.labelType === "short"
            ? sensorInfo.getShortLabel(this.sensorId, (_a = this.store) === null || _a === void 0 ? void 0 : _a.state.locale)
            : sensorInfo.getLabel(this.sensorId, (_b = this.store) === null || _b === void 0 ? void 0 : _b.state.locale);
        if ([
            LsStatusItem.SENSOR_ID_GEZOND_A,
            LsStatusItem.SENSOR_ID_GEZOND_B,
        ].includes(this.sensorId)) {
            const labelSuffixOk = this.store.t("ui:sensor.label_suffix_ok");
            const labelSuffixHealthy = this.store.t("ui:sensor.label_suffix_healthy");
            if (this.labelType === "short") {
                return baseLabel.replace(labelSuffixOk, "");
            }
            return baseLabel.replace(labelSuffixHealthy, "");
        }
        return baseLabel;
    }
    /**
     * Updates the error state based on current component conditions
     */
    updateErrorState() {
        var _a;
        if (this.store === null) {
            this.errorState = getStoreUnavailableError((_a = this.store) === null || _a === void 0 ? void 0 : _a.state.locale);
            return;
        }
        if (this.store.state.error.hasError) {
            this.errorState = {
                hasError: true,
                messageKey: this.store.state.error.messageKey,
                type: this.store.state.error.type,
            };
            this.clearTimer();
            return;
        }
        // No error detected
        this.errorState = {
            hasError: false,
            messageKey: undefined,
            type: "",
        };
    }
    setTimer() {
        // Clear any existing timer first
        this.clearTimer();
        // Used to update relative timestamps
        this.timer = window.setInterval(() => {
            var _a, _b;
            // Check if still mounted and store exists
            if (!this.isComponentMounted) {
                this.clearTimer();
                return;
            }
            // Access store data only when needed
            const sensorData = (_b = (_a = this.store) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.currentSensorData;
            if (!isNil(sensorData)) {
                this.updateData(sensorData);
            }
        }, 20000);
    }
    clearTimer() {
        window.clearInterval(this.timer);
        this.timer = null;
    }
    connectedCallback() {
        this.isComponentMounted = true;
        this.setTimer();
    }
    disconnectedCallback() {
        this.isComponentMounted = false;
        this.clearTimer();
        // Unsubscribe from store changes
        if (this.storeUnsubscribe !== null) {
            this.storeUnsubscribe();
            this.storeUnsubscribe = null;
        }
        if (this.localeUnsubscribe !== null) {
            this.localeUnsubscribe();
            this.localeUnsubscribe = null;
        }
    }
    async componentWillLoad() {
        dayjs.extend(relativeTime);
        this.store = await getStore(this.idKey);
        if (this.localeUnsubscribe !== null) {
            this.localeUnsubscribe();
        }
        this.localeUnsubscribe = watchStoreLocale(this, this.store, () => {
            if (!this.isValidSensorId) {
                this.sensorData = this.store.t("ui:sensor.valid_options");
                this.timestamp = this.sensorsArray.join(", ");
                return;
            }
            this.updateData(this.store.state.currentSensorData);
        }, { skipForceUpdate: true });
        if (!this.isValidSensorId) {
            this.sensorData = this.store.t("ui:sensor.valid_options");
            this.timestamp = this.sensorsArray.join(", ");
            this.clearTimer();
            return;
        }
        // If timer is cleared we need to start it again
        if (this.timer === null) {
            this.setTimer();
        }
        this.updateData(this.store.state.currentSensorData);
        // Store the unsubscribe function for cleanup
        this.storeUnsubscribe = this.store.onChange("currentSensorData", (sensorData) => {
            this.updateData(sensorData);
        });
    }
    render() {
        var _a;
        const sensorIdLabel = this.sensorId === null || this.sensorId === undefined
            ? this.store.t("ui:sensor.not_specified")
            : this.sensorId;
        const fallbackLabel = this.store.t("ui:sensor.fallback_label", {
            id: sensorIdLabel,
        });
        return (h(Host, { key: 'b22658860e862850d17c186608709d840a87aacc' }, h("slot", { key: '321c34086cac3058674a8498feba4c658ae29cd3' }), h("dl", { key: '1e7f9d2b1e3d24ca4e783a5514c73f9fb09d60bb', class: "ls-status-item" }, h("dt", { key: 'c772dabeb5717a8e53b3faed6f69a65dbff52a91', class: "label" }, this.dataLabel || fallbackLabel), h("dd", { key: '9f24db4e9eccf83cbae25c1c17bb480fb37ce0c0', class: "value" }, sensorInfo.getValue(this.sensorData, this.sensorId, (_a = this.store) === null || _a === void 0 ? void 0 : _a.state.locale) ||
            "-"), h("dd", { key: '964a5e7bf0c8eb586899f004de7b4717973a9c4e', class: "timestamp" }, this.timestamp))));
    }
    static get is() { return "ls-status-item"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["ls-status-item.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["ls-status-item.css"]
        };
    }
    static get properties() {
        return {
            "sensorId": {
                "type": "number",
                "attribute": "sensor-id",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The ID of the sensor item that is to be displayed."
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "idKey": {
                "type": "string",
                "attribute": "id-key",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The unique key that is used to identify store data."
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "labelType": {
                "type": "string",
                "attribute": "label-type",
                "mutable": false,
                "complexType": {
                    "original": "\"default\" | \"short\"",
                    "resolved": "\"default\" | \"short\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Selects which label set to use for the sensor label."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "\"default\""
            }
        };
    }
    static get states() {
        return {
            "sensorData": {},
            "timestamp": {},
            "errorState": {}
        };
    }
    static get watchers() {
        return [{
                "propName": "sensorId",
                "methodName": "watchPropHandler"
            }];
    }
}
LsStatusItem.SENSOR_ID_GEZOND_A = 10;
LsStatusItem.SENSOR_ID_GEZOND_B = 524;
//# sourceMappingURL=ls-status-item.js.map
