import bpy
from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton
from PySide6.QtCore import QTimer, Qt, QPoint
import win32gui
import win32con


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # Set the window to be frameless
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setFixedWidth(300)

        # Set a custom background color for the window using stylesheets
        self.setStyleSheet("background-color: lightblue;")

        # Create a central widget with a layout
        widget = QWidget()
        layout = QVBoxLayout()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

        # Create and configure a button
        button = QPushButton('Add UVSphere')
        button.setFixedSize(280, 50)
        button.clicked.connect(self.button_pressed)
        layout.addWidget(button)

        # Timer to check Blender focus and update the window
        self.timer = QTimer()
        self.timer.timeout.connect(self.update_window)
        self.timer.start(100)

        # Initialize a counter for object placement
        self.num = 0

        # Get Blender's window handle
        self.blender_hwnd = self.get_blender_window_handle()
        if self.blender_hwnd:
            print(f"Blender window handle: {self.blender_hwnd}")
        else:
            print("Blender window handle not found. Ensure the title contains 'Blender'.")

        # Variable to store the position of the mouse when dragging starts
        self.old_pos = None

        # "Do Once" state
        self.do_once_triggered = False

    def button_pressed(self):
        # Create a UV Sphere at a specific location based on the counter
        with bpy.context.temp_override(window=bpy.context.window_manager.windows[0]):
            bpy.ops.mesh.primitive_uv_sphere_add(location=(2.0 * self.num, 0, 0,))
        self.num += 1

    def update_window(self):
        """Update the PySide6 window color and topmost state based on Blender's focus state."""
        # Get the foreground window (currently focused)
        current_hwnd = win32gui.GetForegroundWindow()
        print(f"Blender HWND: {self.blender_hwnd}, Current Foreground HWND: {current_hwnd}")

        # Check if Blender is focused
        is_blender_focused = current_hwnd == self.blender_hwnd
        is_qt_focused = current_hwnd == int(self.winId())

        if is_blender_focused:
            self.setStyleSheet("background-color: lightblue;")  # Blender focused
            self.set_topmost(True)
            self.reset_do_once()  # Reset "Do Once" when Blender is focused

        elif is_qt_focused:
            self.setStyleSheet("background-color: red;")  # Qt window focused
            self.set_topmost(False)
            self.reset_do_once()  # Reset "Do Once" when Qt window is focused

        else:
            self.setStyleSheet("background-color: green;")  # Neither Blender nor Qt focused
            self.set_topmost(False)

            # If the condition is met and "Do Once" hasn't been triggered yet
            if not self.do_once_triggered:
                self.do_once()
                self.do_once_triggered = True

        # Update window title with the active object's name
        with bpy.context.temp_override(window=bpy.context.window_manager.windows[0]):
            title = bpy.context.active_object.name if bpy.context.active_object else 'NONE'
            self.setWindowTitle(title)

    def set_topmost(self, topmost):
        """Set the topmost state of the window."""
        hwnd = int(self.winId())
        flag = win32con.HWND_TOPMOST if topmost else win32con.HWND_NOTOPMOST
        win32gui.SetWindowPos(
            hwnd, flag, 0, 0, 0, 0,
            win32con.SWP_NOMOVE | win32con.SWP_NOSIZE | win32con.SWP_NOACTIVATE
        )

    def mousePressEvent(self, event):
        """Handle the start of a drag action."""
        if event.button() == Qt.LeftButton:
            self.old_pos = event.globalPosition().toPoint()

    def mouseMoveEvent(self, event):
        """Handle dragging the window."""
        if self.old_pos:
            delta = event.globalPosition().toPoint() - self.old_pos
            self.move(self.pos() + delta)
            self.old_pos = event.globalPosition().toPoint()

    def mouseReleaseEvent(self, event):
        """Reset the drag state."""
        if event.button() == Qt.LeftButton:
            self.old_pos = None

    def get_blender_window_handle(self):
        """Get Blender's window handle by searching for its title."""
        def enum_windows_callback(hwnd, results):
            title = win32gui.GetWindowText(hwnd)
            if "Blender" in title:  # Adjust this to match your Blender window title
                results.append(hwnd)

        results = []
        win32gui.EnumWindows(enum_windows_callback, results)
        if results:
            print(f"Found Blender window(s): {results}")
            return results[0]  # Return the first match
        return None

    def reset_do_once(self):
        """Reset the 'Do Once' functionality."""
        self.do_once_triggered = False

    def do_once(self):
        """Perform the 'Do Once' operation when Qt window turns green."""
        print("Performing 'Do Once' operation...")

        # Push the Qt window two steps down in the Z-order
        hwnd = int(self.winId())
        # First, push to HWND_NOTOPMOST (one step down)
        win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST, 0, 0, 0, 0,
                              win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)
        # Then, push to HWND_BOTTOM (second step down)
        win32gui.SetWindowPos(hwnd, win32con.HWND_BOTTOM, 0, 0, 0, 0,
                              win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)

    def closeEvent(self, event):
        # Stop the timer when the window is closed
        self.timer.stop()
        event.accept()


# Ensure QApplication is running before creating the window
if QApplication.instance() is None:
    app = QApplication(["blender"])


# Create and show the main window
window = MainWindow()
window.show()
