#!/usr/bin/python

import sys
import subprocess
import threading
import time
import os
import re
from datetime import datetime
from PyQt6.QtWidgets import *
from PyQt6.QtCore import *
from PyQt6.QtGui import *


class SudoPasswordDialog(QDialog):
    """Dialog for entering sudo password"""
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Authentication Required")
        self.setModal(True)
        self.setFixedSize(400, 200)
        self.password = None
        
        layout = QVBoxLayout()
        
        # Message
        message = QLabel("Root privileges are required for this operation.")
        message.setWordWrap(True)
        layout.addWidget(message)
        
        # Password field
        password_layout = QHBoxLayout()
        password_label = QLabel("Password:")
        self.password_input = QLineEdit()
        self.password_input.setEchoMode(QLineEdit.EchoMode.Password)
        password_layout.addWidget(password_label)
        password_layout.addWidget(self.password_input)
        layout.addLayout(password_layout)
        
        # Remember checkbox
        self.remember_checkbox = QCheckBox("Remember password for this session")
        layout.addWidget(self.remember_checkbox)
        
        # Buttons
        button_box = QDialogButtonBox(
            QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
        )
        button_box.accepted.connect(self.accept_password)
        button_box.rejected.connect(self.reject)
        layout.addWidget(button_box)
        
        self.setLayout(layout)
        
    def accept_password(self):
        self.password = self.password_input.text()
        self.remember = self.remember_checkbox.isChecked()
        self.accept()


class InitSystemDetector:
    """Detect and handle different init systems"""
    
    @staticmethod
    def detect():
        """Detect which init system is running"""
        try:
            # Check for systemd
            if os.path.exists('/run/systemd/system/'):
                return 'systemd'
            
            # Check for OpenRC
            if os.path.exists('/run/openrc/'):
                return 'openrc'
            
            # Check process 1
            try:
                pid1_link = os.readlink('/proc/1/exe')
                if 'systemd' in pid1_link:
                    return 'systemd'
                elif 'init' in pid1_link:
                    # Could be OpenRC or sysvinit
                    # Check for OpenRC init scripts
                    if os.path.exists('/etc/init.d/') and os.path.exists('/etc/runlevels/'):
                        return 'openrc'
            except:
                pass
            
            # Default to systemd if can't determine
            return 'systemd'
            
        except Exception as e:
            print(f"Error detecting init system: {e}")
            return 'systemd'
    
    @staticmethod
    def get_service_commands(service_name, action, use_sudo=True):
        """Get appropriate commands for the current init system"""
        init_system = InitSystemDetector.detect()
        
        # Use different service names for different init systems
        if init_system == 'systemd':
            service_cmd = service_name  # 'bluetooth' for systemd
        elif init_system == 'openrc':
            service_cmd = 'bluetoothd'  # 'bluetoothd' for OpenRC
        else:
            service_cmd = service_name
        
        if init_system == 'systemd':
            if action == 'start':
                cmd = ['systemctl', 'start', service_cmd]
            elif action == 'stop':
                cmd = ['systemctl', 'stop', service_cmd]
            elif action == 'restart':
                cmd = ['systemctl', 'restart', service_cmd]
            elif action == 'status':
                cmd = ['systemctl', 'status', service_cmd]
            elif action == 'enable':
                cmd = ['systemctl', 'enable', service_cmd]
            elif action == 'disable':
                cmd = ['systemctl', 'disable', service_cmd]
            elif action == 'is-active':
                cmd = ['systemctl', 'is-active', service_cmd]
            elif action == 'is-enabled':
                cmd = ['systemctl', 'is-enabled', service_cmd]
            else:
                raise ValueError(f"Unknown action: {action}")
                
        elif init_system == 'openrc':
            # Use /etc/init.d/ for service management
            if action == 'start':
                cmd = ['/etc/init.d/', service_cmd, 'start']
            elif action == 'stop':
                cmd = ['/etc/init.d/', service_cmd, 'stop']
            elif action == 'restart':
                cmd = ['/etc/init.d/', service_cmd, 'restart']
            elif action == 'status':
                cmd = ['/etc/init.d/', service_cmd, 'status']
            elif action == 'enable':
                # For OpenRC, add to default runlevel using rc-update
                cmd = ['rc-update', 'add', service_cmd, 'default']
            elif action == 'disable':
                cmd = ['rc-update', 'del', service_cmd]
            elif action == 'is-active':
                # Check if service is running
                cmd = ['/etc/init.d/', service_cmd, 'status']
            elif action == 'is-enabled':
                # For OpenRC, check if service is in any runlevel
                cmd = ['rc-update', 'show']
            else:
                raise ValueError(f"Unknown action: {action}")
        else:
            raise ValueError(f"Unsupported init system: {init_system}")
        
        return cmd, init_system, service_cmd


class BluetoothManager(QMainWindow):
    def __init__(self):
        super().__init__()
        self.scanning = False
        self.scan_thread = None
        self.devices = {}
        self.init_system = InitSystemDetector.detect()
        self.sudo_password = None
        self.password_remembered = False
        
        # Set service name based on init system
        if self.init_system == 'systemd':
            self.service_name = 'bluetooth'
        else:
            self.service_name = 'bluetoothd'
            
        self.init_ui()
        self.check_bluetooth_service()
        
    def init_ui(self):
        """Initialize the user interface"""
        self.setWindowTitle(f"Bluetooth Device Manager ({self.init_system})")
        self.setGeometry(100, 100, 1000, 750)
        
        # Central widget
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        layout = QVBoxLayout(central_widget)
        
        # Service status section
        service_frame = QGroupBox("Bluetooth Service Management")
        service_layout = QGridLayout()
        
        # Init system indicator
        init_label = QLabel("Init System:")
        init_label.setStyleSheet("font-weight: bold; color: #E0E0E0;")
        
        self.init_system_label = QLabel(self.init_system.upper())
        self.init_system_label.setStyleSheet("color: #4CAF50; font-weight: bold; background-color: #2C2C2C; padding: 3px; border-radius: 3px;")
        
        # Service name
        service_name_label = QLabel("Service:")
        service_name_label.setStyleSheet("font-weight: bold; color: #E0E0E0;")
        
        self.service_name_label = QLabel(self.service_name)
        self.service_name_label.setStyleSheet("color: #2196F3; font-weight: bold; background-color: #2C2C2C; padding: 3px; border-radius: 3px;")
        
        # Service status
        status_title = QLabel("Service Status:")
        status_title.setStyleSheet("font-weight: bold; color: #E0E0E0;")
        
        self.status_label = QLabel("Checking...")
        self.status_label.setStyleSheet("font-weight: bold; padding: 8px; border-radius: 4px; background-color: #2C2C2C;")
        
        # Service actions
        button_layout = QHBoxLayout()
        
        self.start_btn = QPushButton("▶ Start")
        self.start_btn.clicked.connect(lambda: self.manage_service('start'))
        self.start_btn.setStyleSheet("""
            QPushButton {
                background-color: #4CAF50;
                color: white;
                padding: 8px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #45a049;
            }
            QPushButton:disabled {
                background-color: #666666;
                color: #999999;
            }
        """)
        
        self.stop_btn = QPushButton("⏹ Stop")
        self.stop_btn.clicked.connect(lambda: self.manage_service('stop'))
        self.stop_btn.setStyleSheet("""
            QPushButton {
                background-color: #f44336;
                color: white;
                padding: 8px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #da190b;
            }
            QPushButton:disabled {
                background-color: #666666;
                color: #999999;
            }
        """)
        
        self.restart_btn = QPushButton("↻ Restart")
        self.restart_btn.clicked.connect(lambda: self.manage_service('restart'))
        self.restart_btn.setStyleSheet("""
            QPushButton {
                background-color: #2196F3;
                color: white;
                padding: 8px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #0b7dda;
            }
            QPushButton:disabled {
                background-color: #666666;
                color: #999999;
            }
        """)
        
        self.enable_btn = QPushButton("✓ Enable Auto-start")
        self.enable_btn.clicked.connect(lambda: self.manage_service('enable'))
        self.enable_btn.setStyleSheet("""
            QPushButton {
                background-color: #FF9800;
                color: white;
                padding: 8px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #e68900;
            }
        """)
        
        self.disable_btn = QPushButton("✗ Disable Auto-start")
        self.disable_btn.clicked.connect(lambda: self.manage_service('disable'))
        self.disable_btn.setStyleSheet("""
            QPushButton {
                background-color: #9E9E9E;
                color: white;
                padding: 8px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #7A7A7A;
            }
        """)
        
        button_layout.addWidget(self.start_btn)
        button_layout.addWidget(self.stop_btn)
        button_layout.addWidget(self.restart_btn)
        button_layout.addWidget(self.enable_btn)
        button_layout.addWidget(self.disable_btn)
        
        # Auto-start status
        auto_start_layout = QHBoxLayout()
        auto_start_label = QLabel("Auto-start:")
        auto_start_label.setStyleSheet("font-weight: bold; color: #E0E0E0;")
        
        self.auto_start_status = QLabel("Checking...")
        self.auto_start_status.setStyleSheet("font-weight: bold; padding: 4px; border-radius: 3px;")
        
        auto_start_layout.addWidget(auto_start_label)
        auto_start_layout.addWidget(self.auto_start_status)
        auto_start_layout.addStretch()
        
        # Add widgets to grid
        service_layout.addWidget(init_label, 0, 0)
        service_layout.addWidget(self.init_system_label, 0, 1)
        service_layout.addWidget(service_name_label, 0, 2)
        service_layout.addWidget(self.service_name_label, 0, 3)
        service_layout.addWidget(status_title, 1, 0)
        service_layout.addWidget(self.status_label, 1, 1, 1, 3)
        service_layout.addLayout(button_layout, 2, 0, 1, 4)
        service_layout.addLayout(auto_start_layout, 3, 0, 1, 4)
        
        service_frame.setLayout(service_layout)
        
        # Control buttons section
        control_frame = QGroupBox("Scan Controls")
        control_layout = QHBoxLayout()
        
        self.scan_button = QPushButton("🔍 Start Scan")
        self.scan_button.clicked.connect(self.toggle_scan)
        self.scan_button.setStyleSheet("""
            QPushButton {
                background-color: #4CAF50;
                color: white;
                padding: 10px;
                border-radius: 4px;
                font-weight: bold;
                font-size: 14px;
            }
            QPushButton:hover {
                background-color: #45a049;
            }
        """)
        
        self.refresh_button = QPushButton("⟳ Refresh Devices")
        self.refresh_button.clicked.connect(self.refresh_devices)
        self.refresh_button.setStyleSheet("""
            QPushButton {
                background-color: #2196F3;
                color: white;
                padding: 10px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #0b7dda;
            }
        """)
        
        self.agent_button = QPushButton("🛡 Start Agent")
        self.agent_button.clicked.connect(self.start_agent)
        self.agent_button.setStyleSheet("""
            QPushButton {
                background-color: #9C27B0;
                color: white;
                padding: 10px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #7B1FA2;
            }
        """)
        
        self.power_button = QPushButton("🔌 Power On")
        self.power_button.clicked.connect(self.toggle_power)
        self.power_button.setStyleSheet("""
            QPushButton {
                background-color: #FF9800;
                color: white;
                padding: 10px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #e68900;
            }
        """)
        
        control_layout.addWidget(self.scan_button)
        control_layout.addWidget(self.refresh_button)
        control_layout.addWidget(self.agent_button)
        control_layout.addWidget(self.power_button)
        control_layout.addStretch()
        control_frame.setLayout(control_layout)
        
        # Device list section
        devices_frame = QGroupBox("Available Devices")
        devices_frame.setStyleSheet("QGroupBox { color: #E0E0E0; }")
        devices_layout = QVBoxLayout()
        
        # Create table for devices
        self.device_table = QTableWidget()
        self.device_table.setColumnCount(7)
        self.device_table.setHorizontalHeaderLabels(["MAC Address", "Name", "Alias", "Paired", "Trusted", "Connected", "Blocked"])
        self.device_table.horizontalHeader().setStretchLastSection(True)
        self.device_table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
        self.device_table.setSelectionMode(QTableWidget.SelectionMode.SingleSelection)
        self.device_table.setAlternatingRowColors(True)
        self.device_table.setStyleSheet("""
            QTableWidget {
                background-color: #2C2C2C;
                color: #E0E0E0;
                gridline-color: #444444;
                alternate-background-color: #353535;
            }
            QHeaderView::section {
                background-color: #3C3C3C;
                color: #E0E0E0;
                padding: 6px;
                border: 1px solid #444444;
                font-weight: bold;
            }
        """)
        
        devices_layout.addWidget(self.device_table)
        devices_frame.setLayout(devices_layout)
        
        # Action buttons section
        action_frame = QGroupBox("Device Actions")
        action_frame.setStyleSheet("QGroupBox { color: #E0E0E0; }")
        action_layout = QHBoxLayout()
        
        self.pair_button = QPushButton("🤝 Pair")
        self.pair_button.clicked.connect(self.pair_device)
        self.pair_button.setEnabled(False)
        self.pair_button.setStyleSheet(self.get_action_button_style("#4CAF50"))
        
        self.trust_button = QPushButton("✓ Trust")
        self.trust_button.clicked.connect(self.trust_device)
        self.trust_button.setEnabled(False)
        self.trust_button.setStyleSheet(self.get_action_button_style("#FF9800"))
        
        self.connect_button = QPushButton("🔗 Connect")
        self.connect_button.clicked.connect(self.connect_device)
        self.connect_button.setEnabled(False)
        self.connect_button.setStyleSheet(self.get_action_button_style("#2196F3"))
        
        self.disconnect_button = QPushButton("🔌 Disconnect")
        self.disconnect_button.clicked.connect(self.disconnect_device)
        self.disconnect_button.setEnabled(False)
        self.disconnect_button.setStyleSheet(self.get_action_button_style("#9C27B0"))
        
        self.remove_button = QPushButton("🗑 Remove")
        self.remove_button.clicked.connect(self.remove_device)
        self.remove_button.setEnabled(False)
        self.remove_button.setStyleSheet(self.get_action_button_style("#f44336"))
        
        self.block_button = QPushButton("🚫 Block")
        self.block_button.clicked.connect(self.block_device)
        self.block_button.setEnabled(False)
        self.block_button.setStyleSheet(self.get_action_button_style("#FF5722"))
        
        self.info_button = QPushButton("ℹ Info")
        self.info_button.clicked.connect(self.show_device_info)
        self.info_button.setEnabled(False)
        self.info_button.setStyleSheet(self.get_action_button_style("#607D8B"))
        
        action_layout.addWidget(self.pair_button)
        action_layout.addWidget(self.trust_button)
        action_layout.addWidget(self.connect_button)
        action_layout.addWidget(self.disconnect_button)
        action_layout.addWidget(self.remove_button)
        action_layout.addWidget(self.block_button)
        action_layout.addWidget(self.info_button)
        action_layout.addStretch()
        action_frame.setLayout(action_layout)
        
        # Log section
        log_frame = QGroupBox("Activity Log")
        log_frame.setStyleSheet("QGroupBox { color: #E0E0E0; }")
        log_layout = QVBoxLayout()
        
        self.log_text = QTextEdit()
        self.log_text.setReadOnly(True)
        self.log_text.setMaximumHeight(150)
        self.log_text.setStyleSheet("""
            QTextEdit {
                background-color: #2C2C2C;
                color: #E0E0E0;
                border: 1px solid #444444;
                border-radius: 3px;
                font-family: monospace;
            }
        """)
        
        button_layout_log = QHBoxLayout()
        self.clear_log_button = QPushButton("🗑 Clear Log")
        self.clear_log_button.clicked.connect(lambda: self.log_text.clear())
        self.clear_log_button.setStyleSheet("""
            QPushButton {
                background-color: #666666;
                color: white;
                padding: 6px;
                border-radius: 4px;
            }
            QPushButton:hover {
                background-color: #555555;
            }
        """)
        
        self.export_log_button = QPushButton("💾 Export Log")
        self.export_log_button.clicked.connect(self.export_log)
        self.export_log_button.setStyleSheet("""
            QPushButton {
                background-color: #4CAF50;
                color: white;
                padding: 6px;
                border-radius: 4px;
            }
            QPushButton:hover {
                background-color: #45a049;
            }
        """)
        
        button_layout_log.addWidget(self.clear_log_button)
        button_layout_log.addWidget(self.export_log_button)
        button_layout_log.addStretch()
        
        log_layout.addWidget(self.log_text)
        log_layout.addLayout(button_layout_log)
        log_frame.setLayout(log_layout)
        
        # Add all frames to main layout
        layout.addWidget(service_frame)
        layout.addWidget(control_frame)
        layout.addWidget(devices_frame)
        layout.addWidget(action_frame)
        layout.addWidget(log_frame)
        
        # Connect table selection
        self.device_table.itemSelectionChanged.connect(self.on_device_selected)
        
        # Timer for periodic status updates
        self.status_timer = QTimer()
        self.status_timer.timeout.connect(self.update_status)
        self.status_timer.start(5000)  # Update every 5 seconds
        
        self.log_message("Application started", "info")
        self.log_message(f"Detected init system: {self.init_system}", "info")
        self.log_message(f"Using service name: {self.service_name}", "info")
        
    def get_action_button_style(self, color):
        """Generate style for action buttons"""
        return f"""
            QPushButton {{
                background-color: {color};
                color: white;
                padding: 8px;
                border-radius: 4px;
                font-weight: bold;
            }}
            QPushButton:hover {{
                background-color: {self.darken_color(color)};
            }}
            QPushButton:disabled {{
                background-color: #666666;
                color: #999999;
            }}
        """
    
    def darken_color(self, color):
        """Darken a hex color for hover effect"""
        # Simple darkening - remove this function or implement properly
        # For now, return the same color
        return color
        
    def log_message(self, message, level="info"):
        """Add message to log with timestamp"""
        timestamp = datetime.now().strftime("%H:%M:%S")
        color_map = {
            "info": "#E0E0E0",
            "success": "#4CAF50",
            "error": "#f44336",
            "warning": "#FF9800",
            "debug": "#2196F3"
        }
        color = color_map.get(level, "#E0E0E0")
        
        icon_map = {
            "info": "ℹ",
            "success": "✓",
            "error": "✗",
            "warning": "⚠",
            "debug": "🔧"
        }
        icon = icon_map.get(level, "ℹ")
        
        formatted_message = f'<span style="color: #888888;">[{timestamp}]</span> <span style="color: {color};">{icon} {message}</span>'
        self.log_text.append(formatted_message)
        
        # Auto-scroll to bottom
        scrollbar = self.log_text.verticalScrollBar()
        scrollbar.setValue(scrollbar.maximum())
        
    def get_sudo_password(self):
        """Get sudo password from user via GUI dialog"""
        if self.password_remembered and self.sudo_password:
            return self.sudo_password
            
        dialog = SudoPasswordDialog(self)
        if dialog.exec() == QDialog.DialogCode.Accepted:
            self.sudo_password = dialog.password
            self.password_remembered = dialog.remember
            return self.sudo_password
        return None
        
    def run_command(self, command, use_sudo=False, require_password=False):
        """Run shell command and return output"""
        try:
            full_command = command.copy()
            
            if use_sudo:
                if require_password:
                    password = self.get_sudo_password()
                    if password is None:
                        return -1, "", "Authentication cancelled"
                    
                    # Use sudo with password via stdin
                    full_command = ['sudo', '-S'] + command
                    
                    result = subprocess.run(
                        full_command,
                        input=password + '\n',
                        capture_output=True,
                        text=True,
                        timeout=30
                    )
                else:
                    full_command = ['sudo'] + command
                    result = subprocess.run(
                        full_command,
                        capture_output=True,
                        text=True,
                        timeout=30
                    )
            else:
                result = subprocess.run(
                    full_command,
                    capture_output=True,
                    text=True,
                    timeout=30
                )
            
            return result.returncode, result.stdout, result.stderr
            
        except subprocess.TimeoutExpired:
            return -1, "", "Command timed out"
        except Exception as e:
            return -1, "", str(e)
            
    def check_bluetooth_service(self):
        """Check if Bluetooth service is running and enabled"""
        self.update_service_status()
        self.update_auto_start_status()
            
    def update_service_status(self):
        """Update service running status"""
        try:
            # Check service status
            if self.init_system == 'systemd':
                # For systemd
                returncode, stdout, stderr = self.run_command(['systemctl', 'is-active', self.service_name])
                if returncode == 0 and stdout.strip() == 'active':
                    self.service_running = True
                    self.status_label.setText("RUNNING")
                    self.status_label.setStyleSheet("color: #4CAF50; font-weight: bold; padding: 8px; background-color: #1B5E20; border-radius: 4px;")
                else:
                    self.service_running = False
                    self.status_label.setText("STOPPED")
                    self.status_label.setStyleSheet("color: #f44336; font-weight: bold; padding: 8px; background-color: #B71C1C; border-radius: 4px;")
                    
            elif self.init_system == 'openrc':
                # For OpenRC, check using /etc/init.d/
                init_script = f'/etc/init.d/{self.service_name}'
                if os.path.exists(init_script):
                    returncode, stdout, stderr = self.run_command([init_script, 'status'])
                    if returncode == 0 and ('running' in stdout.lower() or 'started' in stdout.lower()):
                        self.service_running = True
                        self.status_label.setText("RUNNING")
                        self.status_label.setStyleSheet("color: #4CAF50; font-weight: bold; padding: 8px; background-color: #1B5E20; border-radius: 4px;")
                    else:
                        self.service_running = False
                        self.status_label.setText("STOPPED")
                        self.status_label.setStyleSheet("color: #f44336; font-weight: bold; padding: 8px; background-color: #B71C1C; border-radius: 4px;")
                else:
                    # If init script doesn't exist, check via pid
                    returncode, stdout, stderr = self.run_command(['pgrep', '-f', self.service_name])
                    if returncode == 0:
                        self.service_running = True
                        self.status_label.setText("RUNNING")
                        self.status_label.setStyleSheet("color: #4CAF50; font-weight: bold; padding: 8px; background-color: #1B5E20; border-radius: 4px;")
                    else:
                        self.service_running = False
                        self.status_label.setText("STOPPED")
                        self.status_label.setStyleSheet("color: #f44336; font-weight: bold; padding: 8px; background-color: #B71C1C; border-radius: 4px;")
            
            # Update button states
            self.start_btn.setEnabled(not self.service_running)
            self.stop_btn.setEnabled(self.service_running)
            self.restart_btn.setEnabled(self.service_running)
                
        except Exception as e:
            self.log_message(f"Error checking service status: {str(e)}", "error")
            
    def update_auto_start_status(self):
        """Update service auto-start status"""
        try:
            if self.init_system == 'systemd':
                returncode, stdout, stderr = self.run_command(['systemctl', 'is-enabled', self.service_name])
                if returncode == 0 and stdout.strip() == 'enabled':
                    self.auto_start_status.setText("Enabled")
                    self.auto_start_status.setStyleSheet("color: #4CAF50; font-weight: bold; padding: 4px; background-color: #1B5E20; border-radius: 3px;")
                    self.enable_btn.setEnabled(False)
                    self.disable_btn.setEnabled(True)
                else:
                    self.auto_start_status.setText("Disabled")
                    self.auto_start_status.setStyleSheet("color: #f44336; font-weight: bold; padding: 4px; background-color: #B71C1C; border-radius: 3px;")
                    self.enable_btn.setEnabled(True)
                    self.disable_btn.setEnabled(False)
                    
            elif self.init_system == 'openrc':
                # For OpenRC, check if service is in any runlevel
                returncode, stdout, stderr = self.run_command(['rc-update', 'show'])
                
                if returncode == 0 and self.service_name in stdout:
                    self.auto_start_status.setText("Enabled")
                    self.auto_start_status.setStyleSheet("color: #4CAF50; font-weight: bold; padding: 4px; background-color: #1B5E20; border-radius: 3px;")
                    self.enable_btn.setEnabled(False)
                    self.disable_btn.setEnabled(True)
                else:
                    self.auto_start_status.setText("Disabled")
                    self.auto_start_status.setStyleSheet("color: #f44336; font-weight: bold; padding: 4px; background-color: #B71C1C; border-radius: 3px;")
                    self.enable_btn.setEnabled(True)
                    self.disable_btn.setEnabled(False)
                    
        except Exception as e:
            self.log_message(f"Error checking auto-start status: {str(e)}", "error")
            
    def manage_service(self, action):
        """Manage Bluetooth service (start, stop, restart, enable, disable)"""
        try:
            if action in ['start', 'stop', 'restart']:
                confirm_msg = {
                    'start': f'Start {self.service_name} service?',
                    'stop': f'Stop {self.service_name} service?',
                    'restart': f'Restart {self.service_name} service?'
                }.get(action)
                
                reply = QMessageBox.question(self, 'Confirm', confirm_msg,
                                           QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
                if reply != QMessageBox.StandardButton.Yes:
                    return
            
            self.log_message(f"{action.capitalize()}ing {self.service_name} service...", "info")
            
            if self.init_system == 'systemd':
                # Systemd commands
                if action in ['start', 'stop', 'restart']:
                    cmd = ['systemctl', action, self.service_name]
                elif action == 'enable':
                    cmd = ['systemctl', 'enable', self.service_name]
                elif action == 'disable':
                    cmd = ['systemctl', 'disable', self.service_name]
                    
                returncode, stdout, stderr = self.run_command(cmd, use_sudo=True, require_password=True)
                
            elif self.init_system == 'openrc':
                # OpenRC commands using /etc/init.d/
                init_script = f'/etc/init.d/{self.service_name}'
                
                if action in ['start', 'stop', 'restart']:
                    if os.path.exists(init_script):
                        cmd = [init_script, action]
                    else:
                        self.log_message(f"Init script not found: {init_script}", "error")
                        return
                elif action == 'enable':
                    cmd = ['rc-update', 'add', self.service_name, 'default']
                elif action == 'disable':
                    cmd = ['rc-update', 'del', self.service_name]
                
                returncode, stdout, stderr = self.run_command(cmd, use_sudo=True, require_password=True)
            
            if returncode == 0:
                self.log_message(f"Successfully {action}ed {self.service_name} service", "success")
                
                # Update status after a short delay
                QTimer.singleShot(1000, self.check_bluetooth_service)
                
            else:
                error_msg = stderr if stderr else stdout
                self.log_message(f"Failed to {action} service: {error_msg}", "error")
                
                # Show detailed error dialog
                QMessageBox.critical(self, f"Failed to {action} service", 
                                   f"Error: {error_msg}\n\nCommand: {' '.join(cmd)}")
                
        except Exception as e:
            self.log_message(f"Error managing service: {str(e)}", "error")
            
    def toggle_scan(self):
        """Start or stop scanning for devices"""
        if not self.service_running:
            self.log_message("Cannot scan: Bluetooth service is not running", "error")
            QMessageBox.warning(self, "Service Not Running", 
                              "Bluetooth service is not running. Please start the service first.")
            return
            
        if not self.scanning:
            self.start_scanning()
        else:
            self.stop_scanning()
            
    def start_scanning(self):
        """Start scanning for Bluetooth devices"""
        self.scanning = True
        self.scan_button.setText("🛑 Stop Scan")
        self.scan_button.setStyleSheet("""
            QPushButton {
                background-color: #f44336;
                color: white;
                padding: 10px;
                border-radius: 4px;
                font-weight: bold;
                font-size: 14px;
            }
            QPushButton:hover {
                background-color: #da190b;
            }
        """)
        
        # Enable discovery
        returncode, stdout, stderr = self.run_command(["bluetoothctl", "discoverable", "on"])
        if returncode == 0:
            self.log_message("Discovery enabled", "success")
        
        # Start scanning in background thread
        self.scan_thread = threading.Thread(target=self.scan_devices, daemon=True)
        self.scan_thread.start()
        
        self.log_message("Started scanning for devices...", "info")
        
    def stop_scanning(self):
        """Stop scanning for Bluetooth devices"""
        self.scanning = False
        self.scan_button.setText("🔍 Start Scan")
        self.scan_button.setStyleSheet("""
            QPushButton {
                background-color: #4CAF50;
                color: white;
                padding: 10px;
                border-radius: 4px;
                font-weight: bold;
                font-size: 14px;
            }
            QPushButton:hover {
                background-color: #45a049;
            }
        """)
        
        # Disable discovery
        returncode, stdout, stderr = self.run_command(["bluetoothctl", "discoverable", "off"])
        if returncode == 0:
            self.log_message("Discovery disabled", "success")
            
        self.log_message("Stopped scanning", "info")
        
    def scan_devices(self):
        """Scan for Bluetooth devices in background thread"""
        try:
            # First, power on the controller if not already
            self.run_command(["bluetoothctl", "power", "on"])
            
            while self.scanning:
                # Start scan
                returncode, stdout, stderr = self.run_command(["bluetoothctl", "scan", "on"])
                
                if returncode == 0:
                    # Get list of devices
                    returncode, stdout, stderr = self.run_command(["bluetoothctl", "devices"])
                    
                    if returncode == 0:
                        devices = []
                        for line in stdout.strip().split('\n'):
                            line = line.strip()
                            if line and not line.startswith('['):
                                parts = line.split(' ', 2)
                                if len(parts) >= 3:
                                    mac_address = parts[1]
                                    device_name = parts[2]
                                    devices.append((mac_address, device_name))
                        
                        # Update UI with devices
                        QMetaObject.invokeMethod(self, "update_device_list", 
                                               Qt.ConnectionType.QueuedConnection,
                                               Q_ARG(list, devices))
                
                time.sleep(2)  # Wait before next scan
                
        except Exception as e:
            QMetaObject.invokeMethod(self, "log_message", 
                                   Qt.ConnectionType.QueuedConnection,
                                   Q_ARG(str, f"Scan error: {str(e)}"),
                                   Q_ARG(str, "error"))
    
    @pyqtSlot(list)
    def update_device_list(self, devices):
        """Update the device list in the UI"""
        self.device_table.setRowCount(0)
        self.devices = {}
        
        for i, (mac_address, device_name) in enumerate(devices):
            self.device_table.insertRow(i)
            
            # Get detailed info for each device
            returncode, info_stdout, stderr = self.run_command(["bluetoothctl", "info", mac_address])
            
            paired = "no"
            trusted = "no"
            connected = "no"
            blocked = "no"
            alias = device_name  # Default to device name if no alias
            
            if returncode == 0:
                for line in info_stdout.split('\n'):
                    line_lower = line.lower()
                    if "paired:" in line_lower:
                        paired = "yes" if "yes" in line_lower else "no"
                    elif "trusted:" in line_lower:
                        trusted = "yes" if "yes" in line_lower else "no"
                    elif "connected:" in line_lower:
                        connected = "yes" if "yes" in line_lower else "no"
                    elif "blocked:" in line_lower:
                        blocked = "yes" if "yes" in line_lower else "no"
                    elif "alias:" in line:
                        # FIXED: Check if split produces at least 2 parts
                        parts = line.split("Alias:")
                        if len(parts) >= 2:
                            alias = parts[1].strip()
            
            # Store device info
            self.devices[mac_address] = {
                'name': device_name,
                'alias': alias,
                'paired': paired,
                'trusted': trusted,
                'connected': connected,
                'blocked': blocked
            }
            
            # Add items to table
            self.device_table.setItem(i, 0, QTableWidgetItem(mac_address))
            self.device_table.setItem(i, 1, QTableWidgetItem(device_name))
            self.device_table.setItem(i, 2, QTableWidgetItem(alias))
            
            # Color coded status indicators
            status_items = [
                (3, paired, "#4CAF50", "#f44336"),
                (4, trusted, "#4CAF50", "#f44336"),
                (5, connected, "#4CAF50", "#f44336"),
                (6, blocked, "#f44336", "#4CAF50")  # Blocked is reversed
            ]
            
            for col, value, yes_color, no_color in status_items:
                item = QTableWidgetItem(value)
                if value == "yes":
                    item.setForeground(QColor(yes_color))
                else:
                    item.setForeground(QColor(no_color))
                self.device_table.setItem(i, col, item)
        
        self.device_table.resizeColumnsToContents()
        
    def refresh_devices(self):
        """Refresh the list of paired devices"""
        if not self.service_running:
            self.log_message("Cannot refresh: Bluetooth service is not running", "error")
            return
            
        self.log_message("Refreshing device list...", "info")
        
        try:
            # FIXED: Use 'devices' command instead of 'paired-devices'
            # Then check each device to see if it's paired
            returncode, stdout, stderr = self.run_command(["bluetoothctl", "devices"])
            
            if returncode == 0:
                devices = []
                for line in stdout.strip().split('\n'):
                    line = line.strip()
                    if line and not line.startswith('['):
                        parts = line.split(' ', 2)
                        if len(parts) >= 3:
                            mac_address = parts[1]
                            device_name = parts[2]
                            
                            # Check if this device is paired by getting its info
                            paired_returncode, paired_stdout, paired_stderr = self.run_command(["bluetoothctl", "info", mac_address])
                            if paired_returncode == 0:
                                # Check if device is paired
                                for info_line in paired_stdout.split('\n'):
                                    if "Paired:" in info_line.lower() and "yes" in info_line.lower():
                                        devices.append((mac_address, device_name))
                                        break
                
                if devices:
                    self.update_device_list(devices)
                    self.log_message(f"Found {len(devices)} paired device(s)", "success")
                else:
                    self.log_message("No paired devices found", "info")
                    self.device_table.setRowCount(0)
                    self.devices = {}
            else:
                error_msg = stderr.strip() if stderr else stdout.strip()
                if not error_msg:
                    error_msg = "Unknown error occurred"
                # Clean ANSI escape codes from error message
                error_msg = re.sub(r'\x1b\[[0-9;]*[a-zA-Z]', '', error_msg)
                self.log_message(f"Error refreshing devices: {error_msg}", "error")
                
        except Exception as e:
            self.log_message(f"Exception while refreshing devices: {str(e)}", "error")
            
    def start_agent(self):
        """Start the Bluetooth agent"""
        returncode, stdout, stderr = self.run_command(["bluetoothctl", "agent", "on"])
        if returncode == 0:
            self.log_message("Bluetooth agent started", "success")
        else:
            error_msg = stderr if stderr else stdout
            self.log_message(f"Failed to start agent: {error_msg}", "error")
            
    def toggle_power(self):
        """Toggle Bluetooth power state"""
        # Get current power state
        returncode, stdout, stderr = self.run_command(["bluetoothctl", "show"])
        
        power_on = False
        if returncode == 0:
            for line in stdout.split('\n'):
                if "Powered:" in line and "yes" in line.lower():
                    power_on = True
                    break
        
        if power_on:
            returncode, stdout, stderr = self.run_command(["bluetoothctl", "power", "off"])
            if returncode == 0:
                self.log_message("Bluetooth powered off", "success")
                self.power_button.setText("🔌 Power On")
            else:
                error_msg = stderr if stderr else stdout
                self.log_message(f"Failed to power off: {error_msg}", "error")
        else:
            returncode, stdout, stderr = self.run_command(["bluetoothctl", "power", "on"])
            if returncode == 0:
                self.log_message("Bluetooth powered on", "success")
                self.power_button.setText("🔌 Power Off")
            else:
                error_msg = stderr if stderr else stdout
                self.log_message(f"Failed to power on: {error_msg}", "error")
            
    def on_device_selected(self):
        """Enable/disable action buttons based on selection"""
        selected_rows = self.device_table.selectionModel().selectedRows()
        has_selection = len(selected_rows) > 0
        
        if has_selection:
            mac_address = self.get_selected_device()
            device_info = self.devices.get(mac_address, {})
            
            self.pair_button.setEnabled(has_selection and device_info.get('paired') == 'no')
            self.trust_button.setEnabled(has_selection and device_info.get('trusted') == 'no')
            self.connect_button.setEnabled(has_selection and device_info.get('connected') == 'no' and device_info.get('paired') == 'yes')
            self.disconnect_button.setEnabled(has_selection and device_info.get('connected') == 'yes')
            self.remove_button.setEnabled(has_selection)
            self.block_button.setEnabled(has_selection and device_info.get('blocked') == 'no')
            self.info_button.setEnabled(has_selection)
        else:
            self.pair_button.setEnabled(False)
            self.trust_button.setEnabled(False)
            self.connect_button.setEnabled(False)
            self.disconnect_button.setEnabled(False)
            self.remove_button.setEnabled(False)
            self.block_button.setEnabled(False)
            self.info_button.setEnabled(False)
        
    def get_selected_device(self):
        """Get the MAC address of the selected device"""
        selected_items = self.device_table.selectedItems()
        if selected_items:
            row = selected_items[0].row()
            mac_address = self.device_table.item(row, 0).text()
            return mac_address
        return None
        
    def pair_device(self):
        """Pair with selected device"""
        mac_address = self.get_selected_device()
        if not mac_address:
            return
            
        self.log_message(f"Pairing with device {mac_address}...", "info")
        
        # Start agent if not already running
        self.start_agent()
        
        # Set agent to default
        self.run_command(["bluetoothctl", "default-agent"])
        
        # Pair device
        returncode, stdout, stderr = self.run_command(["bluetoothctl", "pair", mac_address])
        
        if returncode == 0:
            self.log_message(f"Successfully paired with {mac_address}", "success")
            self.refresh_devices()
        else:
            error_msg = stderr if stderr else stdout
            self.log_message(f"Pairing failed: {error_msg}", "error")
            
    def trust_device(self):
        """Trust selected device"""
        mac_address = self.get_selected_device()
        if not mac_address:
            return
            
        self.log_message(f"Setting device {mac_address} as trusted...", "info")
        
        returncode, stdout, stderr = self.run_command(["bluetoothctl", "trust", mac_address])
        
        if returncode == 0:
            self.log_message(f"Device {mac_address} is now trusted", "success")
            self.refresh_devices()
        else:
            error_msg = stderr if stderr else stdout
            self.log_message(f"Failed to trust device: {error_msg}", "error")
            
    def connect_device(self):
        """Connect to selected device"""
        mac_address = self.get_selected_device()
        if not mac_address:
            return
            
        device_info = self.devices.get(mac_address, {})
        
        # Check if device is paired
        if device_info.get('paired') != 'yes':
            reply = QMessageBox.question(self, 'Not Paired', 
                                       'Device is not paired. Would you like to pair it first?',
                                       QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
            if reply == QMessageBox.StandardButton.Yes:
                self.pair_device()
                # Wait a bit for pairing to complete
                time.sleep(2)
            else:
                return
        
        self.log_message(f"Connecting to device {mac_address}...", "info")
        
        returncode, stdout, stderr = self.run_command(["bluetoothctl", "connect", mac_address])
        
        if returncode == 0:
            self.log_message(f"Successfully connected to {mac_address}", "success")
            self.refresh_devices()
        else:
            error_msg = stderr if stderr else stdout
            self.log_message(f"Connection failed: {error_msg}", "error")
            
    def disconnect_device(self):
        """Disconnect from selected device"""
        mac_address = self.get_selected_device()
        if not mac_address:
            return
            
        self.log_message(f"Disconnecting from device {mac_address}...", "info")
        
        returncode, stdout, stderr = self.run_command(["bluetoothctl", "disconnect", mac_address])
        
        if returncode == 0:
            self.log_message(f"Successfully disconnected from {mac_address}", "success")
            self.refresh_devices()
        else:
            error_msg = stderr if stderr else stdout
            self.log_message(f"Disconnection failed: {error_msg}", "error")
            
    def remove_device(self):
        """Remove selected device"""
        mac_address = self.get_selected_device()
        if not mac_address:
            return
            
        reply = QMessageBox.question(self, 'Remove Device', 
                                   f'Are you sure you want to remove device {mac_address}?',
                                   QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
        
        if reply == QMessageBox.StandardButton.Yes:
            self.log_message(f"Removing device {mac_address}...", "info")
            
            # First disconnect if connected
            self.run_command(["bluetoothctl", "disconnect", mac_address])
            
            # Remove device
            returncode, stdout, stderr = self.run_command(["bluetoothctl", "remove", mac_address])
            
            if returncode == 0:
                self.log_message(f"Successfully removed device {mac_address}", "success")
                self.refresh_devices()
            else:
                error_msg = stderr if stderr else stdout
                self.log_message(f"Failed to remove device: {error_msg}", "error")
                
    def block_device(self):
        """Block selected device"""
        mac_address = self.get_selected_device()
        if not mac_address:
            return
            
        self.log_message(f"Blocking device {mac_address}...", "info")
        
        returncode, stdout, stderr = self.run_command(["bluetoothctl", "block", mac_address])
        
        if returncode == 0:
            self.log_message(f"Successfully blocked device {mac_address}", "success")
            self.refresh_devices()
        else:
            error_msg = stderr if stderr else stdout
            self.log_message(f"Failed to block device: {error_msg}", "error")
                
    def show_device_info(self):
        """Show detailed information about selected device"""
        mac_address = self.get_selected_device()
        if not mac_address:
            return
            
        self.log_message(f"Getting info for device {mac_address}...", "info")
        
        returncode, stdout, stderr = self.run_command(["bluetoothctl", "info", mac_address])
        
        if returncode == 0:
            # Create a dialog to show info
            dialog = QDialog(self)
            dialog.setWindowTitle(f"Device Info - {mac_address}")
            dialog.setMinimumWidth(600)
            dialog.setMinimumHeight(400)
            dialog.setStyleSheet("""
                QDialog {
                    background-color: #2C2C2C;
                }
                QTextEdit {
                    background-color: #1C1C1C;
                    color: #E0E0E0;
                    font-family: monospace;
                    border: 1px solid #444444;
                    border-radius: 3px;
                }
            """)
            
            layout = QVBoxLayout()
            
            text_edit = QTextEdit()
            text_edit.setPlainText(stdout)
            text_edit.setReadOnly(True)
            text_edit.setFont(QFont("Monospace", 10))
            
            button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
            button_box.rejected.connect(dialog.reject)
            button_box.setStyleSheet("""
                QPushButton {
                    background-color: #444444;
                    color: white;
                    padding: 6px;
                    border-radius: 4px;
                }
                QPushButton:hover {
                    background-color: #555555;
                }
            """)
            
            layout.addWidget(text_edit)
            layout.addWidget(button_box)
            
            dialog.setLayout(layout)
            dialog.exec()
        else:
            error_msg = stderr if stderr else stdout
            self.log_message(f"Failed to get device info: {error_msg}", "error")
            
    def update_status(self):
        """Periodic status update"""
        if self.service_running:
            self.check_bluetooth_service()
            if not self.scanning:
                self.refresh_devices()
                
    def export_log(self):
        """Export log to file"""
        file_name, _ = QFileDialog.getSaveFileName(
            self, "Export Log", "bluetooth_manager_log.txt", "Text Files (*.txt);;All Files (*)"
        )
        
        if file_name:
            try:
                with open(file_name, 'w') as f:
                    f.write(self.log_text.toPlainText())
                self.log_message(f"Log exported to {file_name}", "success")
            except Exception as e:
                self.log_message(f"Failed to export log: {str(e)}", "error")


def main():
    app = QApplication(sys.argv)
    app.setStyle("Fusion")
    
    # Apply dark theme with no black text
    palette = QPalette()
    palette.setColor(QPalette.ColorRole.Window, QColor(45, 45, 45))
    palette.setColor(QPalette.ColorRole.WindowText, QColor(224, 224, 224))
    palette.setColor(QPalette.ColorRole.Base, QColor(30, 30, 30))
    palette.setColor(QPalette.ColorRole.AlternateBase, QColor(53, 53, 53))
    palette.setColor(QPalette.ColorRole.ToolTipBase, QColor(60, 60, 60))
    palette.setColor(QPalette.ColorRole.ToolTipText, QColor(224, 224, 224))
    palette.setColor(QPalette.ColorRole.Text, QColor(224, 224, 224))
    palette.setColor(QPalette.ColorRole.Button, QColor(53, 53, 53))
    palette.setColor(QPalette.ColorRole.ButtonText, QColor(224, 224, 224))
    palette.setColor(QPalette.ColorRole.BrightText, QColor(255, 255, 255))
    palette.setColor(QPalette.ColorRole.Link, QColor(42, 130, 218))
    palette.setColor(QPalette.ColorRole.Highlight, QColor(42, 130, 218))
    palette.setColor(QPalette.ColorRole.HighlightedText, QColor(255, 255, 255))
    palette.setColor(QPalette.ColorRole.PlaceholderText, QColor(127, 127, 127))
    
    app.setPalette(palette)
    
    # Set style sheet for better visual appearance
    app.setStyleSheet("""
        QMainWindow, QDialog {
            background-color: #2D2D2D;
        }
        QGroupBox {
            font-weight: bold;
            border: 2px solid #444444;
            border-radius: 5px;
            margin-top: 10px;
            padding-top: 10px;
            background-color: #353535;
        }
        QGroupBox::title {
            subcontrol-origin: margin;
            left: 10px;
            padding: 0 5px 0 5px;
            color: #E0E0E0;
        }
        QLabel {
            color: #E0E0E0;
        }
        QLineEdit {
            background-color: #3C3C3C;
            color: #E0E0E0;
            border: 1px solid #555555;
            border-radius: 3px;
            padding: 5px;
        }
        QCheckBox {
            color: #E0E0E0;
        }
        QCheckBox::indicator {
            width: 13px;
            height: 13px;
        }
        QMessageBox {
            background-color: #2D2D2D;
        }
        QMessageBox QLabel {
            color: #E0E0E0;
        }
    """)
    
    window = BluetoothManager()
    window.show()
    
    sys.exit(app.exec())


if __name__ == "__main__":
    main()
