import QtQuick
import QtQuick.Controls
import Quickshell

import qs.Commons
import qs.Modules.MainScreen
import qs.Services.UI
import qs.Widgets

SmartPanel {
  id: root

  // Disable when overlay mode is enabled (LauncherOverlayWindow handles it)
  enabled: !Settings.data.appLauncher.overviewLayer
  visible: !Settings.data.appLauncher.overviewLayer

  // Reference to core (set after panelContent loads)
  property var launcherCoreRef: null

  // Expose core launcher for external access (e.g., IPC)
  readonly property string searchText: launcherCoreRef ? launcherCoreRef.searchText : ""
  readonly property int selectedIndex: launcherCoreRef ? launcherCoreRef.selectedIndex : 0
  readonly property var results: launcherCoreRef ? launcherCoreRef.results : []
  readonly property var activeProvider: launcherCoreRef ? launcherCoreRef.activeProvider : null
  readonly property var currentProvider: launcherCoreRef ? launcherCoreRef.currentProvider : null
  readonly property bool isGridView: launcherCoreRef ? launcherCoreRef.isGridView : false
  readonly property int gridColumns: launcherCoreRef ? launcherCoreRef.gridColumns : 5

  function setSearchText(text) {
    if (launcherCoreRef)
      launcherCoreRef.setSearchText(text);
  }

  // Preview panel support
  readonly property bool previewActive: {
    if (!launcherCoreRef)
      return false;
    var provider = launcherCoreRef.activeProvider;
    if (!provider || !provider.hasPreview)
      return false;
    if (!Settings.data.appLauncher.enableClipPreview)
      return false;
    return selectedIndex >= 0 && results && !!results[selectedIndex];
  }
  readonly property int previewPanelWidth: Math.round(400 * Style.uiScaleRatio)

  // Panel sizing
  readonly property int listPanelWidth: Math.round(500 * Style.uiScaleRatio)
  readonly property int totalBaseWidth: listPanelWidth + Style.margin2L

  preferredWidth: totalBaseWidth
  preferredHeight: Math.round(600 * Style.uiScaleRatio)
  preferredWidthRatio: 0.25
  preferredHeightRatio: 0.5

  // Positioning
  readonly property string screenBarPosition: Settings.getBarPositionForScreen(screen?.name)
  readonly property string panelPosition: {
    if (Settings.data.appLauncher.position === "follow_bar") {
      if (screenBarPosition === "left" || screenBarPosition === "right") {
        return `center_${screenBarPosition}`;
      } else {
        return `${screenBarPosition}_center`;
      }
    } else {
      return Settings.data.appLauncher.position;
    }
  }
  panelAnchorHorizontalCenter: !root.useButtonPosition && (panelPosition === "center" || panelPosition.endsWith("_center"))
  panelAnchorVerticalCenter: !root.useButtonPosition && panelPosition === "center"
  panelAnchorLeft: !root.useButtonPosition && panelPosition !== "center" && panelPosition.endsWith("_left")
  panelAnchorRight: !root.useButtonPosition && panelPosition !== "center" && panelPosition.endsWith("_right")
  panelAnchorBottom: !root.useButtonPosition && panelPosition.startsWith("bottom_")
  panelAnchorTop: !root.useButtonPosition && panelPosition.startsWith("top_")

  panelContent: Rectangle {
    id: ui
    color: "transparent"
    opacity: launcherCore.resultsReady ? 1.0 : 0.0

    Component.onCompleted: root.launcherCoreRef = launcherCore

    Behavior on opacity {
      NumberAnimation {
        duration: Style.animationFast
        easing.type: Easing.OutCirc
      }
    }

    // Preview Panel (external) - uses provider's preview component
    NDropShadow {
      source: previewBox
      anchors.fill: previewBox
      autoPaddingEnabled: true
      visible: previewBox.visible
      z: previewBox.z - 1
    }

    NBox {
      id: previewBox
      visible: root.previewActive
      width: root.previewPanelWidth
      height: Math.round(400 * Style.uiScaleRatio)
      forceOpaque: true // no blur for now
      x: root.panelAnchorRight ? -(root.previewPanelWidth + Style.marginM) : ui.width + Style.marginM
      y: {
        var view = launcherCore.resultsView;
        if (!view)
          return Style.marginL;
        var row = launcherCore.isGridView ? Math.floor(launcherCore.selectedIndex / launcherCore.gridColumns) : launcherCore.selectedIndex;
        var gridCellSize = Math.floor((root.listPanelWidth - Style.margin2XS - ((launcherCore.targetGridColumns - 1) * Style.marginS)) / launcherCore.targetGridColumns);
        var itemHeight = launcherCore.isGridView ? (gridCellSize + Style.marginXXS) : (launcherCore.entryHeight + (view.spacing || 0));
        var yPos = row * itemHeight - (view.contentY || 0);
        var mapped = view.mapToItem(ui, 0, yPos);
        return Math.max(Style.marginL, Math.min(mapped.y, ui.height - previewBox.height - Style.marginL));
      }
      z: -1

      opacity: visible ? 1.0 : 0.0
      Behavior on opacity {
        NumberAnimation {
          duration: Style.animationFast
        }
      }
      Behavior on y {
        NumberAnimation {
          duration: Style.animationFast
          easing.type: Easing.OutCubic
        }
      }

      Loader {
        id: previewLoader
        anchors.fill: parent
        active: root.previewActive
        source: {
          if (!active)
            return "";
          var provider = launcherCore.activeProvider;
          if (provider && provider.previewComponentPath)
            return provider.previewComponentPath;
          return "";
        }

        onLoaded: updatePreviewItem()
        onItemChanged: updatePreviewItem()

        function updatePreviewItem() {
          if (!item || launcherCore.selectedIndex < 0 || !launcherCore.results[launcherCore.selectedIndex])
            return;
          var provider = launcherCore.activeProvider;
          if (provider && provider.getPreviewData) {
            item.currentItem = provider.getPreviewData(launcherCore.results[launcherCore.selectedIndex]);
          } else {
            item.currentItem = launcherCore.results[launcherCore.selectedIndex];
          }
        }
      }
    }

    // Core launcher (state, providers, UI)
    LauncherCore {
      id: launcherCore
      anchors.fill: parent
      screen: root.screen
      isOpen: root.isPanelOpen
      onRequestClose: root.close()
      // Defer so the signal emission completes before SmartPanel
      // sets isPanelOpen=false and the contentLoader destroys us.
      onRequestCloseImmediately: Qt.callLater(root.closeImmediately)
    }

    // Update preview when selection changes
    Connections {
      target: launcherCore
      function onSelectedIndexChanged() {
        if (previewLoader.item)
          previewLoader.updatePreviewItem();
      }
    }
  }
}
