import QtQuick
import Quickshell
import qs.Commons
import qs.Services.Noctalia
import qs.Services.UI

Item {
  id: root

  required property string widgetId
  required property var widgetScreen
  required property var widgetProps

  property string section: widgetProps && widgetProps.section || ""
  property int sectionIndex: widgetProps && widgetProps.sectionWidgetIndex || 0

  // Don't reserve space unless the loaded widget is really visible
  implicitWidth: getImplicitSize(loader.item, "implicitWidth")
  implicitHeight: getImplicitSize(loader.item, "implicitHeight")

  function getImplicitSize(item, prop) {
    return (item && item.visible) ? item[prop] : 0;
  }

  readonly property bool _isPlugin: ControlCenterWidgetRegistry.isPluginWidget(widgetId)

  function _loadPluginWidget() {
    var comp = ControlCenterWidgetRegistry.getWidget(widgetId);
    if (!comp)
      return;
    var pluginId = widgetId.substring(7); // Remove "plugin:" prefix
    var api = PluginService.getPluginAPI(pluginId);
    loader.setSource(comp.url, api ? {
                                       "pluginApi": api
                                     } : {});
  }

  Loader {
    id: loader
    anchors.fill: parent
    asynchronous: false

    // Core widgets use sourceComponent; plugin widgets use setSource()
    // so pluginApi is available from the first binding evaluation.
    Component.onCompleted: {
      if (root._isPlugin) {
        root._loadPluginWidget();
      } else {
        sourceComponent = Qt.binding(function () {
          return ControlCenterWidgetRegistry.getWidget(widgetId);
        });
      }
    }

    onLoaded: {
      if (!item)
        return;

      // Apply properties to loaded widget
      for (var prop in widgetProps) {
        if (item.hasOwnProperty(prop)) {
          item[prop] = widgetProps[prop];
        }
      }

      // Set screen property
      if (item.hasOwnProperty("screen")) {
        item.screen = widgetScreen;
      }

      // Call custom onLoaded if it exists
      if (item.hasOwnProperty("onLoaded")) {
        item.onLoaded();
      }
    }

    Component.onDestruction: {
      // Explicitly clear references
      widgetProps = null;
    }
  }

  // Error handling
  Component.onCompleted: {
    if (!ControlCenterWidgetRegistry.hasWidget(widgetId)) {
      Logger.w("ControlCenterWidgetLoader", "Widget not found in registry:", widgetId);
      // Retry briefly in case the registry initializes after this component
      retryTimer.start();
    }
  }

  // Retry mechanism to cope with early evaluation before registry is ready
  Timer {
    id: retryTimer
    interval: 150
    repeat: true
    running: false
    property int attempts: 0
    onTriggered: {
      attempts += 1;
      if (ControlCenterWidgetRegistry.hasWidget(widgetId)) {
        loader.sourceComponent = ControlCenterWidgetRegistry.getWidget(widgetId);
        stop();
        attempts = 0;
        return;
      }
      if (attempts >= 20) { // ~3s max
        stop();
        attempts = 0;
        Logger.w("ControlCenterWidgetLoader", "Giving up waiting for widget:", widgetId);
      }
    }
  }
}
