var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
import React, { forwardRef, memo, Suspense, isValidElement, useCallback, useMemo } from 'react';
import { WidgetCard } from './WidgetCard';
import { useShellStore } from '../stores/shellStore';
import { PageLoading } from '../UI/feedback/PageLoading';
const isRenderableComponent = (Component) => typeof Component === 'function' ||
    (Component &&
        typeof Component === 'object' &&
        Component !== null &&
        '$$typeof' in Component);
/**
 * Widget implementation for dashboards that correctly handles lazy-loading.
 */
const DashboardWidget = forwardRef((props, ref) => {
    const { widgetType, id, deleteCard, children, params: paramValues, setParams } = props, rest = __rest(props, ["widgetType", "id", "deleteCard", "children", "params", "setParams"]);
    const { className, style } = rest, widgetProps = __rest(rest, ["className", "style"]);
    const widgetStyle = Object.assign({}, (widgetProps.style || {}));
    if (style && typeof style === 'object') {
        if (Object.prototype.hasOwnProperty.call(style, 'height')) {
            widgetStyle.height = style.height;
        }
        if (Object.prototype.hasOwnProperty.call(style, 'width')) {
            widgetStyle.width = style.width;
        }
    }
    const widgetPropsWithClassName = Object.assign(Object.assign(Object.assign({}, widgetProps), (className ? { className } : {})), (Object.keys(widgetStyle).length ? { style: widgetStyle } : {}));
    const { getWidget, isValidWidget } = useShellStore();
    const onDelete = useCallback(() => {
        deleteCard === null || deleteCard === void 0 ? void 0 : deleteCard(id);
    }, [deleteCard, id]);
    const { Widget, params: paramDefs } = useMemo(() => {
        if (!(isValidWidget === null || isValidWidget === void 0 ? void 0 : isValidWidget(widgetType))) {
            return {};
        }
        const res = getWidget(widgetType);
        // If getWidget returns null or undefined, widget not found
        if (!res) {
            return {};
        }
        // If it's already a React.lazy component (LazyExoticComponent), use it directly
        // React.lazy components have a $$typeof property set to Symbol.for('react.lazy')
        if (res.$$typeof === Symbol.for('react.lazy')) {
            return { Widget: res, params: {} };
        }
        // Handle descriptor object format (widget with params)
        if (res && typeof res === 'object' && !isValidElement(res) && !res.then) {
            const widgetComp = res.Widget || res.default || null;
            return { Widget: widgetComp, params: res.params || {} };
        }
        // If we receive anything else, it's an unsupported format.
        console.warn(`getWidget returned an unexpected type for "${widgetType}":`, res);
        return {};
    }, [widgetType, getWidget, isValidWidget]);
    const params = useMemo(() => {
        if (!paramDefs)
            return paramValues || {};
        const defaultParams = Object.fromEntries(Object.entries(paramDefs).map(([key, { defaultValue }]) => [key, defaultValue]));
        return Object.assign(Object.assign({}, defaultParams), paramValues);
    }, [paramDefs, paramValues]);
    const setParam = useCallback((name, value) => setParams(id, { [name]: value }), [id, setParams]);
    if (!isValidWidget || !getWidget) {
        return (React.createElement("div", { ref: ref, className: className, style: style }, React.createElement(WidgetCard, Object.assign({}, widgetPropsWithClassName, { title: "Error" }), "isValidWidget or getWidget functions are not define")));
    }
    if (!Widget) {
        return (React.createElement("div", { ref: ref, className: className, style: style }, React.createElement(WidgetCard, Object.assign({}, widgetPropsWithClassName, { title: "Error" }), "Unknown widget type &ldquo;", widgetType, "&rdquo;")));
    }
    if (!isRenderableComponent(Widget)) {
        console.error(`DashboardWidget: widget "${widgetType}" resolved to a non-renderable component.`, Widget);
        return (React.createElement("div", { ref: ref, className: className, style: style }, React.createElement(WidgetCard, Object.assign({}, widgetPropsWithClassName, { title: "Error" }), "Unable to render widget type &ldquo;", widgetType, "&rdquo;")));
    }
    const widgetElement = (React.createElement(Widget, Object.assign({}, widgetPropsWithClassName, { id: id, params: params, setParam: setParam, onDelete: onDelete }), children));
    return (React.createElement("div", { ref: ref, className: className, style: style }, React.createElement(Suspense, { fallback: React.createElement(PageLoading, null) }, widgetElement)));
});
DashboardWidget.displayName = 'DashboardWidget';
const MemoizedDashboardWidget = memo(DashboardWidget);
MemoizedDashboardWidget.displayName = 'DashboardWidget';
export default MemoizedDashboardWidget;
//# sourceMappingURL=DashboardWidget.js.map