import QtQuick
import Quickshell
import Quickshell.Wayland
import qs.Commons
import qs.Services.Compositor
import qs.Services.UI
import qs.Widgets

// Generic full-screen popup window for menus and context menus
// This is a top-level PanelWindow (sibling to MainScreen, not nested inside it)
// Provides click-outside-to-close functionality for any popup content
// Loads TrayMenu by default but can show context menus via showContextMenu()
PanelWindow {
  id: root

  required property ShellScreen screen
  property string windowType: "popupmenu"  // Used for namespace and registration

  // Content item to display (set by the popup that uses this window)
  property var contentItem: null

  // Expose the trayMenu Loader directly (for backward compatibility)
  readonly property alias trayMenuLoader: trayMenuLoader

  // Dynamic context menu callback for items in other windows (e.g., desktop widgets)
  property var dynamicMenuCallback: null

  anchors.top: true
  anchors.left: true
  anchors.right: true
  anchors.bottom: true
  visible: false
  color: "transparent"

  // Use Top layer for proper event handling, but on labwc use Bottom
  // to avoid stealing input from popups while still catching outside clicks.
  // However, when a dialog is open, always use Top so dialogs appear above apps.
  WlrLayershell.layer: (CompositorService.isLabwc && !hasDialog) ? WlrLayer.Bottom : WlrLayer.Top
  WlrLayershell.keyboardFocus: hasDialog ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
  WlrLayershell.namespace: "noctalia-" + windowType + "-" + (screen?.name || "unknown")
  WlrLayershell.exclusionMode: ExclusionMode.Ignore

  // Track if a dialog is currently open (needed for keyboard focus)
  property bool hasDialog: false

  // Register with PanelService so widgets can find this window
  Component.onCompleted: {
    objectName = "popupMenuWindow-" + (screen?.name || "unknown");
    PanelService.registerPopupMenuWindow(screen, root);
  }

  Component.onDestruction: {
    PanelService.unregisterPopupMenuWindow(screen);
  }

  // Load TrayMenu as the default content
  Loader {
    id: trayMenuLoader
    source: Quickshell.shellDir + "/Modules/Bar/Extras/TrayMenu.qml"
    onLoaded: {
      if (item) {
        item.screen = root.screen;
        // Set the loaded item as default content
        root.contentItem = item;
      }
    }
  }

  // Dynamic context menu - created as child of this window (Top layer) so input works correctly
  // Used for items in other windows like desktop widgets (bottom layer)
  NPopupContextMenu {
    id: dynamicMenu
    visible: false
    screen: root.screen
    minWidth: 180

    onTriggered: (action, item) => {
                   if (root.dynamicMenuCallback) {
                     // Callback returns true if it will handle closing (e.g., opening a dialog)
                     var handled = root.dynamicMenuCallback(action);
                     if (!handled) {
                       root.close();
                     }
                   } else {
                     root.close();
                   }
                 }
  }

  function open() {
    visible = true;
    BarService.popupOpen = true;
  }

  // Show a context menu (temporarily replaces TrayMenu as content)
  function showContextMenu(menu) {
    if (menu) {
      contentItem = menu;
      open();
    }
  }

  // Show a dynamic context menu with model and callback at screen coordinates
  // Used for items in other window layers (e.g., desktop widgets in bottom layer)
  function showDynamicContextMenu(model, screenX, screenY, callback) {
    dynamicMenu.model = model;
    dynamicMenuCallback = callback;

    // Use the anchor point item for positioning at absolute coordinates
    dynamicMenu.anchorItem = anchorPoint;
    anchorPoint.x = screenX;
    anchorPoint.y = screenY;

    contentItem = dynamicMenu;
    dynamicMenu.visible = true;
    open();
  }

  // Invisible anchor point for dynamic menu positioning
  Item {
    id: anchorPoint
    width: 1
    height: 1
  }

  // Hide just the dynamic menu without closing the popup window
  // Used when transitioning from context menu to a dialog
  function hideDynamicMenu() {
    dynamicMenu.visible = false;
  }

  function close() {
    visible = false;
    BarService.popupOpen = false;
    // Call close/hide method on current content
    if (contentItem) {
      if (typeof contentItem.hideMenu === "function") {
        contentItem.hideMenu();
      } else if (typeof contentItem.close === "function") {
        contentItem.close();
      }
    }
    // Hide dynamic menu
    dynamicMenu.visible = false;
    dynamicMenuCallback = null;
    // Restore TrayMenu as default content
    if (trayMenuLoader.item) {
      contentItem = trayMenuLoader.item;
    }
  }

  // Full-screen click catcher - click anywhere outside content closes the window
  MouseArea {
    anchors.fill: parent
    acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
    onClicked: root.close()
  }

  // Container for dialogs that need a full-screen Item parent (e.g., Qt Popup)
  Item {
    id: dialogContainer
    anchors.fill: parent
  }

  // Expose the dialog container for external use
  readonly property alias dialogParent: dialogContainer
}
