import sys
import time
import pickle
import logging
from threading import Thread, Lock, Event
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import (
    Qt, QSize, QTimer, pyqtSignal, QObject, QPropertyAnimation, QEasingCurve
)
from PyQt5.QtGui import QIcon, QFont, QPixmap, QColor
from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QPushButton, QListWidget, QVBoxLayout,
    QWidget, QFileDialog, QMessageBox, QHBoxLayout, QLabel, QTabWidget,
    QFrame, QSplitter, QSizePolicy, QLineEdit, QAbstractItemView, QAction,
    QToolButton, QProgressBar, QCheckBox, QDialog, QDialogButtonBox,
    QFormLayout, QComboBox, QTextEdit, QListWidgetItem, QMenu, QGroupBox,
    QGraphicsDropShadowEffect, QStackedLayout, QMenuBar, QStatusBar,
    QSpacerItem, QStyle, QStyleOptionTab
)
from pynput import mouse, keyboard
from pynput.keyboard import Key, Listener as KeyboardListener, KeyCode, GlobalHotKeys

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# Data structure to hold events
class MacroEvent:
    """
    Represents a single macro event with its type, details, and timestamp.
    """
    def __init__(self, event_type, details, timestamp):
        self.event_type = event_type  # 'mouse_move', 'mouse_click', 'key_press', etc.
        self.details = details        # Details like position, button, key
        self.timestamp = timestamp    # Time since the last event

# Signals class for inter-thread communication
class Signals(QObject):
    """
    Defines custom signals for communication between threads and the main GUI.
    """
    event_recorded = pyqtSignal(object)
    recording_finished = pyqtSignal()
    playback_finished = pyqtSignal()
    playback_error = pyqtSignal(str)
    toggle_record = pyqtSignal()
    toggle_play = pyqtSignal()

# Worker class for recording events
class RecorderWorker(QObject):
    """
    Handles the recording of mouse and keyboard events in a separate thread.
    """
    def __init__(self, signals):
        super().__init__()
        self.signals = signals
        self.is_recording = False
        self.start_time = None
        self.last_time = None
        self.events = []
        self.lock = Lock()
        self.mouse_listener = None
        self.keyboard_listener = None
        self.stop_event = Event()

    def start_recording(self):
        """
        Initializes the recording by setting up listeners for mouse and keyboard events.
        """
        with self.lock:
            self.is_recording = True
            self.events = []
            self.start_time = time.time()
            self.last_time = self.start_time
            logging.info("Recording started.")

        # Define event handlers
        with mouse.Listener(
            on_move=self.on_move,
            on_click=self.on_click,
            on_scroll=self.on_scroll
        ) as self.mouse_listener, \
             keyboard.Listener(
                on_press=self.on_press,
                on_release=self.on_release
             ) as self.keyboard_listener:
            self.mouse_listener.join()
            self.keyboard_listener.join()

    def stop_recording(self):
        """
        Stops the recording by stopping the listeners.
        """
        with self.lock:
            if not self.is_recording:
                return
            self.is_recording = False
            logging.info("Recording stopped.")
            self.stop_event.set()

        if self.mouse_listener and self.mouse_listener.running:
            self.mouse_listener.stop()
        if self.keyboard_listener and self.keyboard_listener.running:
            self.keyboard_listener.stop()
        self.signals.recording_finished.emit()

    def on_move(self, x, y):
        """
        Handles mouse movement events.
        """
        with self.lock:
            if not self.is_recording:
                return
            current_time = time.time()
            delta = current_time - self.last_time
            self.last_time = current_time
            event = MacroEvent('mouse_move', {'position': (x, y)}, delta)
            self.events.append(event)
            self.signals.event_recorded.emit(event)
            logging.debug(f"Mouse moved to {(x, y)} with delta {delta}")

    def on_click(self, x, y, button, pressed):
        """
        Handles mouse click events.
        """
        with self.lock:
            if not self.is_recording:
                return
            current_time = time.time()
            delta = current_time - self.last_time
            self.last_time = current_time
            event_type = 'mouse_click_pressed' if pressed else 'mouse_click_released'
            event = MacroEvent(event_type, {'position': (x, y), 'button': button}, delta)
            self.events.append(event)
            self.signals.event_recorded.emit(event)
            action = 'pressed' if pressed else 'released'
            logging.debug(f"Mouse {action} at {(x, y)} with delta {delta}")

    def on_scroll(self, x, y, dx, dy):
        """
        Handles mouse scroll events.
        """
        with self.lock:
            if not self.is_recording:
                return
            current_time = time.time()
            delta = current_time - self.last_time
            self.last_time = current_time
            event = MacroEvent('mouse_scroll', {'position': (x, y), 'dx': dx, 'dy': dy}, delta)
            self.events.append(event)
            self.signals.event_recorded.emit(event)
            logging.debug(f"Mouse scrolled at {(x, y)} with delta {delta}")

    def on_press(self, key):
        """
        Handles key press events.
        """
        with self.lock:
            if not self.is_recording:
                return
            current_time = time.time()
            delta = current_time - self.last_time
            self.last_time = current_time
            event = MacroEvent('key_press', {'key': key}, delta)
            self.events.append(event)
            self.signals.event_recorded.emit(event)
            logging.debug(f"Key pressed: {key} with delta {delta}")

    def on_release(self, key):
        """
        Handles key release events.
        """
        with self.lock:
            if not self.is_recording:
                return
            current_time = time.time()
            delta = current_time - self.last_time
            self.last_time = current_time
            event = MacroEvent('key_release', {'key': key}, delta)
            self.events.append(event)
            self.signals.event_recorded.emit(event)
            logging.debug(f"Key released: {key} with delta {delta}")

# Worker class for playing back events
class PlayerWorker(QObject):
    """
    Handles the playback of recorded macro events in a separate thread.
    """
    playback_finished = pyqtSignal()
    playback_error = pyqtSignal(str)
    
    def __init__(self, events, signals, continuous=False):
        super().__init__()
        self.events = events
        self.signals = signals
        self.is_playing = False
        self.continuous = continuous
        self.lock = Lock()
        self.pause_event = Event()
        self.pause_event.set()  # Initialize as set so playback can start
        self.stop_event = Event()

    def play_events(self):
        """
        Plays back the recorded events with the appropriate delays.
        """
        try:
            self.is_playing = True
            controller_mouse = mouse.Controller()
            controller_keyboard = keyboard.Controller()
            logging.info("Playback started.")

            while self.is_playing and not self.stop_event.is_set():
                for event in self.events:
                    if self.stop_event.is_set():
                        break
                    
                    self.pause_event.wait()  # Wait if paused
                    
                    if self.stop_event.is_set():
                        break
                        
                    time.sleep(event.timestamp)
                    
                    try:
                        if event.event_type == 'mouse_move':
                            controller_mouse.position = event.details['position']
                        elif event.event_type == 'mouse_click_pressed':
                            controller_mouse.position = event.details['position']
                            controller_mouse.press(event.details['button'])
                        elif event.event_type == 'mouse_click_released':
                            controller_mouse.position = event.details['position']
                            controller_mouse.release(event.details['button'])
                        elif event.event_type == 'mouse_scroll':
                            controller_mouse.scroll(event.details['dx'], event.details['dy'])
                        elif event.event_type == 'key_press':
                            controller_keyboard.press(event.details['key'])
                        elif event.event_type == 'key_release':
                            controller_keyboard.release(event.details['key'])
                    except Exception as e:
                        logging.error(f"Error playing event {event.event_type}: {e}")
                        continue

                    self.playback_finished.emit()
                    logging.debug(f"Played event: {event.event_type}")

                if not self.continuous:
                    break
                logging.info("Macro replayed. Restarting for continuous playback.")

            self.is_playing = False
            self.playback_finished.emit()
            logging.info("Playback finished.")
        except Exception as e:
            self.is_playing = False
            logging.error(f"Playback error: {e}")
            self.playback_error.emit(str(e))

    def pause_playback(self):
        """
        Pauses the playback.
        """
        self.pause_event.clear()
        logging.info("Playback paused.")

    def resume_playback(self):
        """
        Resumes the playback.
        """
        self.pause_event.set()
        logging.info("Playback resumed.")

    def stop_playback(self):
        """
        Stops the playback.
        """
        with self.lock:
            self.is_playing = False
            self.stop_event.set()
            self.pause_event.set()  # In case it's paused
            logging.info("Playback stopped by user.")

# Hotkey Listener Class using pynput's GlobalHotKeys
class KeyboardHotkeyListener:
    """
    Manages global hotkeys for recording and playing macros.
    """
    def __init__(self, hotkeys, signals):
        """
        :param hotkeys: Dictionary with keys 'record' and 'play' mapping to their hotkey strings
        :param signals: Signals object for inter-thread communication
        """
        self.hotkeys = hotkeys
        self.signals = signals
        self.listener = None
        self.lock = Lock()

    def create_hotkeys(self):
        """
        Converts hotkey strings to pynput's GlobalHotKeys format.
        """
        hotkey_dict = {}
        for action, hotkey in self.hotkeys.items():
            if hotkey:
                parts = hotkey.split('+')
                formatted_hotkey = '+'.join(
                    ['<' + part.lower() + '>' if part.lower() in ['ctrl', 'alt', 'shift', 'meta'] else part.lower()
                     for part in parts])
                if action == 'record':
                    hotkey_dict[formatted_hotkey] = self.signals.toggle_record.emit
                elif action == 'play':
                    hotkey_dict[formatted_hotkey] = self.signals.toggle_play.emit
        logging.info(f"Hotkeys created: {hotkey_dict}")
        return hotkey_dict

    def start_listening(self):
        """
        Starts listening for the defined hotkeys.
        """
        with self.lock:
            if self.listener:
                return  # Already listening

            hotkey_dict = self.create_hotkeys()
            if not hotkey_dict:
                return  # No hotkeys defined

            self.listener = GlobalHotKeys(hotkey_dict)
            self.listener.start()
            logging.info("Hotkey listener started.")

    def stop_listening(self):
        """
        Stops listening for hotkeys.
        """
        with self.lock:
            if self.listener:
                self.listener.stop()
                self.listener = None
                logging.info("Hotkey listener stopped.")

    def update_hotkeys(self, new_hotkeys):
        """
        Updates the hotkeys with new definitions.
        """
        with self.lock:
            self.hotkeys = new_hotkeys
            self.stop_listening()
            self.start_listening()

    def enable_hotkeys(self):
        """
        Enables hotkey listening.
        """
        self.start_listening()

    def disable_hotkeys(self):
        """
        Disables hotkey listening.
        """
        self.stop_listening()

# Dialog for setting hotkeys
class HotkeyDialog(QDialog):
    """
    Dialog window for users to set or update global hotkeys.
    """
    def __init__(self, parent=None, current_hotkeys=None):
        super().__init__(parent)
        self.setWindowTitle("Set Hotkeys")
        self.setFixedSize(450, 300)
        self.current_hotkeys = current_hotkeys or {}
        self.new_hotkeys = {}

        # Main Layout
        layout = QVBoxLayout()

        # Instruction Label
        instruction_label = QLabel(
            "Press the desired key combination for each action.\nUse modifiers like Ctrl, Alt, Shift, Meta.\nCombine keys using '+' (e.g., Ctrl+Alt+R)."
        )
        instruction_label.setStyleSheet("font-size: 12px; color: #ffffff;")
        instruction_label.setAlignment(Qt.AlignCenter)
        layout.addWidget(instruction_label)

        # Form Layout for Hotkeys
        form_layout = QFormLayout()

        # Record Hotkey Input
        self.record_hotkey_input = QLineEdit()
        self.record_hotkey_input.setPlaceholderText("e.g., Ctrl+Alt+R")
        self.record_hotkey_input.setText(self.current_hotkeys.get("record", "Ctrl+Alt+R"))
        form_layout.addRow("Record Hotkey:", self.record_hotkey_input)

        # Play Hotkey Input
        self.play_hotkey_input = QLineEdit()
        self.play_hotkey_input.setPlaceholderText("e.g., Ctrl+Alt+P")
        self.play_hotkey_input.setText(self.current_hotkeys.get("play", "Ctrl+Alt+P"))
        form_layout.addRow("Play Hotkey:", self.play_hotkey_input)

        layout.addLayout(form_layout)

        # Buttons
        buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        buttons.accepted.connect(self.validate_and_accept)
        buttons.rejected.connect(self.reject)
        layout.addWidget(buttons)

        self.setLayout(layout)

    def validate_and_accept(self):
        """
        Validates the entered hotkeys before accepting.
        """
        record_hotkey = self.record_hotkey_input.text().strip()
        play_hotkey = self.play_hotkey_input.text().strip()

        if not self.validate_hotkey(record_hotkey):
            QMessageBox.warning(self, "Invalid Hotkey", "Please enter a valid Record hotkey (e.g., Ctrl+Alt+R).")
            return

        if not self.validate_hotkey(play_hotkey):
            QMessageBox.warning(self, "Invalid Hotkey", "Please enter a valid Play hotkey (e.g., Ctrl+Alt+P).")
            return

        if record_hotkey == play_hotkey:
            QMessageBox.warning(self, "Duplicate Hotkeys", "Record and Play hotkeys cannot be the same.")
            return

        self.accept()

    def validate_hotkey(self, hotkey):
        """
        Validates the hotkey format.
        """
        parts = hotkey.split('+')
        valid_modifiers = ['Ctrl', 'Alt', 'Shift', 'Meta']
        if len(parts) < 2:
            return False
        for part in parts[:-1]:
            if part not in valid_modifiers:
                return False
        # The last part should be a single character or a named key
        if not parts[-1].isalnum() and parts[-1] not in ['Enter', 'Space', 'Backspace', 'Tab', 'Esc']:
            return False
        return True

    def get_hotkeys(self):
        """
        Retrieves the hotkeys set by the user.
        """
        return {
            "record": self.record_hotkey_input.text(),
            "play": self.play_hotkey_input.text()
        }

# Dialog for managing multiple macros
class MacroManagerDialog(QDialog):
    """
    Dialog window for managing multiple macros, including renaming and deleting.
    """
    def __init__(self, parent=None, macros=None):
        super().__init__(parent)
        self.setWindowTitle("Manage Macros")
        self.setFixedSize(500, 400)
        self.macros = macros or {}

        # Main Layout
        layout = QVBoxLayout()

        # Instruction Label
        instruction_label = QLabel("Manage your macros by renaming or deleting them.")
        instruction_label.setStyleSheet("font-size: 14px; color: #ffffff;")
        instruction_label.setAlignment(Qt.AlignCenter)
        layout.addWidget(instruction_label)

        # List Widget
        self.list_widget = QListWidget()
        self.list_widget.addItems(self.macros.keys())
        self.list_widget.setSelectionMode(QAbstractItemView.SingleSelection)
        self.list_widget.setStyleSheet("""
            QListWidget {
                background-color: #1e1e1e;
                border: none;
                padding: 10px;
                border-radius: 8px;
                font-size: 14px;
            }
            QListWidget::item:selected {
                background-color: #ff3b30;
                color: #ffffff;
            }
        """)
        layout.addWidget(self.list_widget)

        # Buttons Layout
        buttons_layout = QHBoxLayout()

        # Rename Button
        self.rename_button = QPushButton("Rename")
        self.rename_button.setStyleSheet("""
            QPushButton {
                background-color: #2c2c2c;
                color: #ffffff;
                border: none;
                padding: 10px 20px;
                border-radius: 8px;
                transition: background-color 0.3s;
            }
            QPushButton:hover {
                background-color: #ff3b30;
            }
            QPushButton:disabled {
                background-color: #555555;
                color: #aaaaaa;
            }
        """)
        self.rename_button.setEnabled(False)
        buttons_layout.addWidget(self.rename_button)

        # Delete Button
        self.delete_button = QPushButton("Delete")
        self.delete_button.setStyleSheet("""
            QPushButton {
                background-color: #2c2c2c;
                color: #ffffff;
                border: none;
                padding: 10px 20px;
                border-radius: 8px;
                transition: background-color 0.3s;
            }
            QPushButton:hover {
                background-color: #ff3b30;
            }
            QPushButton:disabled {
                background-color: #555555;
                color: #aaaaaa;
            }
        """)
        self.delete_button.setEnabled(False)
        buttons_layout.addWidget(self.delete_button)

        layout.addLayout(buttons_layout)

        # Connect Signals
        self.list_widget.itemSelectionChanged.connect(self.update_buttons)
        self.rename_button.clicked.connect(self.rename_macro)
        self.delete_button.clicked.connect(self.delete_macro)

        # Add Stretch and Close Button
        layout.addStretch()

        # Close Button
        close_button = QPushButton("Close")
        close_button.setStyleSheet("""
            QPushButton {
                background-color: #2c2c2c;
                color: #ffffff;
                border: none;
                padding: 10px 20px;
                border-radius: 8px;
                transition: background-color 0.3s;
            }
            QPushButton:hover {
                background-color: #ff3b30;
            }
        """)
        close_button.clicked.connect(self.accept)
        layout.addWidget(close_button)

        self.setLayout(layout)

    def update_buttons(self):
        """
        Enables or disables buttons based on selection.
        """
        has_selection = bool(self.list_widget.selectedItems())
        self.rename_button.setEnabled(has_selection)
        self.delete_button.setEnabled(has_selection)

    def rename_macro(self):
        """
        Renames the selected macro.
        """
        selected_item = self.list_widget.selectedItems()[0]
        current_name = selected_item.text()
        new_name, ok = QtWidgets.QInputDialog.getText(self, "Rename Macro", "New name:", text=current_name)
        if ok and new_name:
            if new_name in self.macros:
                QMessageBox.warning(self, "Rename Macro", "A macro with this name already exists.")
                return
            self.macros[new_name] = self.macros.pop(current_name)
            selected_item.setText(new_name)
            logging.info(f"Macro renamed from {current_name} to {new_name}")

    def delete_macro(self):
        """
        Deletes the selected macro.
        """
        selected_item = self.list_widget.selectedItems()[0]
        macro_name = selected_item.text()
        reply = QMessageBox.question(self, "Delete Macro",
                                     f"Are you sure you want to delete the macro '{macro_name}'?",
                                     QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            del self.macros[macro_name]
            self.list_widget.takeItem(self.list_widget.row(selected_item))
            logging.info(f"Macro deleted: {macro_name}")

# Main Application Window
class MacroRecorderPlayer(QMainWindow):
    """
    The primary window of the Macro Recorder and Player application.
    """
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Ultimate Macro Recorder & Player")
        self.setGeometry(100, 100, 800, 600)  # Smaller, fixed window size
        self.setFixedSize(800, 600)  # Prevent window resizing
        self.setWindowIcon(QIcon.fromTheme("media-record"))

        self.macros = {}  # Dictionary to hold multiple macros
        self.current_macro = None
        self.events = []
        self.is_recording = False
        self.is_playing = False
        self.continuous_playback = False
        self.hotkeys = {"record": "Ctrl+Alt+R", "play": "Ctrl+Alt+P"}  # Default hotkeys

        # Signals for inter-thread communication
        self.signals = Signals()
        self.signals.event_recorded.connect(self.on_event_recorded)
        self.signals.recording_finished.connect(self.on_recording_finished)
        self.signals.playback_finished.connect(self.on_playback_finished)
        self.signals.playback_error.connect(self.on_playback_error)
        self.signals.toggle_record.connect(self.toggle_recording_triggered)
        self.signals.toggle_play.connect(self.toggle_playback_triggered)

        # Initialize UI Components
        self.init_ui()

        # Initialize Threads
        self.init_threads()

        # Initialize Hotkey Listener
        self.init_hotkey_listener()

        # Start periodic mouse position updates
        self.init_mouse_position_updater()

    def init_ui(self):
        """
        Sets up the user interface components.
        """
        # Central Widget
        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        # Main Layout
        main_layout = QHBoxLayout()
        central_widget.setLayout(main_layout)

        # Sidebar Frame
        self.sidebar = QFrame()
        self.sidebar.setFrameShape(QFrame.StyledPanel)
        self.sidebar.setFixedWidth(200)  # Reduced sidebar width
        sidebar_layout = QVBoxLayout()
        self.sidebar.setLayout(sidebar_layout)
        sidebar_layout.setAlignment(Qt.AlignTop)

        # Logo or Icon at the Top
        logo_label = QLabel()
        logo_pixmap = QPixmap(64, 64)
        logo_pixmap.fill(Qt.transparent)  # Transparent placeholder
        logo_label.setPixmap(QIcon.fromTheme("media-record").pixmap(64, 64))
        logo_label.setAlignment(Qt.AlignCenter)
        sidebar_layout.addWidget(logo_label)

        # Spacer
        sidebar_layout.addSpacing(20)

        # Control Buttons with Icons and Enhanced Animations
        button_style = """
            QPushButton {
                background-color: #2c2c2c;
                border: none;
                border-radius: 12px;
                padding: 12px;
                font-size: 16px;
                color: #ffffff;
                text-align: left;
                transition: background-color 0.3s, transform 0.2s;
            }
            QPushButton:hover {
                background-color: #ff3b30;
                transform: scale(1.05);
            }
            QPushButton:pressed {
                background-color: #cc2900;
                transform: scale(0.95);
            }
            QPushButton:disabled {
                background-color: #555555;
                color: #aaaaaa;
            }
        """

        # Record Button
        self.record_button = QPushButton("  Record")
        self.record_button.setIcon(QIcon.fromTheme("media-record"))
        self.record_button.setStyleSheet(button_style)
        self.record_button.setIconSize(QSize(32, 32))
        self.record_button.setToolTip("Start Recording Macro")
        self.record_button.clicked.connect(self.toggle_recording)
        sidebar_layout.addWidget(self.record_button)

        # Play Button
        self.play_button = QPushButton("  Play")
        self.play_button.setIcon(QIcon.fromTheme("media-playback-start"))
        self.play_button.setStyleSheet(button_style)
        self.play_button.setIconSize(QSize(32, 32))
        self.play_button.setEnabled(False)
        self.play_button.setToolTip("Play Current Macro")
        self.play_button.clicked.connect(self.play_macro)
        sidebar_layout.addWidget(self.play_button)

        # Pause Button
        self.pause_button = QPushButton("  Pause")
        self.pause_button.setIcon(QIcon.fromTheme("media-playback-pause"))
        self.pause_button.setStyleSheet(button_style)
        self.pause_button.setIconSize(QSize(32, 32))
        self.pause_button.setEnabled(False)
        self.pause_button.setToolTip("Pause Playback")
        self.pause_button.clicked.connect(self.pause_playback)
        sidebar_layout.addWidget(self.pause_button)

        # Stop Button
        self.stop_button = QPushButton("  Stop")
        self.stop_button.setIcon(QIcon.fromTheme("media-playback-stop"))
        self.stop_button.setStyleSheet(button_style)
        self.stop_button.setIconSize(QSize(32, 32))
        self.stop_button.setEnabled(False)
        self.stop_button.setToolTip("Stop Playback")
        self.stop_button.clicked.connect(self.stop_playback)
        sidebar_layout.addWidget(self.stop_button)

        # Save Button
        self.save_button = QPushButton("  Save")
        self.save_button.setIcon(QIcon.fromTheme("document-save"))
        self.save_button.setStyleSheet(button_style)
        self.save_button.setIconSize(QSize(32, 32))
        self.save_button.setEnabled(False)
        self.save_button.setToolTip("Save Current Macro")
        self.save_button.clicked.connect(self.save_macro)
        sidebar_layout.addWidget(self.save_button)

        # Load Button
        self.load_button = QPushButton("  Load")
        self.load_button.setIcon(QIcon.fromTheme("document-open"))
        self.load_button.setStyleSheet(button_style)
        self.load_button.setIconSize(QSize(32, 32))
        self.load_button.setToolTip("Load a Macro")
        self.load_button.clicked.connect(self.load_macro)
        sidebar_layout.addWidget(self.load_button)

        # Clear Button
        self.clear_button = QPushButton("  Clear")
        self.clear_button.setIcon(QIcon.fromTheme("edit-clear"))
        self.clear_button.setStyleSheet(button_style)
        self.clear_button.setIconSize(QSize(32, 32))
        self.clear_button.setEnabled(False)
        self.clear_button.setToolTip("Clear Current Macro")
        self.clear_button.clicked.connect(self.clear_events)
        sidebar_layout.addWidget(self.clear_button)

        # Macro Management Button
        self.manage_macros_button = QPushButton("  Manage Macros")
        self.manage_macros_button.setIcon(QIcon.fromTheme("view-list-icons"))
        self.manage_macros_button.setStyleSheet(button_style)
        self.manage_macros_button.setIconSize(QSize(32, 32))
        self.manage_macros_button.setToolTip("Manage Multiple Macros")
        self.manage_macros_button.clicked.connect(self.manage_macros)
        sidebar_layout.addWidget(self.manage_macros_button)

        # Theme Toggle Button
        self.theme_toggle_button = QPushButton("  Switch to Light Theme")
        self.theme_toggle_button.setIcon(QIcon.fromTheme("applications-graphics"))
        self.theme_toggle_button.setStyleSheet(button_style)
        self.theme_toggle_button.setIconSize(QSize(32, 32))
        self.theme_toggle_button.setToolTip("Toggle Dark/Light Theme")
        self.theme_toggle_button.clicked.connect(self.toggle_theme)
        sidebar_layout.addWidget(self.theme_toggle_button)

        # Spacer to Push Elements to Top
        spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        sidebar_layout.addSpacerItem(spacer)

        # Main Content Area
        self.content = QFrame()
        self.content.setFrameShape(QFrame.StyledPanel)
        content_layout = QVBoxLayout()
        self.content.setLayout(content_layout)

        # Top Status Bar with Shadow Effect
        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)
        self.status_bar_label = QLabel("Status: Idle")
        self.status_bar_label.setStyleSheet("font-size: 16px; color: #ffffff;")
        self.status_bar.addPermanentWidget(self.status_bar_label)

        # Real-Time Mouse Position with Drop Shadow
        self.mouse_position_label = QLabel("Mouse Position: (0, 0)")
        self.mouse_position_label.setStyleSheet("font-size: 16px; color: #ffffff;")
        shadow = QGraphicsDropShadowEffect()
        shadow.setBlurRadius(10)
        shadow.setXOffset(3)
        shadow.setYOffset(3)
        shadow.setColor(QtGui.QColor(0, 0, 0, 180))
        self.mouse_position_label.setGraphicsEffect(shadow)
        self.mouse_position_label.setAlignment(Qt.AlignCenter)
        content_layout.addWidget(self.mouse_position_label)

        # Search Bar with Enhanced Styling
        search_layout = QHBoxLayout()
        self.search_label = QLabel("Search Events:")
        self.search_label.setStyleSheet("font-size: 14px; color: #ffffff;")
        self.search_input = QLineEdit()
        self.search_input.setPlaceholderText("Type to search events...")
        self.search_input.setStyleSheet("""
            QLineEdit {
                padding: 10px;
                border-radius: 12px;
                border: 2px solid #444444;
                background-color: #2c2c2c;
                color: #ffffff;
                font-size: 14px;
            }
            QLineEdit::focus {
                border: 2px solid #ff3b30;
            }
        """)
        self.search_input.textChanged.connect(self.search_events)
        search_layout.addWidget(self.search_label)
        search_layout.addWidget(self.search_input)
        content_layout.addLayout(search_layout)

        # Splitter for Event Lists and Details
        splitter = QSplitter(Qt.Vertical)

        # Tabbed Interface for Events
        self.tabs = QTabWidget()
        self.tabs.setTabPosition(QTabWidget.North)
        self.tabs.setTabsClosable(False)
        self.tabs.setMovable(False)
        self.tabs.setStyleSheet("""
            QTabWidget::pane {
                border: none;
            }
            QTabBar::tab {
                background: #2c2c2c;
                color: #ffffff;
                padding: 10px;
                border: 1px solid #444444;
                border-bottom: none;
                border-top-left-radius: 12px;
                border-top-right-radius: 12px;
            }
            QTabBar::tab:selected {
                background: #ff3b30;
                color: #ffffff;
            }
        """)

        # Mouse Movements Tab
        self.mouse_move_tab = QListWidget()
        self.mouse_move_tab.setSelectionMode(QAbstractItemView.SingleSelection)
        self.mouse_move_tab.itemClicked.connect(self.display_event_details)
        self.mouse_move_tab.setStyleSheet("""
            QListWidget {
                background-color: #1e1e1e;
                border: none;
                padding: 10px;
                border-radius: 8px;
                font-size: 14px;
            }
            QListWidget::item:selected {
                background-color: #ff3b30;
                color: #ffffff;
            }
        """)
        self.tabs.addTab(self.mouse_move_tab, QIcon.fromTheme("system-run"), "Mouse Movements")

        # Mouse Clicks Tab
        self.mouse_click_tab = QListWidget()
        self.mouse_click_tab.setSelectionMode(QAbstractItemView.SingleSelection)
        self.mouse_click_tab.itemClicked.connect(self.display_event_details)
        self.mouse_click_tab.setStyleSheet("""
            QListWidget {
                background-color: #1e1e1e;
                border: none;
                padding: 10px;
                border-radius: 8px;
                font-size: 14px;
            }
            QListWidget::item:selected {
                background-color: #ff3b30;
                color: #ffffff;
            }
        """)
        self.tabs.addTab(self.mouse_click_tab, QIcon.fromTheme("go-jump"), "Mouse Clicks")

        # Mouse Scrolls Tab
        self.mouse_scroll_tab = QListWidget()
        self.mouse_scroll_tab.setSelectionMode(QAbstractItemView.SingleSelection)
        self.mouse_scroll_tab.itemClicked.connect(self.display_event_details)
        self.mouse_scroll_tab.setStyleSheet("""
            QListWidget {
                background-color: #1e1e1e;
                border: none;
                padding: 10px;
                border-radius: 8px;
                font-size: 14px;
            }
            QListWidget::item:selected {
                background-color: #ff3b30;
                color: #ffffff;
            }
        """)
        self.tabs.addTab(self.mouse_scroll_tab, QIcon.fromTheme("text-x-generic"), "Mouse Scrolls")

        # Keyboard Events Tab
        self.keyboard_tab = QListWidget()
        self.keyboard_tab.setSelectionMode(QAbstractItemView.SingleSelection)
        self.keyboard_tab.itemClicked.connect(self.display_event_details)
        self.keyboard_tab.setStyleSheet("""
            QListWidget {
                background-color: #1e1e1e;
                border: none;
                padding: 10px;
                border-radius: 8px;
                font-size: 14px;
            }
            QListWidget::item:selected {
                background-color: #ff3b30;
                color: #ffffff;
            }
        """)
        self.tabs.addTab(self.keyboard_tab, QIcon.fromTheme("input-keyboard"), "Keyboard Events")

        splitter.addWidget(self.tabs)

        # Event Details Panel with Enhanced Readability
        self.details_panel = QTextEdit()
        self.details_panel.setReadOnly(True)
        self.details_panel.setFixedHeight(200)
        self.details_panel.setStyleSheet("""
            QTextEdit {
                background-color: #2c2c2c;
                color: #ffffff;
                border: 2px solid #444444;
                border-radius: 12px;
                padding: 10px;
                font-size: 14px;
                font-family: 'Courier New', Courier, monospace;
            }
        """)
        splitter.addWidget(self.details_panel)

        splitter.setStretchFactor(0, 5)
        splitter.setStretchFactor(1, 2)

        content_layout.addWidget(splitter)

        # Progress Bar with Enhanced Styling
        self.progress_bar = QProgressBar()
        self.progress_bar.setValue(0)
        self.progress_bar.setVisible(False)
        self.progress_bar.setStyleSheet("""
            QProgressBar {
                border: 2px solid #ff3b30;
                border-radius: 12px;
                text-align: center;
                color: #ffffff;
                font-size: 14px;
                height: 25px;
            }
            QProgressBar::chunk {
                background-color: #ff3b30;
                border-radius: 12px;
            }
        """)
        content_layout.addWidget(self.progress_bar)

        # Continuous Playback Checkbox with Enhanced Styling
        self.continuous_playback_checkbox = QCheckBox("Enable Continuous Playback")
        self.continuous_playback_checkbox.setStyleSheet("QCheckBox { color: #ffffff; font-size: 14px; }")
        content_layout.addWidget(self.continuous_playback_checkbox)

        # Macro Selection Dropdown
        macro_selection_layout = QHBoxLayout()
        self.macro_selection_label = QLabel("Current Macro:")
        self.macro_selection_label.setStyleSheet("font-size: 14px; color: #ffffff;")
        self.macro_selection_dropdown = QComboBox()
        self.macro_selection_dropdown.setStyleSheet("""
            QComboBox {
                padding: 10px;
                border-radius: 12px;
                border: 2px solid #444444;
                background-color: #2c2c2c;
                color: #ffffff;
                font-size: 14px;
            }
            QComboBox::drop-down {
                border: none;
            }
            QComboBox::down-arrow {
                image: url(none);
            }
            QComboBox::on {
                padding-top: 3px;
                padding-left: 4px;
            }
        """)
        self.macro_selection_dropdown.currentIndexChanged.connect(self.select_macro)
        macro_selection_layout.addWidget(self.macro_selection_label)
        macro_selection_layout.addWidget(self.macro_selection_dropdown)
        content_layout.addLayout(macro_selection_layout)

        # Add Widgets to Main Layout
        main_layout.addWidget(self.sidebar)
        main_layout.addWidget(self.content)

        # Set the application's overall style
        self.apply_modern_theme()

    def init_threads(self):
        """
        Initializes the recorder and player workers.
        """
        # Recorder Thread
        self.recorder_worker = RecorderWorker(self.signals)
        self.record_thread = Thread(target=self.recorder_worker.start_recording, daemon=True)

        # Player Worker placeholders
        self.player_worker = None
        self.player_thread = None

    def init_hotkey_listener(self):
        """
        Initializes the global hotkey listener in a separate thread.
        """
        self.hotkey_listener = KeyboardHotkeyListener(self.hotkeys, self.signals)
        self.hotkey_listener_thread = Thread(target=self.hotkey_listener.start_listening, daemon=True)
        self.hotkey_listener_thread.start()
        self.hotkey_listener.enable_hotkeys()

    def init_mouse_position_updater(self):
        """
        Sets up a timer to periodically update the mouse position display.
        """
        self.mouse_position_timer = QTimer()
        self.mouse_position_timer.timeout.connect(self.update_mouse_position)
        self.mouse_position_timer.start(100)  # Update every 100 ms

    def toggle_sidebar(self):
        """
        Toggles the visibility and size of the sidebar with animation.
        """
        if self.sidebar.width() == 200:
            new_width = 60
            self.toggle_sidebar_button_icon = QIcon.fromTheme("go-previous")
        else:
            new_width = 200
            self.toggle_sidebar_button_icon = QIcon.fromTheme("go-next")

        animation = QPropertyAnimation(self.sidebar, b"minimumWidth")
        animation.setDuration(300)
        animation.setStartValue(self.sidebar.width())
        animation.setEndValue(new_width)
        animation.setEasingCurve(QEasingCurve.InOutQuart)
        animation.start()

    def toggle_theme(self):
        """
        Switches between dark and light themes.
        """
        if self.theme_toggle_button.text() == "  Switch to Light Theme":
            self.apply_light_theme()
            self.theme_toggle_button.setText("  Switch to Dark Theme")
            self.theme_toggle_button.setToolTip("Toggle to Dark Theme")
            logging.info("Switched to Light Theme.")
        else:
            self.apply_modern_theme()
            self.theme_toggle_button.setText("  Switch to Light Theme")
            self.theme_toggle_button.setToolTip("Toggle to Light Theme")
            logging.info("Switched to Dark Theme.")

    def toggle_recording_triggered(self):
        """
        Slot connected to the toggle_record signal from hotkeys.
        """
        self.toggle_recording()

    def toggle_playback_triggered(self):
        """
        Slot connected to the toggle_play signal from hotkeys.
        """
        if not self.is_playing:
            self.play_macro()
        else:
            self.pause_playback()

    def toggle_recording(self):
        """
        Starts or stops macro recording based on current state.
        """
        if not self.is_recording:
            self.start_recording()
        else:
            self.stop_recording()

    def start_recording(self):
        """
        Initiates the recording process.
        """
        # Select or create a new macro
        if not self.current_macro:
            macro_name, ok = QtWidgets.QInputDialog.getText(self, "New Macro", "Enter macro name:")
            if ok and macro_name:
                if macro_name in self.macros:
                    QMessageBox.warning(self, "Duplicate Macro", "A macro with this name already exists.")
                    return
                self.macros[macro_name] = []
                self.current_macro = macro_name
                self.macro_selection_dropdown.addItem(macro_name)
                self.macro_selection_dropdown.setCurrentText(macro_name)
                logging.info(f"New macro created: {macro_name}")
            else:
                return

        self.is_recording = True
        self.events = []
        self.clear_event_lists()
        self.record_button.setText("  Stop")
        self.record_button.setToolTip("Stop Recording Macro")
        self.play_button.setEnabled(False)
        self.save_button.setEnabled(False)
        self.clear_button.setEnabled(False)
        self.manage_macros_button.setEnabled(False)
        self.status_bar_label.setText(f"Status: Recording '{self.current_macro}'...")
        self.hotkey_listener.disable_hotkeys()
        self.record_thread = Thread(target=self.recorder_worker.start_recording, daemon=True)
        self.record_thread.start()
        logging.info(f"Recording started for macro: {self.current_macro}")

    def stop_recording(self):
        """
        Stops the ongoing recording process.
        """
        self.recorder_worker.stop_recording()
        self.is_recording = False
        self.record_button.setText("  Record")
        self.record_button.setToolTip("Start Recording Macro")
        self.play_button.setEnabled(True)
        self.save_button.setEnabled(True)
        self.clear_button.setEnabled(True)
        self.manage_macros_button.setEnabled(True)
        self.status_bar_label.setText(f"Status: Idle")
        self.hotkey_listener.enable_hotkeys()
        logging.info(f"Recording stopped for macro: {self.current_macro}")

    def on_recording_finished(self):
        """
        Slot that gets called when recording is finished.
        """
        self.is_recording = False
        self.record_button.setText("  Record")
        self.record_button.setToolTip("Start Recording Macro")
        self.play_button.setEnabled(True)
        self.save_button.setEnabled(True)
        self.clear_button.setEnabled(True)
        self.manage_macros_button.setEnabled(True)
        self.status_bar_label.setText(f"Status: Idle")
        self.hotkey_listener.enable_hotkeys()
        logging.info("Recording finished signal received.")

    def on_event_recorded(self, event):
        """
        Slot that gets called when a new event is recorded.
        """
        self.events.append(event)
        self.macros[self.current_macro].append(event)
        self.add_event_to_list(event)

    def add_event_to_list(self, event):
        """
        Adds the recorded event to the appropriate event list in the UI.
        """
        if event.event_type == 'mouse_move':
            text = f"Position: {event.details['position']} | Delay: {event.timestamp:.2f}s"
            self.mouse_move_tab.addItem(text)
        elif event.event_type in ['mouse_click_pressed', 'mouse_click_released']:
            action = "Pressed" if 'pressed' in event.event_type else "Released"
            button = event.details['button']
            text = f"{action} {button} at {event.details['position']} | Delay: {event.timestamp:.2f}s"
            self.mouse_click_tab.addItem(text)
        elif event.event_type == 'mouse_scroll':
            dx = event.details['dx']
            dy = event.details['dy']
            position = event.details['position']
            text = f"Scroll ({dx}, {dy}) at {position} | Delay: {event.timestamp:.2f}s"
            self.mouse_scroll_tab.addItem(text)
        elif event.event_type in ['key_press', 'key_release']:
            action = "Pressed" if 'press' in event.event_type else "Released"
            key = event.details['key']
            key_str = self.format_key(key)
            text = f"{action} {key_str} | Delay: {event.timestamp:.2f}s"
            self.keyboard_tab.addItem(text)

    def format_key(self, key):
        """
        Formats the key object into a readable string.
        """
        if isinstance(key, KeyCode):
            return key.char.upper() if key.char else str(key).capitalize()
        else:
            return str(key).replace("Key.", "").capitalize()

    def clear_event_lists(self):
        """
        Clears all event lists in the UI.
        """
        self.mouse_move_tab.clear()
        self.mouse_click_tab.clear()
        self.mouse_scroll_tab.clear()
        self.keyboard_tab.clear()
        self.details_panel.clear()

    def play_macro(self):
        """
        Initiates the playback of the current macro.
        """
        if not self.current_macro or not self.macros.get(self.current_macro):
            QMessageBox.warning(self, "Play Macro", "No macro selected or macro is empty.")
            return

        self.events = self.macros[self.current_macro]
        self.is_playing = True
        self.continuous_playback = self.continuous_playback_checkbox.isChecked()
        self.play_button.setEnabled(False)
        self.record_button.setEnabled(False)
        self.save_button.setEnabled(False)
        self.load_button.setEnabled(False)
        self.clear_button.setEnabled(False)
        self.manage_macros_button.setEnabled(False)
        self.pause_button.setEnabled(True)
        self.stop_button.setEnabled(True)
        self.status_bar_label.setText(f"Status: Playing '{self.current_macro}'...")
        self.progress_bar.setVisible(True)
        self.progress_bar.setMaximum(len(self.events))
        self.progress_bar.setValue(0)
        self.hotkey_listener.disable_hotkeys()

        # Initialize Player Worker
        self.player_worker = PlayerWorker(self.events, self.signals, continuous=self.continuous_playback)
        self.player_worker.playback_finished.connect(self.update_progress)
        self.player_worker.playback_error.connect(self.on_playback_error)
        self.play_thread = Thread(target=self.player_worker.play_events, daemon=True)
        self.play_thread.start()
        logging.info(f"Playback started for macro: {self.current_macro}")

    def update_progress(self):
        """
        Updates the progress bar during playback.
        """
        current_value = self.progress_bar.value() + 1
        self.progress_bar.setValue(current_value)
        if current_value >= self.progress_bar.maximum():
            self.on_playback_finished()

    def pause_playback(self):
        """
        Pauses or resumes the playback.
        """
        if self.player_worker and self.is_playing:
            # Currently playing, so pause
            self.player_worker.pause_playback()
            self.is_playing = False
            self.pause_button.setText("  Resume")
            self.status_bar_label.setText(f"Status: Playback Paused for '{self.current_macro}'...")
            logging.info("Playback paused.")
        else:
            # Resume playback
            if self.player_worker and not self.is_playing:
                self.player_worker.resume_playback()
                self.is_playing = True
                self.pause_button.setText("  Pause")
                self.status_bar_label.setText(f"Status: Playing '{self.current_macro}'...")
                logging.info("Playback resumed.")

    def stop_playback(self):
        """
        Stops the ongoing playback.
        """
        if self.player_worker:
            self.player_worker.stop_playback()
            self.is_playing = False
            self.play_button.setEnabled(True)
            self.record_button.setEnabled(True)
            self.save_button.setEnabled(True)
            self.load_button.setEnabled(True)
            self.clear_button.setEnabled(True)
            self.manage_macros_button.setEnabled(True)
            self.pause_button.setEnabled(False)
            self.stop_button.setEnabled(False)
            self.pause_button.setText("  Pause")
            self.progress_bar.setVisible(False)
            self.progress_bar.setValue(0)
            self.status_bar_label.setText("Status: Idle")
            self.hotkey_listener.enable_hotkeys()
            logging.info("Playback stopped by user.")

    def on_playback_finished(self):
        """
        Slot that gets called when playback is finished.
        """
        self.is_playing = False
        self.play_button.setEnabled(True)
        self.record_button.setEnabled(True)
        self.save_button.setEnabled(True)
        self.load_button.setEnabled(True)
        self.clear_button.setEnabled(True)
        self.manage_macros_button.setEnabled(True)
        self.pause_button.setEnabled(False)
        self.stop_button.setEnabled(False)
        self.pause_button.setText("  Pause")
        self.progress_bar.setVisible(False)
        self.progress_bar.setValue(0)
        self.status_bar_label.setText("Status: Idle")
        self.hotkey_listener.enable_hotkeys()
        QMessageBox.information(self, "Playback", f"Macro '{self.current_macro}' playback completed.")
        logging.info(f"Playback finished for macro: {self.current_macro}")

    def on_playback_error(self, error):
        """
        Slot that gets called when an error occurs during playback.
        """
        QMessageBox.critical(self, "Playback Error", f"An error occurred during playback:\n{error}")
        self.is_playing = False
        self.play_button.setEnabled(True)
        self.record_button.setEnabled(True)
        self.save_button.setEnabled(True)
        self.load_button.setEnabled(True)
        self.clear_button.setEnabled(True)
        self.manage_macros_button.setEnabled(True)
        self.pause_button.setEnabled(False)
        self.stop_button.setEnabled(False)
        self.pause_button.setText("  Pause")
        self.progress_bar.setVisible(False)
        self.progress_bar.setValue(0)
        self.status_bar_label.setText("Status: Idle")
        self.hotkey_listener.enable_hotkeys()
        logging.error(f"Playback error: {error}")

    def save_macro(self):
        """
        Saves the current macro to a file.
        """
        if not self.current_macro or not self.macros.get(self.current_macro):
            QMessageBox.warning(self, "Save Macro", "No macro selected or macro is empty.")
            return

        options = QFileDialog.Options()
        file_path, _ = QFileDialog.getSaveFileName(
            self, "Save Macro", f"{self.current_macro}.macro", "Macro Files (*.macro);;All Files (*)", options=options
        )
        if file_path:
            try:
                with open(file_path, 'wb') as f:
                    pickle.dump(self.macros[self.current_macro], f)
                QMessageBox.information(self, "Save Macro",
                                        f"Macro '{self.current_macro}' saved successfully to {file_path}.")
                logging.info(f"Macro saved: {self.current_macro} at {file_path}")
            except Exception as e:
                QMessageBox.critical(self, "Save Macro", f"Failed to save macro:\n{e}")
                logging.error(f"Failed to save macro {self.current_macro}: {e}")

    def load_macro(self):
        """
        Loads one or multiple macros from files.
        """
        options = QFileDialog.Options()
        file_paths, _ = QFileDialog.getOpenFileNames(
            self, "Load Macro", "", "Macro Files (*.macro);;All Files (*)", options=options
        )
        if file_paths:
            for file_path in file_paths:
                try:
                    with open(file_path, 'rb') as f:
                        events = pickle.load(f)
                    macro_name = file_path.split("/")[-1].split(".macro")[0]
                    if macro_name in self.macros:
                        QMessageBox.warning(self, "Load Macro",
                                            f"A macro named '{macro_name}' already exists. Skipping.")
                        continue
                    self.macros[macro_name] = events
                    self.macro_selection_dropdown.addItem(macro_name)
                    QMessageBox.information(self, "Load Macro",
                                            f"Macro '{macro_name}' loaded successfully.")
                    logging.info(f"Macro loaded: {macro_name} from {file_path}")
                except Exception as e:
                    QMessageBox.critical(self, "Load Macro",
                                         f"Failed to load macro from {file_path}:\n{e}")
                    logging.error(f"Failed to load macro from {file_path}: {e}")

    def manage_macros(self):
        """
        Opens the macro manager dialog to manage existing macros.
        """
        if not self.macros:
            QMessageBox.information(self, "Manage Macros", "No macros available to manage.")
            return
        dialog = MacroManagerDialog(self, macros=self.macros)
        dialog.exec_()
        # Update macro selection dropdown if any changes occurred
        self.update_macro_dropdown()

    def update_macro_dropdown(self):
        """
        Updates the macro selection dropdown after changes.
        """
        previous_macro = self.current_macro
        self.macro_selection_dropdown.clear()
        self.macro_selection_dropdown.addItems(self.macros.keys())
        if self.macros:
            if previous_macro in self.macros:
                self.current_macro = previous_macro
                self.macro_selection_dropdown.setCurrentText(self.current_macro)
            else:
                self.current_macro = list(self.macros.keys())[0]
                self.macro_selection_dropdown.setCurrentText(self.current_macro)
            self.play_button.setEnabled(True)
            self.save_button.setEnabled(True)
            self.clear_button.setEnabled(True)
        else:
            self.current_macro = None
            self.play_button.setEnabled(False)
            self.save_button.setEnabled(False)
            self.clear_button.setEnabled(False)
        logging.info("Macro selection dropdown updated.")

    def clear_events(self):
        """
        Clears all events from the current macro.
        """
        if self.current_macro:
            reply = QMessageBox.question(self, "Clear Macro",
                                         f"Are you sure you want to clear all events from macro '{self.current_macro}'?",
                                         QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if reply == QMessageBox.Yes:
                self.macros[self.current_macro] = []
                self.clear_event_lists()
                self.play_button.setEnabled(False)
                self.save_button.setEnabled(False)
                self.clear_button.setEnabled(False)
                logging.info(f"All events cleared from macro: {self.current_macro}")
        else:
            self.clear_event_lists()
            self.play_button.setEnabled(False)
            self.save_button.setEnabled(False)
            self.clear_button.setEnabled(False)

    def update_mouse_position(self):
        """
        Updates the mouse position label with the current cursor position.
        """
        try:
            controller = mouse.Controller()
            position = controller.position
            self.mouse_position_label.setText(f"Mouse Position: {position}")
        except Exception as e:
            self.mouse_position_label.setText("Mouse Position: Error")
            logging.error(f"Failed to update mouse position: {e}")

    def display_event_details(self, item):
        """
        Displays details of the selected event in the details panel.
        """
        event_text = item.text()
        self.details_panel.setText(event_text)

    def search_events(self, text):
        """
        Searches for events containing the specified text in the current tab.
        """
        current_tab = self.tabs.currentWidget()
        for index in range(current_tab.count()):
            item = current_tab.item(index)
            if text.lower() in item.text().lower():
                current_tab.setCurrentRow(index)
                self.display_event_details(item)
                break

    def select_macro(self, index):
        """
        Handles macro selection from the dropdown.
        """
        if index >= 0:
            self.current_macro = self.macro_selection_dropdown.currentText()
            self.clear_event_lists()
            for event in self.macros[self.current_macro]:
                self.add_event_to_list(event)
            self.status_bar_label.setText(f"Status: Selected '{self.current_macro}'")
            self.play_button.setEnabled(True)
            self.save_button.setEnabled(True)
            self.clear_button.setEnabled(True)
            logging.info(f"Macro selected: {self.current_macro}")

    def open_settings(self):
        """
        Opens the settings dialog for configuring hotkeys.
        """
        dialog = HotkeyDialog(self, current_hotkeys=self.hotkeys)
        if dialog.exec_():
            new_hotkeys = dialog.get_hotkeys()
            self.hotkeys = new_hotkeys
            self.hotkey_listener.update_hotkeys(self.hotkeys)
            QMessageBox.information(self, "Settings", "Hotkeys updated successfully.")
            logging.info("Hotkeys updated.")

    def apply_modern_theme(self):
        """
        Applies a dark modern theme to the application.
        """
        modern_stylesheet = """
            /* Modern Dark Theme with Enhanced Styling */
            QWidget {
                background-color: #121212;
                color: #ffffff;
                font-family: 'Segoe UI', sans-serif;
            }

            QPushButton {
                background-color: #2c2c2c;
                border: none;
                border-radius: 12px;
                padding: 12px;
                font-size: 16px;
                color: #ffffff;
                text-align: left;
                transition: background-color 0.3s, transform 0.2s;
            }

            QPushButton:hover {
                background-color: #ff3b30;
                transform: scale(1.05);
            }

            QPushButton:pressed {
                background-color: #cc2900;
                transform: scale(0.95);
            }

            QPushButton:disabled {
                background-color: #555555;
                color: #aaaaaa;
            }

            QLineEdit, QTextEdit, QComboBox {
                background-color: #1e1e1e;
                border: 2px solid #444444;
                border-radius: 12px;
                padding: 10px;
                color: #ffffff;
                font-size: 14px;
            }

            QLineEdit::focus, QTextEdit::focus, QComboBox::focus {
                border: 2px solid #ff3b30;
            }

            QListWidget {
                background-color: #1e1e1e;
                border: none;
                padding: 10px;
                border-radius: 8px;
                font-size: 14px;
            }

            QListWidget::item:selected {
                background-color: #ff3b30;
                color: #ffffff;
            }

            QTabWidget::pane {
                border: none;
            }

            QTabBar::tab {
                background: #2c2c2c;
                color: #ffffff;
                padding: 10px;
                border: 1px solid #444444;
                border-bottom: none;
                border-top-left-radius: 12px;
                border-top-right-radius: 12px;
            }

            QTabBar::tab:selected {
                background: #ff3b30;
                color: #ffffff;
            }

            QProgressBar {
                border: 2px solid #ff3b30;
                border-radius: 12px;
                text-align: center;
                color: #ffffff;
                font-size: 14px;
                height: 25px;
            }

            QProgressBar::chunk {
                background-color: #ff3b30;
                border-radius: 12px;
            }

            QCheckBox {
                color: #ffffff;
                font-size: 14px;
            }

            QLabel {
                font-size: 14px;
            }

            QToolButton {
                background-color: #1a1a1a;
                color: #ffffff;
                border: none;
                padding: 12px;
                border-radius: 12px;
                transition: background 0.3s, transform 0.2s;
            }

            QToolButton:hover {
                background-color: #ff3b30;
                transform: scale(1.05);
            }

            QToolButton:pressed {
                background-color: #cc2900;
                transform: scale(0.95);
            }

            /* Scrollbar Styles */
            QScrollBar:vertical {
                border: none;
                background: #1e1e1e;
                width: 12px;
                margin: 0px 0px 0px 0px;
            }

            QScrollBar::handle:vertical {
                background: #444444;
                min-height: 20px;
                border-radius: 6px;
            }

            QScrollBar::handle:vertical:hover {
                background: #ff3b30;
            }

            QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
                background: none;
                height: 0px;
            }

            /* Tooltip Styles */
            QToolTip {
                background-color: #1e1e1e;
                color: #ffffff;
                border: 1px solid #ff3b30;
                padding: 5px;
                border-radius: 8px;
                font-size: 12px;
            }
        """
        self.setStyleSheet(modern_stylesheet)

    def apply_light_theme(self):
        """
        Applies a light modern theme to the application.
        """
        light_stylesheet = """
            /* Modern Light Theme with Enhanced Styling */
            QWidget {
                background-color: #f0f0f0;
                color: #000000;
                font-family: 'Segoe UI', sans-serif;
            }

            QPushButton {
                background-color: #ffffff;
                border: 2px solid #cccccc;
                border-radius: 12px;
                padding: 12px;
                font-size: 16px;
                color: #000000;
                text-align: left;
                transition: background-color 0.3s, transform 0.2s;
            }

            QPushButton:hover {
                background-color: #ff3b30;
                color: #ffffff;
                transform: scale(1.05);
            }

            QPushButton:pressed {
                background-color: #cc2900;
                color: #ffffff;
                transform: scale(0.95);
            }

            QPushButton:disabled {
                background-color: #dddddd;
                color: #aaaaaa;
            }

            QLineEdit, QTextEdit, QComboBox {
                background-color: #ffffff;
                border: 2px solid #cccccc;
                border-radius: 12px;
                padding: 10px;
                color: #000000;
                font-size: 14px;
            }

            QLineEdit::focus, QTextEdit::focus, QComboBox::focus {
                border: 2px solid #ff3b30;
            }

            QListWidget {
                background-color: #ffffff;
                border: none;
                padding: 10px;
                border-radius: 8px;
                font-size: 14px;
            }

            QListWidget::item:selected {
                background-color: #ff3b30;
                color: #ffffff;
            }

            QTabWidget::pane {
                border: none;
            }

            QTabBar::tab {
                background: #ffffff;
                color: #000000;
                padding: 10px;
                border: 1px solid #cccccc;
                border-bottom: none;
                border-top-left-radius: 12px;
                border-top-right-radius: 12px;
            }

            QTabBar::tab:selected {
                background: #ff3b30;
                color: #ffffff;
            }

            QProgressBar {
                border: 2px solid #ff3b30;
                border-radius: 12px;
                text-align: center;
                color: #ffffff;
                font-size: 14px;
                height: 25px;
            }

            QProgressBar::chunk {
                background-color: #ff3b30;
                border-radius: 12px;
            }

            QCheckBox {
                color: #000000;
                font-size: 14px;
            }

            QLabel {
                font-size: 14px;
            }

            QToolButton {
                background-color: #e0e0e0;
                color: #000000;
                border: none;
                padding: 12px;
                border-radius: 12px;
                transition: background 0.3s, transform 0.2s;
            }

            QToolButton:hover {
                background-color: #ff3b30;
                color: #ffffff;
                transform: scale(1.05);
            }

            QToolButton:pressed {
                background-color: #cc2900;
                color: #ffffff;
                transform: scale(0.95);
            }

            /* Scrollbar Styles */
            QScrollBar:vertical {
                border: none;
                background: #f0f0f0;
                width: 12px;
                margin: 0px 0px 0px 0px;
            }

            QScrollBar::handle:vertical {
                background: #cccccc;
                min-height: 20px;
                border-radius: 6px;
            }

            QScrollBar::handle:vertical:hover {
                background: #ff3b30;
            }

            QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
                background: none;
                height: 0px;
            }

            /* Tooltip Styles */
            QToolTip {
                background-color: #ffffff;
                color: #000000;
                border: 1px solid #ff3b30;
                padding: 5px;
                border-radius: 8px;
                font-size: 12px;
            }
        """
        self.setStyleSheet(light_stylesheet)

    def update_theme(self, is_dark=True):
        """
        Updates the theme based on user selection.
        """
        if is_dark:
            self.apply_modern_theme()
            self.theme_toggle_button.setText("  Switch to Light Theme")
            self.theme_toggle_button.setToolTip("Toggle to Light Theme")
            logging.info("Applied Dark Theme.")
        else:
            self.apply_light_theme()
            self.theme_toggle_button.setText("  Switch to Dark Theme")
            self.theme_toggle_button.setToolTip("Toggle to Dark Theme")
            logging.info("Applied Light Theme.")

    def toggle_theme(self):
        """
        Switches between dark and light themes.
        """
        if self.theme_toggle_button.text() == "  Switch to Light Theme":
            self.update_theme(is_dark=False)
        else:
            self.update_theme(is_dark=True)

    def toggle_recording_triggered(self):
        """
        Slot connected to the toggle_record signal from hotkeys.
        """
        self.toggle_recording()

    def toggle_playback_triggered(self):
        """
        Slot connected to the toggle_play signal from hotkeys.
        """
        if not self.is_playing:
            self.play_macro()
        else:
            self.pause_playback()

    def toggle_recording(self):
        """
        Starts or stops macro recording based on current state.
        """
        if not self.is_recording:
            self.start_recording()
        else:
            self.stop_recording()

    def start_recording(self):
        """
        Initiates the recording process.
        """
        # Select or create a new macro
        if not self.current_macro:
            macro_name, ok = QtWidgets.QInputDialog.getText(self, "New Macro", "Enter macro name:")
            if ok and macro_name:
                if macro_name in self.macros:
                    QMessageBox.warning(self, "Duplicate Macro", "A macro with this name already exists.")
                    return
                self.macros[macro_name] = []
                self.current_macro = macro_name
                self.macro_selection_dropdown.addItem(macro_name)
                self.macro_selection_dropdown.setCurrentText(macro_name)
                logging.info(f"New macro created: {macro_name}")
            else:
                return

        self.is_recording = True
        self.events = []
        self.clear_event_lists()
        self.record_button.setText("  Stop")
        self.record_button.setToolTip("Stop Recording Macro")
        self.play_button.setEnabled(False)
        self.save_button.setEnabled(False)
        self.clear_button.setEnabled(False)
        self.manage_macros_button.setEnabled(False)
        self.status_bar_label.setText(f"Status: Recording '{self.current_macro}'...")
        self.hotkey_listener.disable_hotkeys()
        self.record_thread = Thread(target=self.recorder_worker.start_recording, daemon=True)
        self.record_thread.start()
        logging.info(f"Recording started for macro: {self.current_macro}")

    def stop_recording(self):
        """
        Stops the ongoing recording process.
        """
        self.recorder_worker.stop_recording()
        self.is_recording = False
        self.record_button.setText("  Record")
        self.record_button.setToolTip("Start Recording Macro")
        self.play_button.setEnabled(True)
        self.save_button.setEnabled(True)
        self.clear_button.setEnabled(True)
        self.manage_macros_button.setEnabled(True)
        self.status_bar_label.setText(f"Status: Idle")
        self.hotkey_listener.enable_hotkeys()
        logging.info(f"Recording stopped for macro: {self.current_macro}")

    def on_recording_finished(self):
        """
        Slot that gets called when recording is finished.
        """
        self.is_recording = False
        self.record_button.setText("  Record")
        self.record_button.setToolTip("Start Recording Macro")
        self.play_button.setEnabled(True)
        self.save_button.setEnabled(True)
        self.clear_button.setEnabled(True)
        self.manage_macros_button.setEnabled(True)
        self.status_bar_label.setText(f"Status: Idle")
        self.hotkey_listener.enable_hotkeys()
        logging.info("Recording finished signal received.")

    def on_event_recorded(self, event):
        """
        Slot that gets called when a new event is recorded.
        """
        self.events.append(event)
        self.macros[self.current_macro].append(event)
        self.add_event_to_list(event)

    def add_event_to_list(self, event):
        """
        Adds the recorded event to the appropriate event list in the UI.
        """
        if event.event_type == 'mouse_move':
            text = f"Position: {event.details['position']} | Delay: {event.timestamp:.2f}s"
            self.mouse_move_tab.addItem(text)
        elif event.event_type in ['mouse_click_pressed', 'mouse_click_released']:
            action = "Pressed" if 'pressed' in event.event_type else "Released"
            button = event.details['button']
            text = f"{action} {button} at {event.details['position']} | Delay: {event.timestamp:.2f}s"
            self.mouse_click_tab.addItem(text)
        elif event.event_type == 'mouse_scroll':
            dx = event.details['dx']
            dy = event.details['dy']
            position = event.details['position']
            text = f"Scroll ({dx}, {dy}) at {position} | Delay: {event.timestamp:.2f}s"
            self.mouse_scroll_tab.addItem(text)
        elif event.event_type in ['key_press', 'key_release']:
            action = "Pressed" if 'press' in event.event_type else "Released"
            key = event.details['key']
            key_str = self.format_key(key)
            text = f"{action} {key_str} | Delay: {event.timestamp:.2f}s"
            self.keyboard_tab.addItem(text)

    def format_key(self, key):
        """
        Formats the key object into a readable string.
        """
        if isinstance(key, KeyCode):
            return key.char.upper() if key.char else str(key).capitalize()
        else:
            return str(key).replace("Key.", "").capitalize()

    def clear_event_lists(self):
        """
        Clears all event lists in the UI.
        """
        self.mouse_move_tab.clear()
        self.mouse_click_tab.clear()
        self.mouse_scroll_tab.clear()
        self.keyboard_tab.clear()
        self.details_panel.clear()

    def play_macro(self):
        """
        Initiates the playback of the current macro.
        """
        if not self.current_macro or not self.macros.get(self.current_macro):
            QMessageBox.warning(self, "Play Macro", "No macro selected or macro is empty.")
            return

        try:
            self.events = self.macros[self.current_macro]
            if not self.events:
                QMessageBox.warning(self, "Play Macro", "Current macro is empty.")
                return

            self.is_playing = True
            self.continuous_playback = self.continuous_playback_checkbox.isChecked()
            
            # Update UI
            self.play_button.setEnabled(False)
            self.record_button.setEnabled(False)
            self.save_button.setEnabled(False)
            self.load_button.setEnabled(False)
            self.clear_button.setEnabled(False)
            self.manage_macros_button.setEnabled(False)
            self.pause_button.setEnabled(True)
            self.stop_button.setEnabled(True)
            self.status_bar_label.setText(f"Status: Playing '{self.current_macro}'...")
            self.progress_bar.setVisible(True)
            self.progress_bar.setMaximum(len(self.events))
            self.progress_bar.setValue(0)
            self.hotkey_listener.disable_hotkeys()

            # Initialize Player Worker
            self.player_worker = PlayerWorker(self.events, self.signals, continuous=self.continuous_playback)
            
            # Connect signals
            self.player_worker.playback_finished.connect(self.update_progress)
            self.player_worker.playback_error.connect(self.on_playback_error)
            
            # Start playback thread
            self.play_thread = Thread(target=self.player_worker.play_events, daemon=True)
            self.play_thread.start()
            
            logging.info(f"Playback started for macro: {self.current_macro}")
        except Exception as e:
            logging.error(f"Error starting playback: {e}")
            self.on_playback_error(str(e))

    def update_progress(self):
        """
        Updates the progress bar during playback.
        """
        current_value = self.progress_bar.value() + 1
        self.progress_bar.setValue(current_value)
        if current_value >= self.progress_bar.maximum():
            self.on_playback_finished()

    def pause_playback(self):
        """
        Pauses or resumes the playback.
        """
        if self.player_worker and self.is_playing:
            # Currently playing, so pause
            self.player_worker.pause_playback()
            self.is_playing = False
            self.pause_button.setText("  Resume")
            self.status_bar_label.setText(f"Status: Playback Paused for '{self.current_macro}'...")
            logging.info("Playback paused.")
        else:
            # Resume playback
            if self.player_worker and not self.is_playing:
                self.player_worker.resume_playback()
                self.is_playing = True
                self.pause_button.setText("  Pause")
                self.status_bar_label.setText(f"Status: Playing '{self.current_macro}'...")
                logging.info("Playback resumed.")

    def stop_playback(self):
        """
        Stops the ongoing playback.
        """
        if self.player_worker:
            self.player_worker.stop_playback()
            self.is_playing = False
            self.play_button.setEnabled(True)
            self.record_button.setEnabled(True)
            self.save_button.setEnabled(True)
            self.load_button.setEnabled(True)
            self.clear_button.setEnabled(True)
            self.manage_macros_button.setEnabled(True)
            self.pause_button.setEnabled(False)
            self.stop_button.setEnabled(False)
            self.pause_button.setText("  Pause")
            self.progress_bar.setVisible(False)
            self.progress_bar.setValue(0)
            self.status_bar_label.setText("Status: Idle")
            self.hotkey_listener.enable_hotkeys()
            logging.info("Playback stopped by user.")

    def on_playback_finished(self):
        """
        Slot that gets called when playback is finished.
        """
        self.is_playing = False
        self.play_button.setEnabled(True)
        self.record_button.setEnabled(True)
        self.save_button.setEnabled(True)
        self.load_button.setEnabled(True)
        self.clear_button.setEnabled(True)
        self.manage_macros_button.setEnabled(True)
        self.pause_button.setEnabled(False)
        self.stop_button.setEnabled(False)
        self.pause_button.setText("  Pause")
        self.progress_bar.setVisible(False)
        self.progress_bar.setValue(0)
        self.status_bar_label.setText("Status: Idle")
        self.hotkey_listener.enable_hotkeys()
        QMessageBox.information(self, "Playback", f"Macro '{self.current_macro}' playback completed.")
        logging.info(f"Playback finished for macro: {self.current_macro}")

    def on_playback_error(self, error):
        """
        Slot that gets called when an error occurs during playback.
        """
        QMessageBox.critical(self, "Playback Error", f"An error occurred during playback:\n{error}")
        self.is_playing = False
        self.play_button.setEnabled(True)
        self.record_button.setEnabled(True)
        self.save_button.setEnabled(True)
        self.load_button.setEnabled(True)
        self.clear_button.setEnabled(True)
        self.manage_macros_button.setEnabled(True)
        self.pause_button.setEnabled(False)
        self.stop_button.setEnabled(False)
        self.pause_button.setText("  Pause")
        self.progress_bar.setVisible(False)
        self.progress_bar.setValue(0)
        self.status_bar_label.setText("Status: Idle")
        self.hotkey_listener.enable_hotkeys()
        logging.error(f"Playback error: {error}")

    def save_macro(self):
        """
        Saves the current macro to a file.
        """
        if not self.current_macro or not self.macros.get(self.current_macro):
            QMessageBox.warning(self, "Save Macro", "No macro selected or macro is empty.")
            return

        options = QFileDialog.Options()
        file_path, _ = QFileDialog.getSaveFileName(
            self, "Save Macro", f"{self.current_macro}.macro", "Macro Files (*.macro);;All Files (*)", options=options
        )
        if file_path:
            try:
                with open(file_path, 'wb') as f:
                    pickle.dump(self.macros[self.current_macro], f)
                QMessageBox.information(self, "Save Macro",
                                        f"Macro '{self.current_macro}' saved successfully to {file_path}.")
                logging.info(f"Macro saved: {self.current_macro} at {file_path}")
            except Exception as e:
                QMessageBox.critical(self, "Save Macro", f"Failed to save macro:\n{e}")
                logging.error(f"Failed to save macro {self.current_macro}: {e}")

    def load_macro(self):
        """
        Loads one or multiple macros from files.
        """
        options = QFileDialog.Options()
        file_paths, _ = QFileDialog.getOpenFileNames(
            self, "Load Macro", "", "Macro Files (*.macro);;All Files (*)", options=options
        )
        if file_paths:
            for file_path in file_paths:
                try:
                    with open(file_path, 'rb') as f:
                        events = pickle.load(f)
                    macro_name = file_path.split("/")[-1].split(".macro")[0]
                    if macro_name in self.macros:
                        QMessageBox.warning(self, "Load Macro",
                                            f"A macro named '{macro_name}' already exists. Skipping.")
                        continue
                    self.macros[macro_name] = events
                    self.macro_selection_dropdown.addItem(macro_name)
                    QMessageBox.information(self, "Load Macro",
                                            f"Macro '{macro_name}' loaded successfully.")
                    logging.info(f"Macro loaded: {macro_name} from {file_path}")
                except Exception as e:
                    QMessageBox.critical(self, "Load Macro",
                                         f"Failed to load macro from {file_path}:\n{e}")
                    logging.error(f"Failed to load macro from {file_path}: {e}")

    def manage_macros(self):
        """
        Opens the macro manager dialog to manage existing macros.
        """
        if not self.macros:
            QMessageBox.information(self, "Manage Macros", "No macros available to manage.")
            return
        dialog = MacroManagerDialog(self, macros=self.macros)
        dialog.exec_()
        # Update macro selection dropdown if any changes occurred
        self.update_macro_dropdown()

    def update_macro_dropdown(self):
        """
        Updates the macro selection dropdown after changes.
        """
        previous_macro = self.current_macro
        self.macro_selection_dropdown.clear()
        self.macro_selection_dropdown.addItems(self.macros.keys())
        if self.macros:
            if previous_macro in self.macros:
                self.current_macro = previous_macro
                self.macro_selection_dropdown.setCurrentText(self.current_macro)
            else:
                self.current_macro = list(self.macros.keys())[0]
                self.macro_selection_dropdown.setCurrentText(self.current_macro)
            self.play_button.setEnabled(True)
            self.save_button.setEnabled(True)
            self.clear_button.setEnabled(True)
        else:
            self.current_macro = None
            self.play_button.setEnabled(False)
            self.save_button.setEnabled(False)
            self.clear_button.setEnabled(False)
        logging.info("Macro selection dropdown updated.")

    def clear_events(self):
        """
        Clears all events from the current macro.
        """
        if self.current_macro:
            reply = QMessageBox.question(self, "Clear Macro",
                                         f"Are you sure you want to clear all events from macro '{self.current_macro}'?",
                                         QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if reply == QMessageBox.Yes:
                self.macros[self.current_macro] = []
                self.clear_event_lists()
                self.play_button.setEnabled(False)
                self.save_button.setEnabled(False)
                self.clear_button.setEnabled(False)
                logging.info(f"All events cleared from macro: {self.current_macro}")
        else:
            self.clear_event_lists()
            self.play_button.setEnabled(False)
            self.save_button.setEnabled(False)
            self.clear_button.setEnabled(False)

    def update_mouse_position(self):
        """
        Updates the mouse position label with the current cursor position.
        """
        try:
            controller = mouse.Controller()
            position = controller.position
            self.mouse_position_label.setText(f"Mouse Position: {position}")
        except Exception as e:
            self.mouse_position_label.setText("Mouse Position: Error")
            logging.error(f"Failed to update mouse position: {e}")

    def display_event_details(self, item):
        """
        Displays details of the selected event in the details panel.
        """
        event_text = item.text()
        self.details_panel.setText(event_text)

    def search_events(self, text):
        """
        Searches for events containing the specified text in the current tab.
        """
        current_tab = self.tabs.currentWidget()
        for index in range(current_tab.count()):
            item = current_tab.item(index)
            if text.lower() in item.text().lower():
                current_tab.setCurrentRow(index)
                self.display_event_details(item)
                break

    def select_macro(self, index):
        """
        Handles macro selection from the dropdown.
        """
        if index >= 0:
            self.current_macro = self.macro_selection_dropdown.currentText()
            self.clear_event_lists()
            for event in self.macros[self.current_macro]:
                self.add_event_to_list(event)
            self.status_bar_label.setText(f"Status: Selected '{self.current_macro}'")
            self.play_button.setEnabled(True)
            self.save_button.setEnabled(True)
            self.clear_button.setEnabled(True)
            logging.info(f"Macro selected: {self.current_macro}")

    def open_settings(self):
        """
        Opens the settings dialog for configuring hotkeys.
        """
        dialog = HotkeyDialog(self, current_hotkeys=self.hotkeys)
        if dialog.exec_():
            new_hotkeys = dialog.get_hotkeys()
            self.hotkeys = new_hotkeys
            self.hotkey_listener.update_hotkeys(self.hotkeys)
            QMessageBox.information(self, "Settings", "Hotkeys updated successfully.")
            logging.info("Hotkeys updated.")

# Entry Point of the Application
def main():
    """
    The main function to run the application.
    """
    app = QApplication(sys.argv)
    app.setStyle("Fusion")  # Change style for better aesthetics

    # Set a modern font
    font = QFont("Segoe UI", 10)
    app.setFont(font)

    # Initialize and display the main window
    window = MacroRecorderPlayer()
    window.show()

    sys.exit(app.exec_())

if __name__ == "__main__":
    main() please enhance the gui alot do a full complete new layout for eeverything which is alot better no bugs make sure to completly concetrate on perfefct gui with no bugs fully revamp the gui all styles revamped colors aqua do like also a dot in green when ready to start animated ofc and yellow playback started and red is offline