#!/usr/bin/python3

import sys

from PySide6 import QtCore
from PySide6.QtCore import QCoreApplication, QObject, Slot
from PySide6.QtDBus import (
    QDBusConnection,
    QDBusInterface,
    QDBusMessage,
    QDBusObjectPath,
)

BUS_NAME = "org.freedesktop.portal.Desktop"
OBJECT_PATH = "/org/freedesktop/portal/desktop"
SHORTCUT_IFACE = "org.freedesktop.portal.GlobalShortcuts"
REQUEST_IFACE = "org.freedesktop.portal.Request"

shortcuts = [
    (
        "binding1",
        {
            "description": "Binding #1",
            # "preferred-trigger": "CTRL+a",
        },
    ),
    (
        "binding2",
        {
            "description": "Binding #2",
            # "preferred-trigger": "CTRL+b",
        },
    ),
]


class PortalGlobalShortcuts(QObject):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.session = None

        self.bus = QDBusConnection.sessionBus()

        print("Creating session...")
        self.createSession()

    def createSession(self):
        options = {
            "handle_token": "mytest2",
            "session_handle_token": "Mytest2",
        }

        self.portal = QDBusInterface(BUS_NAME, OBJECT_PATH, SHORTCUT_IFACE, self.bus)
        msg = self.portal.call("CreateSession", options)
        if msg.type() == QDBusMessage.ErrorMessage:
            print("Error creating session:", msg.errorMessage())
            return

        # Get reply path (the request object)
        reply_path = msg.arguments()[0]
        print("Session created, waiting for Response signal on:", reply_path)

        self.response = QDBusInterface(BUS_NAME, reply_path.path(), REQUEST_IFACE, self.bus)
        self.response.connect(QtCore.SIGNAL("Response(uint,QVariantMap)"), self.onCreateSessionResponse)

        # iface = QDBusInterface(
        #     BUS_NAME,
        #     OBJECT_PATH,
        #     "org.freedesktop.DBus.Introspectable",
        #     self.bus,
        # )
        # xml = iface.call("Introspect").arguments()[0]
        # print(xml)

        self.portal.connect(QtCore.SIGNAL("Activated(QDBusObjectPath,QString,qulonglong,QVariantMap)"), self.onKeyActivated)
        self.portal.connect(QtCore.SIGNAL("Deactivated(QDBusObjectPath,QString,qulonglong,QVariantMap)"), self.onKeyDeactivated)

    @Slot("uint", "a{sv}")
    def onCreateSessionResponse(self, response, results):
        print("CreateSession callback received")

        self.session = QDBusObjectPath(results["session_handle"])
        print("Session handle:", self.session)

        self.listShortcuts()
        self.bindShortcuts()

    def bindShortcuts(self):
        # <method name="BindShortcuts">
        #   <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QList&lt;QPair&lt;QString,QVariantMap&gt;&gt;"/>
        #   <annotation name="org.qtproject.QtDBus.QtTypeName.In3" value="QVariantMap"/>
        #   <arg type="o" name="session_handle" direction="in"/>
        #   <arg type="a(sa{sv})" name="shortcuts" direction="in"/>
        #   <arg type="s" name="parent_window" direction="in"/>
        #   <arg type="a{sv}" name="options" direction="in"/>
        #   <arg type="o" name="request_handle" direction="out"/>
        # </method>
        msg = self.portal.call("BindShortcuts", self.session, shortcuts, "", {})
        if msg.type() == QDBusMessage.ErrorMessage:
            print("BindShortcuts failed:", msg.errorMessage())
        else:
            print("Shortcuts bound.")

    def listShortcuts(self):
        msg = self.portal.call("ListShortcuts", self.session, {})
        if msg.type() == QDBusMessage.ErrorMessage:
            print("ListShortcuts failed:", msg.errorMessage())
        else:
            print("ListShortcuts called.")

    @Slot("o", "s", "t", "a{sv}")
    def onKeyActivated(self, session_handle, shortcut_id, timestamp, options):
        print(f"{shortcut_id} activated")

    @Slot("o", "s", "u", "a{sv}")
    def onKeyDeactivated(self, session_handle, shortcut_id, timestamp, options):
        print(f"{shortcut_id} deactivated")

    @Slot("o", "a(ssa{sv})")
    def onShortcutsChanged(self, session_handle, shortcuts_list):
        print("Shortcuts changed:", shortcuts_list)


if __name__ == "__main__":
    app = QCoreApplication(sys.argv)
    portal = PortalGlobalShortcuts()
    sys.exit(app.exec())
