from PyQt6.QtWidgets import QComboBox,QButtonGroup, QLineEdit,QMainWindow, QLabel, QWidget, QVBoxLayout, QStackedWidget, QApplication, QPushButton, QTextEdit, QFrame, QHBoxLayout, QVBoxLayout, QScrollArea, QSystemTrayIcon, QMessageBox, QGridLayout, QCheckBox, QStackedLayout, QGroupBox, QDialog
from PyQt6.QtGui import QIcon, QPixmap,QIcon, QPixmap, QTransform, QPainter, QColor, QFont, QFontDatabase, QTextOption
from PyQt6 import QtGui
from PyQt6 import QtCore
from PyQt6.QtCore import Qt,QSize,QThread,pyqtSignal, QTimer, QPointF, QRect, QMutex, QMutexLocker, QObject
import os
import sys
import functools
import threading
import logging
import traceback
import random
import subprocess
import qrcode
from io import BytesIO
from typing import Union
from core.Errors import UnknownConnectionTypeError, CommandNotFoundError, MissingSubscriptionError, InvalidSubscriptionError, ProfileActivationError, UnsupportedApplicationVersionError, FileIntegrityError, ProfileModificationError, ProfileStateConflictError, EndpointVerificationError
from core.controllers.ApplicationVersionController import ApplicationVersionController
from core.controllers.ApplicationController import ApplicationController
from core.controllers.ClientController import ClientController
from core.controllers.ConfigurationController import ConfigurationController
from core.controllers.InvoiceController import InvoiceController
from core.controllers.LocationController import LocationController
from core.controllers.ProfileController import ProfileController
from core.controllers.SubscriptionController import SubscriptionController
from core.controllers.SubscriptionPlanController import SubscriptionPlanController
from core.models.session.SessionConnection import SessionConnection
from core.models.session.SessionProfile import SessionProfile
from core.models.system.SystemConnection import SystemConnection
from core.models.system.SystemProfile import SystemProfile
from core.observers.ApplicationVersionObserver import ApplicationVersionObserver
from core.observers.ClientObserver import ClientObserver
from core.observers.ConnectionObserver import ConnectionObserver
from core.observers.InvoiceObserver import InvoiceObserver
from core.observers.ProfileObserver import ProfileObserver
from datetime import datetime, timezone, timedelta
from core.Constants import Constants
import atexit
import json
import shlex



application_version_observer = ApplicationVersionObserver()
client_observer = ClientObserver()
connection_observer = ConnectionObserver()
invoice_observer = InvoiceObserver()
profile_observer = ProfileObserver()
 

class WorkerThread(QThread):
    text_output = pyqtSignal(str)
    sync_output = pyqtSignal(list, list, bool, bool, list, list)
    invoice_output = pyqtSignal(object, str)
    invoice_finished = pyqtSignal(bool)
    profiles_output = pyqtSignal(dict)
    special_output = pyqtSignal(str)
    finished = pyqtSignal(bool)
    update_finished = pyqtSignal(dict)

    def __init__(self, action=None, profile_data=None, profile_type=None, package_name=None, package_command=None):
        super().__init__()
        self.action = action
        self.profile_data = profile_data
        self.profile_type = profile_type
        self.package_name = package_name
        self.package_command = package_command
        self.is_running = True
        self.is_disabling = False


    def run(self):
        if self.action == 'LIST_PROFILES':
            self.list_profiles()
        elif self.action == 'CREATE_SESSION_PROFILE':
            self.create_profile(self.profile_type)
        elif self.action == 'CREATE_SYSTEM_PROFILE':
            self.create_profile(self.profile_type)
        elif self.action == 'GET_SUBSCRIPTION':
            self.get_subscription()
        elif self.action == 'DISABLE_PROFILE':
            self.disable_profile()
        elif self.action == 'SYNC' or self.action == 'SYNC_TOR':
            self.sync()
        elif self.action == 'DESTROY_PROFILE':
            self.destroy_profile()
        elif self.action == 'DISABLE_ALL_PROFILES':
            self.disable_all_profiles()
        elif self.action == 'INSTALL_PACKAGE':
            self.install_package()
        elif self.action == 'CHECK_FOR_UPDATE':
            self.check_for_update()
        elif self.action == 'DOWNLOAD_UPDATE':
            self.download_update()
        elif self.action == 'CHECK_INVOICE_STATUS':
            self.check_invoice_status()

    def check_invoice_status(self):
        try:
            invoice = InvoiceController.get(self.profile_data['billing_code'])
            if invoice:
                status = invoice.status
                if status == "expired":
                    self.invoice_finished.emit(False)
                else:
                    self.invoice_finished.emit(True)
            else:
                self.invoice_finished.emit(False)
        except Exception as e:
            print(f"Error retrieving invoice: {str(e)}")
            self.invoice_finished.emit(False)


    def download_update(self):
        self.text_output.emit("Starting update process...")
        ClientController.update(client_observer=client_observer)
        client_observer.subscribe('update_progressing', lambda event: self.text_output.emit(f"Downloading: {event.meta.get('progress'):.1f}%"))
        client_observer.subscribe('updated', lambda event: self.text_output.emit("Update process completed"))
        

    def check_for_update(self):
        self.text_output.emit("Checking for updates...")
        ClientController.sync(client_observer=client_observer, connection_observer=connection_observer)
        update_available = ClientController.can_be_updated()
        if update_available:
            self.text_output.emit("An update is available. Downloading...")
            self.finished.emit(True)
        else:
            self.text_output.emit("No updates available.")
            self.finished.emit(False)
        

    def install_package(self):
        try:
            self.text_output.emit(f"Installing {self.package_name}...")
            subprocess.run(shlex.split(self.package_command), check=True)
            self.text_output.emit(f"{self.package_name} installed!")
            self.finished.emit(True)
        except subprocess.CalledProcessError:
            self.text_output.emit("Installation failed")
            self.finished.emit(False)
        except Exception as e:
            self.text_output.emit(f"An error occurred when installing {self.package_name}: {e}")
            self.finished.emit(False)

    def disable_all_profiles(self):
        try:
            for profile_id in self.profile_data:
                profile = ProfileController.get(int(profile_id))
                if isinstance(profile, SessionProfile):
                    ProfileController.disable(profile, ignore=True, profile_observer=profile_observer)
            for profile_id in self.profile_data:
                profile = ProfileController.get(int(profile_id))
                if isinstance(profile, SystemProfile):
                    ProfileController.disable(profile, ignore=True, profile_observer=profile_observer)
            self.text_output.emit("All profiles were successfully disabled")
        except Exception:
            self.text_output.emit("An error occurred when disabling profile")
        finally:
            self.finished.emit(True)

    def destroy_profile(self):
        profile_id = int(self.profile_data['id'])
        profile = ProfileController.get(profile_id)
        
        if profile is not None:
            ProfileController.destroy(profile)
            self.text_output.emit(f'Profile {profile_id} deleted')
        else:
            self.text_output.emit(f'Profile {profile_id} does not exist')


        

    def list_profiles(self):
        profiles = ProfileController.get_all()
        self.profiles_output.emit(profiles)

    def create_profile(self, profile_type):
        location = LocationController.get(self.profile_data['country_code'], self.profile_data['code'])
        if location is None:
            self.text_output.emit(f"Invalid location code: {self.profile_data['location_code']}")
            return

        profile_id = int(self.profile_data['id']) if self.profile_data['id'] else None
        name = self.profile_data['name']
        connection_type = self.profile_data['connection_type']

        if profile_type == "session":

            application_details = self.profile_data['application'].split(':', 1)
            application_version = ApplicationVersionController.get(application_details[0], application_details[1] if len(application_details) > 1 else None)
            if application_version is None:
                self.text_output.emit(f"Invalid application: {self.profile_data['application']}")
                return

            mask_connection = True if connection_type == 'tor' or connection_type == 'system' else False
            resolution = self.profile_data['resolution']
            connection = SessionConnection(connection_type, mask_connection)
            profile = SessionProfile(profile_id, name, None, location, resolution, application_version, connection)
        elif profile_type == "system":
            connection = SystemConnection(connection_type)
            profile = SystemProfile(profile_id, name, None, location, connection)

        else:
            self.text_output.emit(f"Invalid profile type: {profile_type}")
            return
        try:
            ProfileController.create(profile, profile_observer=profile_observer)
        except Exception as e:
            self.text_output.emit(f"An error occurred when creating profile {profile.id}")

        self.text_output.emit(f"{profile_type.capitalize()} Profile created with ID: {profile.id}")

    def disable_profile(self):
        try:
            profile = ProfileController.get(int(self.profile_data['id']))
            if profile:
                ProfileController.disable(profile, profile_observer=profile_observer)
            else:
                self.text_output.emit(f"No profile found with ID: {self.profile_data['id']}")
        except Exception as e:
            self.text_output.emit("An error occurred when disabling profile")
        finally:
            self.finished.emit(True)

    def sync(self):
        try:
            ConfigurationController.set_endpoint_verification_enabled(True)
            if self.action == 'SYNC_TOR':
                ConfigurationController.set_connection('tor')
            else:
                ConfigurationController.set_connection('system')
            self.check_for_update()
            locations = LocationController.get_all()
            browser = ApplicationVersionController.get_all()
            all_browser_versions = [f"{browser.application_code}:{browser.version_number}" for browser in browser if browser.supported]
            all_location_codes = [f"{location.country_code}_{location.code}" for location in locations]
            self.sync_output.emit(all_location_codes, all_browser_versions, True, False, locations, browser)
        except Exception as e:
            print(f'the error is: {e}')
            self.sync_output.emit([], [], False, False, [], [])

        

    def get_connection(self):
        connection = ConfigurationController.get_connection()
        self.text_output.emit(f"Current connection: {connection}")

    def set_connection(self):
        ConfigurationController.set_connection(self.profile_data['connection_type'])
        self.text_output.emit(f"Connection set to '{self.profile_data['connection_type']}'")

    def get_subscription(self):
        try:
            invoice_observer.subscribe('retrieved', lambda event: self.handle_event(event, self.profile_data['currency']))
            invoice_observer.subscribe('processing', lambda event: self.text_output.emit('A payment has been detected and is being verified...'))
            invoice_observer.subscribe('settled', lambda event:  self.text_output.emit('The payment has been successfully verified.'))

            profile = ProfileController.get(int(self.profile_data['id']))
            subscription_plan = SubscriptionPlanController.get(profile.connection, self.profile_data['duration'])
            if subscription_plan is None:
                self.text_output.emit('No compatible subscription plan was found.')
                return
            potential_subscription = SubscriptionController.create(subscription_plan, profile, connection_observer=connection_observer)
            if potential_subscription is not None:
                ProfileController.attach_subscription(profile, potential_subscription)
            else:
                self.text_output.emit('The subscription could not be created. Try again later.')
                return
            

            subscription = InvoiceController.handle_payment(potential_subscription.billing_code, invoice_observer=invoice_observer, connection_observer=connection_observer)
            if subscription is not None:
                ProfileController.attach_subscription(profile, subscription)
                self.text_output.emit('Successfully activated the subscription')
                self.invoice_finished.emit(True)
            else:
                self.text_output.emit('The subscription could not be activated. Try again later.')
                self.invoice_finished.emit(False)

        except Exception as e:
            self.text_output.emit('An unknown error occurred')
            self.invoice_finished.emit(False)


    def handle_connection_events(self, event):
        self.text_output.emit(f'Profile disabled')

    def handle_event(self, event, currency=None):
        invoice = event.subject  
        if isinstance(invoice, object):
            self.invoice_output.emit(invoice, '')
            self.text_output.emit("Invoice generated. Awaiting payment...")
        else:
            self.text_output.emit("Invalid invoice data received.")


class CustomWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        sys.excepthook = self._handle_exception
        self.setWindowFlags(
            Qt.WindowType.Window
        )

        current_dir = os.path.dirname(os.path.abspath(__file__))
        font_path = os.path.join(current_dir, 'resources', 'fonts')

        retro_gaming_path = os.path.join(font_path, 'retro-gaming.ttf')
        font_id = QFontDatabase.addApplicationFont(retro_gaming_path)
        font_family = QFontDatabase.applicationFontFamilies(font_id)[0]
        app_font = QFont(font_family)
        app_font.setPointSize(10)
        QApplication.setFont(app_font)
        
        self.open_sans_family = None
        open_sans_path = os.path.join(font_path, 'open-sans.ttf')
        if os.path.exists(open_sans_path):
            open_sans_id = QFontDatabase.addApplicationFont(open_sans_path)
            if open_sans_id != -1:
                self.open_sans_family = QFontDatabase.applicationFontFamilies(open_sans_id)[0]
        
        self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
        self.setAttribute(Qt.WidgetAttribute.WA_NoSystemBackground)
        self.setWindowTitle('HydraVeil')
        self._data = {"Profile_1": {}}

        self.gui_config_home = os.path.join(Constants.HV_CONFIG_HOME, 'gui')
        self.gui_config_file = os.path.join(self.gui_config_home, 'config.json')

        self.gui_cache_home = os.path.join(Constants.HV_CACHE_HOME, 'gui')
        self.gui_log_file = os.path.join(self.gui_cache_home, 'gui.log')

        self._setup_gui_directory()

        current_dir = os.path.dirname(os.path.abspath(__file__))

        self.btn_path = os.getenv('BTN_PATH', os.path.join(current_dir, 'resources', 'images'))
        self.css_path = os.getenv('CSS_PATH', os.path.join(current_dir, 'resources', 'styles'))

        self.tray = None
        self.init_system_tray(self.btn_path)

        self.is_downloading = False
        self.current_profile_id = None
        self.connection_manager = ConnectionManager()

        current_connection = None
        self.is_tor_mode = current_connection == 'tor'

        self.is_animating = False
        self.animation_step = 0
        self.page_history = []
        self.log_path = None
        
        
        profile_observer.subscribe('created', lambda event: self.update_status('Profile Created'))
        profile_observer.subscribe('destroyed', lambda event: self.update_status('Profile destroyed'))

        client_observer.subscribe('synchronizing', lambda event: self.update_status('Sync in progress...'))
        client_observer.subscribe('synchronized', lambda event: self.update_status('Sync complete'))

        client_observer.subscribe('updating', lambda event: self.update_status('Updating client...'))
        client_observer.subscribe('update_progressing', lambda event: self.update_status(f'Current progress: {event.meta.get('progress'):.2f}%'))
        client_observer.subscribe('updated', lambda event: self.update_status('Restart client to apply update.'))

        application_version_observer.subscribe('downloading', lambda event: self.update_status(f'Downloading {ApplicationController.get(event.subject.application_code).name}'))
        application_version_observer.subscribe('download_progressing', lambda event: self.update_status(f'Downloading {ApplicationController.get(event.subject.application_code).name} {event.meta.get('progress'):.2f}%'))
        application_version_observer.subscribe('downloaded', lambda event: self.update_status(f'Downloaded {ApplicationController.get(event.subject.application_code).name}'))
        
        connection_observer.subscribe('connecting', lambda event: self.update_status(f'[{event.subject.get("attempt_count")}/{event.subject.get("maximum_number_of_attempts")}] Performing connection attempt...'))
        
        self.setFixedSize(800, 570)
        self.central_widget = QWidget(self)
        self.central_widget.setMaximumSize(800, 600)
        self.central_widget.setGeometry(0, 0, 850, 600)
        self.central_widget.setObjectName("centralwidget")

        # Creamos el QLabel para mostrar la imagen
        self.label = QLabel(self.central_widget)
        self.label.setGeometry(0, 0, 800, 570)
        css_file = os.path.join(self.css_path, 'look.css')
        self.setStyleSheet(open(css_file).read() if os.path.exists(css_file) else '') # Opcional: si deseas cargar estilos CSS desde un archivo


        self.status_label = QLabel(self)
        self.status_label.setGeometry(15, 518, 780, 20)
        self.status_label.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)
        self.status_label.setStyleSheet("color: rgb(0, 255, 255); font-size: 16px;")
        self.status_label.setText(f"Status: Client version {Constants.HV_CLIENT_VERSION_NUMBER}")

        self.text_start_x = 15  
        self.text_end_x = 420   
        self.text_width = self.text_end_x - self.text_start_x

        self.marquee_text = ""
        self.marquee_position = 0
        self.marquee_timer = QTimer(self)
        self.marquee_timer.timeout.connect(self.update_marquee)
        self.marquee_enabled = False
        self.scroll_speed = 1  

        self.tor_text = QLabel("Billing & Browsers", self)
        self.tor_text.setGeometry(532, 541, 150, 20)
        self.tor_text.setStyleSheet("""
        QLabel {
            color: cyan;
            font-size: 11px;
            font-weight: bold;
        }
        """)
        self.update_image()
        

        self.set_scroll_speed(7)
        
        self.toggle_button = QPushButton(self)
        self.toggle_button.setGeometry(670, 541, 50, 22)
        self.toggle_button.setCheckable(True)
        self.toggle_button.clicked.connect(self.toggle_mode)

        self.tor_icon = QLabel(self)
        self.tor_icon.setGeometry(730, 537, 25, 25)
        self.set_tor_icon()

        self.create_toggle(self.is_tor_mode)
        self.animation_timer = QTimer()
        self.animation_timer.timeout.connect(self.animate_toggle)
        self.check_logging()

        self.sync_button = QPushButton(self)
        self.sync_button.setGeometry(771, 541, 22, 22)
        self.sync_button.setObjectName('sync_button')

        if CustomWindow.should_be_synchronized():
            sync_icon = QtGui.QIcon(os.path.join(self.btn_path, 'icon_sync_urgent.png'))
        else:
            sync_icon = QtGui.QIcon(os.path.join(self.btn_path, 'icon_sync.png'))

        self.sync_button.setToolTip('Sync')
        self.sync_button.setIcon(sync_icon)
        self.sync_button.setIconSize(self.sync_button.size())
        self.sync_button.clicked.connect(self.sync)

        self.init_ui()

        current_connection = self.get_current_connection()
        self.is_tor_mode = current_connection == 'tor'
        self.set_toggle_state(self.is_tor_mode)

    def perform_update_check(self):

        update_available = ClientController.can_be_updated()

        if update_available:
            menu_page = self.page_stack.findChild(MenuPage)
            menu_page.on_update_check_finished()

    def update_values(self, available_locations, available_browsers, status, is_tor, locations, all_browsers):
        sync_screen = self.page_stack.findChild(SyncScreen)
        if status:
            sync_screen.update_after_sync(available_locations, available_browsers, locations, all_browsers)
            menu_page = self.page_stack.findChild(MenuPage)
            if menu_page and hasattr(menu_page, 'buttons'):
                for button in menu_page.buttons:
                    parent = button.parent()
                    if parent:
                        verification_icons = parent.findChildren(QPushButton)
                        for icon in verification_icons:
                            if icon.geometry().width() == 20 and icon.geometry().height() == 20:
                                icon.setEnabled(True)
        else:
            self.update_status('Sync failed. Please try again later.')

    
    
    def sync(self):
        if ConfigurationController.get_connection() == 'tor':
            self.worker_thread = WorkerThread('SYNC_TOR')
        else:
            self.worker_thread = WorkerThread('SYNC')
        self.sync_button.setIcon(QtGui.QIcon(os.path.join(self.btn_path, 'icon_sync.png')))
        self.worker_thread.finished.connect(lambda: self.perform_update_check())
        self.worker_thread.sync_output.connect(self.update_values)
        self.worker_thread.start()


    def _handle_exception(self, identifier, message, trace):
        if issubclass(identifier, UnknownConnectionTypeError):
            self.setup_popup()
            os.execv(sys.executable, [sys.executable] + sys.argv)

        else:

            config = self._load_gui_config()

            if config and config["logging"]["gui_logging_enabled"] == True:

                logging.error(
                    f"Uncaught exception:\n"
                    f"Type: {identifier.__name__}\n"
                    f"Value: {str(message)}\n"
                    f"Traceback:\n{''.join(traceback.format_tb(trace))}"
                )

            sys.__excepthook__(identifier, message, trace)

    def get_current_connection(self):
            return ConfigurationController.get_connection()

    
    def setup_popup(self):
        connection_dialog = QDialog(self)
        connection_dialog.setWindowTitle("Connection Type")
        connection_dialog.setWindowFlags(Qt.WindowType.Dialog | Qt.WindowType.WindowStaysOnTopHint | Qt.WindowType.CustomizeWindowHint | Qt.WindowType.WindowTitleHint)
        connection_dialog.setModal(True)
        connection_dialog.setFixedSize(400, 200)
        
        layout = QVBoxLayout(connection_dialog)
        
        label = QLabel("Please set your preference for connecting to Simplified Privacy's billing server.")
        label.setWordWrap(True)
        label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        label.setStyleSheet("font-size: 12px; margin-bottom: 20px; color: black;")
        
        button_layout = QHBoxLayout()
        
        regular_btn = QPushButton("Regular")
        tor_btn = QPushButton("Tor")
        
        button_style = """
            QPushButton {
                background-color: #2b2b2b;
                color: white;
                border: none;
                padding: 10px 20px;
                border-radius: 5px;
                font-size: 12px;
            }
            QPushButton:hover {
                background-color: #3b3b3b;
            }
            QPushButton:pressed {
                background-color: #1b1b1b;
            }
        """
        regular_btn.setStyleSheet(button_style)
        tor_btn.setStyleSheet(button_style)
        
        button_layout.addWidget(regular_btn)
        button_layout.addWidget(tor_btn)
        
        layout.addWidget(label)
        layout.addLayout(button_layout)
        
        def set_regular_connection():
            ConfigurationController.set_connection('system')
            self.is_tor_mode = False
            self.set_toggle_state(False)
            connection_dialog.accept()
        
        def set_tor_connection():
            ConfigurationController.set_connection('tor')
            self.is_tor_mode = True
            self.set_toggle_state(True)
            connection_dialog.accept()
        
        regular_btn.clicked.connect(set_regular_connection)
        tor_btn.clicked.connect(set_tor_connection)
        
        connection_dialog.exec()
        
        return ConfigurationController.get_connection()
    
    def _setup_gui_directory(self):
        os.makedirs(self.gui_cache_home, exist_ok=True)
        os.makedirs(self.gui_config_home, exist_ok=True)
        
        if not os.path.exists(self.gui_config_file):
            default_config = {
                "logging": {
                    "gui_logging_enabled": False,
                    "log_level": "INFO"
                }
            }
            with open(self.gui_config_file, 'w') as f:
                json.dump(default_config, f, indent=4)

    def _load_gui_config(self):
        try:
            with open(self.gui_config_file, 'r') as f:
                return json.load(f)
        except FileNotFoundError:
            return None
        except json.JSONDecodeError:
            logging.error("Invalid GUI config file format")
            return None

    def _save_gui_config(self, config):
        with open(self.gui_config_file, 'w') as f:
            json.dump(config, f, indent=4)

    def check_logging(self):
        config = self._load_gui_config()
        if config is None:
            return

        if config["logging"]["gui_logging_enabled"]:
            self._setup_gui_logging()



    def stop_gui_logging(self):
        if os.path.exists(self.gui_log_file):
            os.remove(self.gui_log_file)
        
        config = self._load_gui_config()
        if config:
            config["logging"]["gui_logging_enabled"] = False
            self._save_gui_config(config)
        

    def _setup_gui_logging(self):
        os.makedirs(self.gui_cache_home, exist_ok=True)
        
        formatter = logging.Formatter(
            '%(asctime)s - %(levelname)s - %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S'
        )
        
        file_handler = logging.FileHandler(self.gui_log_file)
        file_handler.setLevel(logging.INFO)
        file_handler.setFormatter(formatter)
        
        logger = logging.getLogger()
        logger.setLevel(logging.INFO)
        logger.handlers = []  
        logger.addHandler(file_handler)
        
        
        if not os.path.exists(self.gui_log_file) or os.path.getsize(self.gui_log_file) == 0:
            logging.info("GUI logging system initialized")


    def set_tor_icon(self):
        if self.is_tor_mode:
            icon_path = os.path.join(self.btn_path, "toricon_mini.png")
             
        else:
            icon_path = os.path.join(self.btn_path, "toricon_mini_false.png")
        pixmap = QPixmap(icon_path)
        self.tor_icon.setPixmap(pixmap)
        self.tor_icon.setScaledContents(True) 
    def create_toggle(self, is_tor_mode):
        handle_x = 30 if is_tor_mode else 3
        colors = self._get_toggle_colors(is_tor_mode)
        
        if not hasattr(self, 'animation_timer'):
            self.animation_timer = QTimer()
            self.animation_timer.timeout.connect(self.animate_toggle)
        
        self.toggle_bg = QLabel(self.toggle_button)
        self.toggle_bg.setGeometry(0, 0, 50, 22)
        
        # Create handle
        self.toggle_handle = QLabel(self.toggle_button)
        self.toggle_handle.setGeometry(handle_x, 3, 16, 16)
        self.toggle_handle.setStyleSheet("""
            QLabel {
                background-color: white;
                border-radius: 8px;
            }
        """)
        
        self.on_label = QLabel("ON", self.toggle_button)
        self.on_label.setGeometry(8, 4, 15, 14)
        
        self.off_label = QLabel("OFF", self.toggle_button)
        self.off_label.setGeometry(25, 4, 40, 14)
        
        self._update_toggle_colors(colors)
        if is_tor_mode:
            self.set_tor_icon()

    def _get_toggle_colors(self, is_tor_mode):
        return {
            'bg': "#00a8ff" if is_tor_mode else "#2c3e50",
            'tor': "white" if is_tor_mode else "transparent",
            'sys': "transparent" if is_tor_mode else "white"
        }

    def _update_toggle_colors(self, colors):
        self.toggle_bg.setStyleSheet(f"""
            QLabel {{
                background-color: {colors['bg']};
                border-radius: 11px;
            }}
        """)
        
        self.on_label.setStyleSheet(f"""
            QLabel {{
                color: {colors['tor']};
                font-size: 9px;
                font-weight: bold;
            }}
        """)
        
        self.off_label.setStyleSheet(f"""
            QLabel {{
                color: {colors['sys']};
                font-size: 9px;
                font-weight: bold;
            }}
        """)

    def set_toggle_state(self, is_tor_mode):
        self.is_tor_mode = is_tor_mode
        handle_x = 30 if is_tor_mode else 3
        self.toggle_handle.setGeometry(handle_x, 3, 16, 16)
        self._update_toggle_colors(self._get_toggle_colors(is_tor_mode))
        self.set_tor_icon()

    def toggle_mode(self):
        if not self.is_animating:
            self.is_animating = True
            self.animation_step = 0
            self.animation_timer.start(16)
            self.is_tor_mode = not self.is_tor_mode
            ConfigurationController.set_connection('tor' if self.is_tor_mode else 'system')

    def animate_toggle(self):
        TOTAL_STEPS = 5
        if self.animation_step <= TOTAL_STEPS:
            progress = self.animation_step / TOTAL_STEPS
            
            if self.is_tor_mode:
                new_x = 20 + (10 * progress)
                start_color = "#2c3e50"
                end_color = "#00a8ff"
            else:
                new_x = 31 - (28 * progress)
                start_color = "#00a8ff"
                end_color = "#2c3e50"
            
            self.toggle_handle.setGeometry(int(new_x), 3, 16, 16)
            
            bg_color = self.interpolate_color(start_color, end_color, progress)
            self.toggle_bg.setStyleSheet(f"""
                QLabel {{
                    background-color: {bg_color};
                    border-radius: 11px;
                }}
            """)
            
            self.off_label.setStyleSheet(f"""
                QLabel {{
                    color: rgba(255, 255, 255, {1 - progress if self.is_tor_mode else progress});
                    font-size: 9px;
                    font-weight: bold;
                }}
            """)
            self.on_label.setStyleSheet(f"""
                QLabel {{
                    color: rgba(255, 255, 255, {progress if self.is_tor_mode else 1 - progress});
                    font-size: 9px;
                    font-weight: bold;
                }}
            """)
            
            self.animation_step += 1
        else:
            self.animation_timer.stop()
            self.is_animating = False
            self.set_tor_icon()

    def interpolate_color(self, start_color, end_color, progress):
        def hex_to_rgb(hex_color):
            hex_color = hex_color.lstrip('#')
            return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
        
        start_rgb = hex_to_rgb(start_color)
        end_rgb = hex_to_rgb(end_color)
        
        current_rgb = tuple(
            int(start_rgb[i] + (end_rgb[i] - start_rgb[i]) * progress)
            for i in range(3)
        )
        
        return f"rgb{current_rgb}"

    
        

    def init_system_tray(self, icon_base_path):
        if QSystemTrayIcon.isSystemTrayAvailable():
            tray_icon = QIcon()
            window_icon = QIcon()
            
            tray_sizes = [22, 24]
            for size in tray_sizes:
                icon_path = os.path.join(icon_base_path, f"hv-icon-{size}x{size}.png")
                if os.path.exists(icon_path):
                    tray_icon.addFile(icon_path, QSize(size, size))
            
            window_sizes = [32, 48, 64, 128]
            for size in window_sizes:
                icon_path = os.path.join(icon_base_path, f"hv-icon-{size}x{size}.png")
                if os.path.exists(icon_path):
                    window_icon.addFile(icon_path, QSize(size, size))

            self.tray = QSystemTrayIcon(self)
            self.tray.setToolTip('HydraVeil')
            self.tray.setIcon(tray_icon)
            self.tray.setVisible(True)
            self.setWindowIcon(window_icon)

    def closeEvent(self, event=None):
        connected_profiles = self.connection_manager.get_connected_profiles()
        if connected_profiles:
            self._show_disconnect_confirmation(connected_profiles, event)
        else:
            pass

    def _show_disconnect_confirmation(self, connected_profiles, event=None, button_text='Exit', message=None):
        if event is not None:
            event.ignore()
            message = self._create_disconnect_message(connected_profiles)
        
        self.popup = self._create_confirmation_popup(message, button_text)
        self.popup.finished.connect(lambda result: self._handle_popup_result(result, connected_profiles, event))
        self.popup.show()

    def _create_disconnect_message(self, connected_profiles):
        profile_numbers = ', '.join(str(profile_id) for profile_id in connected_profiles)
        is_are = "is" if len(connected_profiles) == 1 else "are"
        return f'Profile{"" if len(connected_profiles) == 1 else "s"} {profile_numbers} {is_are} still connected.\nAll connected profiles will be disconnected on exit. \nDo you want to proceed?'

    def _create_confirmation_popup(self, message, button_text):
        popup = ConfirmationPopup(self, message=message, action_button_text=button_text, cancel_button_text="Cancel")
        popup.setWindowModality(Qt.WindowModality.ApplicationModal)
        return popup

    def _handle_popup_result(self, result, connected_profiles, event):
        if result:
            if event is None:
                self._disable_profiles(connected_profiles, exit=False)
                return
            self._disable_profiles(connected_profiles)
        else:
            event.ignore()

    def _disable_profiles(self, connected_profiles, exit=True):
        self.update_status('Disabling profiles...')
        self.worker_thread = WorkerThread('DISABLE_ALL_PROFILES', profile_data=connected_profiles)
        self.worker_thread.text_output.connect(lambda text: self._on_disable_status(text, exit))
        self.worker_thread.start()

    def _on_disable_status(self, text, exit):
        if exit:
            self.update_status('All profiles diabled. Bye!')
            QApplication.instance().quit()
        else:
            self.update_status(text)
            self.update_image()

    def _perform_cleanup_and_close(self, event):
        self.cleanup()
        super().closeEvent(event)

    def update_image(self, appearance_value = "original"):         
        image_path = os.path.join(self.btn_path, f"{appearance_value}.png")

        # Configuramos la imagen en el QLabel
        pixmap = QPixmap(image_path)
        self.label.setPixmap(pixmap)
        self.label.setScaledContents(True)

    

    def init_ui(self):
        # Configuración del diseño de la ventana principal
        layout = QVBoxLayout(self.central_widget)
        self.page_stack = QStackedWidget()
        layout.addWidget(self.page_stack)
        self.menu_page = MenuPage(self.page_stack, self)
        self.editor_page = EditorPage(self.page_stack, self)
        self.pages = [MenuPage(self.page_stack, self),
                     ProtocolPage(self.page_stack, self),
                     WireGuardPage(self.page_stack, self),
                     HidetorPage(self.page_stack, self),
                     LocationPage(self.page_stack, self),
                     BrowserPage(self.page_stack, self),
                     ScreenPage(self.page_stack, self),
                     ResumePage(self.page_stack, self),
                     ResidentialPage(self.page_stack, self),
                     InstallSystemPackage(self.page_stack, self),
                     WelcomePage(self.page_stack, self),
                     PaymentDetailsPage(self.page_stack, self),
                     DurationSelectionPage(self.page_stack, self),
                     CurrencySelectionPage(self.page_stack, self),
                     PaymentConfirmed(self.page_stack, self),
                     IdPage(self.page_stack, self),
                     TorPage(self.page_stack, self),
                     EditorPage(self.page_stack, self),
                     FastModePromptPage(self.page_stack, self),
                     FastRegistrationPage(self.page_stack, self),
                     Settings(self.page_stack, self),
                     ConnectionPage(self.page_stack, self),
                     SyncScreen(self.page_stack, self)]
        for page in self.pages:
            self.page_stack.addWidget(page)
        # Conectar la señal currentChanged al método page_changed
        self.page_stack.currentChanged.connect(self.page_changed)
        
        if self.check_first_launch():
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(WelcomePage)))

    def read_data(self):
        return self._data["Profile_1"]

    def write_data(self, data):
        self._data["Profile_1"].update(data)

    def clear_data(self):
        self._data = {"Profile_1": {}}

    def update_status(self, text, clear=False):
        if text is None:
            self.status_label.setText('Status:')
            self.disable_marquee()
            return
        
        if clear:
            self.status_label.setText('')
            return
        
        
        full_text = f'Status: {text}'
        self.status_label.setText(full_text)
        self.disable_marquee()

    def check_first_launch(self):

        config_file = os.path.join(self.gui_config_home, '.first-run')
        os.makedirs(Constants.HV_CONFIG_HOME, exist_ok=True)
        
        is_first_launch = not os.path.exists(config_file)
        
        if is_first_launch:
            try:
                with open(config_file, 'w') as f:
                    f.write('launched')
            except Exception as e:
                print(f"Error writing to launch file: {e}")
        
            return True
        else:
            return False

    def has_shown_fast_mode_prompt(self):
        flag_file = os.path.join(self.gui_config_home, '.fast-mode-prompted')
        return os.path.exists(flag_file)

    def mark_fast_mode_prompt_shown(self):
        os.makedirs(self.gui_config_home, exist_ok=True)
        flag_file = os.path.join(self.gui_config_home, '.fast-mode-prompted')
        try:
            with open(flag_file, 'w') as f:
                f.write('shown')
        except Exception as e:
            print(f"Error writing fast mode flag: {e}")

    def set_fast_mode_enabled(self, enabled):
        config = self._load_gui_config()
        if config is None:
            config = {"logging": {"gui_logging_enabled": False, "log_level": "INFO"}}
        if "registrations" not in config:
            config["registrations"] = {}
        config["registrations"]["fast_registration_enabled"] = bool(enabled)
        self._save_gui_config(config)

    def navigate_after_profile_created(self):
        if not self.has_shown_fast_mode_prompt():
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(FastModePromptPage)))
        else:
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage)))

    def enable_marquee(self, text):
        self.marquee_text = text + "   " 
        self.marquee_position = 0
        self.marquee_enabled = True
        self.marquee_timer.start(500)  

    def disable_marquee(self):
        self.marquee_enabled = False
        self.marquee_timer.stop()

    def update_marquee(self):
        if not self.marquee_enabled:
            return
        
        metrics = self.status_label.fontMetrics()
        text_width = metrics.horizontalAdvance(self.marquee_text)

        self.marquee_position += self.scroll_speed
        if self.marquee_position >= text_width:
            self.marquee_position = 0

        looped_text = self.marquee_text * 2
        
        chars_that_fit = metrics.horizontalAdvance(looped_text[:self.text_width])
        
        visible_text = looped_text[self.marquee_position:self.marquee_position + chars_that_fit]
        
        while metrics.horizontalAdvance(visible_text) < self.text_width:
            visible_text += self.marquee_text

        while metrics.horizontalAdvance(visible_text) > self.text_width:
            visible_text = visible_text[:-1]

        display_text = 'Status: ' + ' ' * (self.text_start_x - metrics.horizontalAdvance('Status: '))
        display_text += visible_text

        self.status_label.setText(display_text)

    def set_scroll_speed(self, speed):
        self.scroll_speed = speed

    @staticmethod
    def should_be_synchronized():

        current_datetime = datetime.today().astimezone(timezone.utc)
        last_synced_at = ConfigurationController.get_last_synced_at()

        return last_synced_at is None or (current_datetime - last_synced_at) >= timedelta(days=30)

    def page_changed(self, index):

        if CustomWindow.should_be_synchronized():
            sync_icon = QtGui.QIcon(os.path.join(self.btn_path, 'icon_sync_urgent.png'))
        else:
            sync_icon = QtGui.QIcon(os.path.join(self.btn_path, 'icon_sync.png'))

        self.sync_button.setIcon(sync_icon)

        current_page = self.page_stack.widget(index)
        if self.page_history:
            previous_page = self.page_history[-1]
        else:
            previous_page = None

        if isinstance(current_page, MenuPage):
            self.update_status(None)
            if isinstance(previous_page, (ResumePage, EditorPage, Settings, FastRegistrationPage, FastModePromptPage)):
                current_page.eliminacion() 
        
            else:
                pass
        elif isinstance(current_page, ResumePage):
            self.update_status('Choose a name for your profile')
            current_page.eliminacion()

        elif isinstance(current_page, IdPage):
            pass
        elif isinstance(current_page, LocationPage):
            self.update_status(None, clear=True)
        elif isinstance(current_page, InstallSystemPackage):
            self.update_status('Please check package availability.')
        else:
            self.update_status(None)

        if isinstance(current_page, MenuPage):
            self.sync_button.setVisible(True)
            self.tor_text.setVisible(True)
            self.toggle_button.setGeometry(670, 541, 50, 22)
            self.tor_icon.setGeometry(730, 537, 25, 25)
        else:
            self.sync_button.setVisible(False)
            self.tor_text.setVisible(False)
            self.toggle_button.setGeometry(540, 541, 50, 22)
            self.tor_icon.setGeometry(600, 537, 25, 25)

        if current_page != previous_page:
            self.page_history.append(current_page)
            self.page_history = self.page_history[-5:]

        if isinstance(current_page, EditorPage):
            if not self.connection_manager.is_synced():
                self.update_status('Not synchronized.')
    
        self.show()

class Page(QWidget):

    def __init__(self, name, page_stack, custom_window, parent=None):
        super().__init__(parent)
        self.custom_window = custom_window
        self.btn_path = custom_window.btn_path
        self.name = name
        self.page_stack = page_stack
        self.init_ui()
        self.selected_profiles = []
        self.selected_wireguard= [] # Lista para almacenar perfiles seleccionados
        self.selected_residential= []
        self.buttons = [] 

    def add_selected_profile(self, profile):
        self.selected_profiles.clear()
        self.selected_wireguard.clear()
        self.selected_residential.clear()  
        self.selected_profiles.append(profile)
        # self.selected_wireguard.append(wireguard)
        # self.selected_residential.append(residential)

    def init_ui(self):
        self.title = QLabel(self)
        self.title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.title.setObjectName("titles")

        self.display = QLabel(self)
        self.display.setObjectName("display")
        self.display.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)        
        #self.display.setStyleSheet("background-color: yellow;")
        buttons_info = [
            (QPushButton, "button_back", "back", (660, 525, 48, 35)),
            (QPushButton, "button_next", "next", (720, 525, 48, 35)),
            (QPushButton, "button_reverse", "back", (660, 525, 48, 35)),
            (QPushButton, "button_go", "next", (720, 525, 48, 35)),
            (QPushButton, "button_apply", "apply", (720, 525, 48, 35)),
        ]
        for button_type, object_name, icon_name, geometry in buttons_info:
            button = button_type(self)
            button.setObjectName(object_name)
            button.setGeometry(*geometry)
            button.setIcon(QIcon(os.path.join(self.btn_path, f"{icon_name}.png")))
            button.setIconSize(QtCore.QSize(48, 35))
            button.setVisible(False)  # Ocultar el botón inicialmente
            if object_name == "button_back":
                self.button_back = button
                self.button_back.clicked.connect(self.gestionar_back)
            if object_name == "button_next":
                self.button_next = button
                self.button_next.clicked.connect(self.gestionar_next)
            if object_name == "button_reverse":
                self.button_reverse = button
                self.button_reverse.clicked.connect(self.limpiar)

            if object_name == "button_go":
                self.button_go = button
                self.button_go.clicked.connect(self.limpiar)

            if object_name == "button_apply":
                self.button_apply = button
       
        

    def gestionar_back(self):
        current_index = self.page_stack.currentIndex()
        if current_index == 18:
            return
        if current_index > 0:
            self.page_stack.setCurrentIndex(current_index - 1)
            
    def gestionar_next(self):
        
        current_index = self.page_stack.currentIndex()
        next_index = (current_index + 1) % self.page_stack.count()
        self.page_stack.setCurrentIndex(next_index)
        self.limpiar()

    def limpiar(self):
        self.display.clear()
        for boton in self.buttons:
            boton.setChecked(False)
        

        self.button_next.setVisible(False)


class Worker(QObject):
    update_signal = pyqtSignal(str, bool, int, int, str) 
    change_page = pyqtSignal(str, bool)

    def __init__(self, profile_data):
        self.profile_data = profile_data
        super().__init__()
        profile_observer.subscribe('disabled', lambda event: self.handle_profile_status(event.subject, False))
        profile_observer.subscribe('enabled', lambda event: self.handle_profile_status(event.subject, True))
        self.profile_type = None

    def run(self):
        self.profile = ProfileController.get(int(self.profile_data['id']))

        if 'billing_code' in self.profile_data:
            subscription = SubscriptionController.get(self.profile_data['billing_code'], connection_observer=connection_observer)
            if subscription is not None:
                ProfileController.attach_subscription(self.profile, subscription)
            else:
                self.change_page.emit('The billing code associated with this profile is invalid.', True)
                return
        if self.profile:
            try:
                ignore_exceptions = []
                if self.profile_data.get('ignore_endpoint_verification', False):
                    ignore_exceptions.append(EndpointVerificationError)
                if self.profile_data.get('ignore_profile_state_conflict', False):
                    ignore_exceptions.append(ProfileStateConflictError)
                ignore_tuple = tuple(ignore_exceptions)
                ProfileController.enable(self.profile, ignore=ignore_tuple, profile_observer=profile_observer, 
                                         application_version_observer=application_version_observer, 
                                         connection_observer=connection_observer) 
            except EndpointVerificationError:
                self.update_signal.emit("ENDPOINT_VERIFICATION_ERROR", False, self.profile_data['id'], None, None)
            except (InvalidSubscriptionError, MissingSubscriptionError) as e:
                self.change_page.emit(f"Subscription missing or invalid for profile {self.profile_data['id']}", True)
            except ProfileActivationError:
                self.update_signal.emit("The profile could not be enabled", False, None, None, None)
            except UnsupportedApplicationVersionError:
                self.update_signal.emit("The application version in question is not supported", False, None, None, None)
            except FileIntegrityError:
                self.update_signal.emit("Application version file integrity could not be verified.", False, None, None, None)
            except ProfileModificationError:
                self.update_signal.emit("WireGuard configuration could not be attached.", False, None, None, None)
            except ProfileStateConflictError:
                self.update_signal.emit("PROFILE_STATE_CONFLICT_ERROR", False, self.profile_data['id'], None, None)
            except CommandNotFoundError as e :
                self.update_signal.emit(str(e.subject), False, -1, None, None)
            except Exception as e:
                print(e)
                self.update_signal.emit("An unknown error occurred", False, None, None, None)

        else:
            self.update_signal.emit(f"No profile found with ID: {self.profile_data['id']}", False, None, None, None)


    def handle_profile_status(self, profile, is_enabled):
        profile_id = profile.id
        profile_connection = str(profile.connection.code)
        message = self.generate_profile_message(profile, is_enabled)

        if isinstance(profile, SessionProfile):
            self.profile_type = 1
        elif isinstance(profile, SystemProfile):
            self.profile_type = 2
        else:
            self.profile_type = None

        self.update_signal.emit(message, is_enabled, profile_id, self.profile_type, profile_connection)

    @staticmethod
    def generate_profile_message(profile, is_enabled, idle=False):

        profile_id = profile.id
        if not profile.subscription or not profile.subscription.expires_at:
            return f"Offline. No subscription found."
        
        profile_date = profile.subscription.expires_at
        status = 'enabled' if is_enabled else 'disabled'

        expiration_date = profile_date.replace(tzinfo=timezone.utc)
        
        time_left = expiration_date - datetime.now(timezone.utc)
        days_left = time_left.days
        hours_left, remainder = divmod(time_left.seconds, 3600)

        formatted_expiration = expiration_date.strftime("%Y-%m-%d %H:%M:%S")

        if expiration_date < datetime.now(timezone.utc):
            return "Offline. Subscription has expired."
        if idle:
            return f"Offline. Expires in {days_left} days."
        
        if is_enabled:
            return f"Profile {int(profile_id)} {status}. Expires on {formatted_expiration}. Time left: {days_left} days, {hours_left} hours."
        else:
            return f"Profile {int(profile_id)} {status}"
class MenuPage(Page):
    def __init__(self, page_stack=None, main_window=None, parent=None):
        super().__init__("Menu", page_stack, main_window, parent)
        self.main_window = main_window
        self.connection_manager = main_window.connection_manager
        self.is_tor_mode = main_window.is_tor_mode
        self.is_animating = main_window.is_animating
        self.animation_step = main_window.animation_step
        self.btn_path = main_window.btn_path
        self.page_stack = page_stack
        self.profile_info = {}
        self.additional_labels = []
        self.update_status = main_window
        self.title.setGeometry(400, 40, 380, 30); self.title.setText("Load Profile")

        self.scroll_area = QScrollArea(self)
        self.scroll_area.setGeometry(420, 80, 370, 350)
        self.scroll_area.setWidgetResizable(True)
        self.scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        self.scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
        self.scroll_area.setStyleSheet("""
            QScrollArea {
                background-color: transparent; 
                border: none;
            }
            QScrollBar:vertical {
                background-color: rgba(128, 128, 128, 0.3);
                width: 12px;
                border-radius: 6px;
            }
            QScrollBar::handle:vertical {
                background-color: rgba(0, 255, 255, 0.7);
                border-radius: 6px;
                min-height: 20px;
            }
            QScrollBar::handle:vertical:hover {
                background-color: rgba(0, 255, 255, 0.9);
            }
            QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
                background-color: transparent;
                height: 0px;
            }
        """)
        
        self.scroll_widget = QWidget()
        self.scroll_widget.setStyleSheet("background-color: transparent;")
        self.scroll_area.setWidget(self.scroll_widget)
        

        self.not_connected_profile = os.path.join(self.btn_path, "button_profile.png")  
        self.connected_profile = os.path.join(self.btn_path, "button_session_profile.png")
        self.system_wide_connected_profile = os.path.join(self.btn_path, "button_system_profile.png") 
        self.connected_tor_profile = os.path.join(self.btn_path, "button_session_tor.png")
        self.worker = None
        self.IsSystem: int = 0
        self.button_states = {}
        self.is_system_connected = False
        self.profile_button_map = {}  


        #self.label.setStyleSheet("background-color: rgba(0, 255, 0, 51);")  
        self.create_interface_elements()        # Establecer el color de fondo y el color del texto utilizando hojas de estilo

    def showEvent(self, event):
        super().showEvent(event)
        if hasattr(self, 'buttons'):
            for button in self.buttons:
                parent = button.parent()
                if parent:
                    verification_icons = parent.findChildren(QPushButton)
                    for icon in verification_icons:
                        if icon.geometry().width() == 20 and icon.geometry().height() == 20:
                            icon.setEnabled(self.connection_manager.is_synced())

    def on_update_check_finished(self):
            reply = QMessageBox.question(self, 'Update Available', 
                                       'An update is available. Would you like to download it?',
                                       QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
            if reply == QMessageBox.StandardButton.Yes:
                self.worker = WorkerThread('DOWNLOAD_UPDATE')
                self.worker.start()
            else:
                self.update_status.update_status('Update canceled')

    

    def create_interface_elements(self):
        for icon_name, function, position in [
            ("create_profile", self.create_prof, (410, 440, 110, 60)),
            ("edit_profile", self.edit_prof, (540, 440, 110, 60)),
            #("delete_profile", self.delete_profile, (670, 440, 110, 60)),
            ("launch", self.launch, (0, 440,185,63)),
            ("disconnect", self.disconnect, (200, 433,185,73)),
            ("disconnect_system_wide", self.disconnect, (200, 433,185,73)),
            ("just", self.connect, (200, 433,185,73)),
            ("just_session", self.connect, (200, 433,185,73)),
            ("settings", self.settings_gui, (670, 440, 110, 60)),
        ]:
            boton = QPushButton(self)
            boton.setGeometry(QtCore.QRect(*position))
            boton.setObjectName("create_edit_settings_buttons")
            icon = QtGui.QIcon(os.path.join(self.btn_path, f"{icon_name}.png"))
            boton.setIcon(icon)
            boton.setIconSize(boton.size())
            boton.clicked.connect(functools.partial(function))
            boton.setEnabled(False)
            if icon_name == "disconnect":
                boton.setEnabled(True)
                boton.setVisible(False)
                self.disconnect_button = boton
            if icon_name == "launch":
                self.boton_launch = boton
                self.boton_launch.setVisible(False)
            if icon_name =="create_profile":
                self.boton_create=boton
                self.boton_create.setEnabled(True)
            if icon_name =="edit_profile":
                self.boton_edit=boton
            #if icon_name =="delete_profile":
            #    self.boton_settings=boton
            if icon_name =="just":
                boton.setVisible(False)
                self.boton_just=boton
                self.connect_button = boton
            if icon_name =="just_session":
                self.boton_just_session=boton
                self.connect_button = boton
            if icon_name =="disconnect_system_wide":
                boton.setEnabled(True)
                boton.setVisible(False)
                self.disconnect_system_wide_button = boton
            if icon_name =="settings":
                self.settings_button = boton
                self.settings_button.setEnabled(True)
            
        self.create()

    def delete_profile(self):
        self.popup = ConfirmationPopup(self, message="Are you sure you want to\ndelete this profile?", action_button_text="Delete", cancel_button_text="Cancel")
        self.popup.setWindowModality(Qt.WindowModality.ApplicationModal)
        self.popup.finished.connect(lambda result: self.on_popup_finished(result))
        self.popup.show()
    
    def on_popup_finished(self, result):
        if result:
            profile_id = self.reverse_id
            self.update_status.update_status(f'Deleting profile...')
            self.worker_thread = WorkerThread('DESTROY_PROFILE', profile_data={'id': profile_id})
            self.worker_thread.text_output.connect(self.delete_status_update)
            self.worker_thread.start()
        else:
            pass

    def delete_status_update(self, text):
        self.update_status.update_status(text)
        self.eliminacion()

    def show_disconnect_button(self, toggle, profile_type, target_button):
        if target_button.isChecked():
            if profile_type == 1:
                self.disconnect_button.setVisible(toggle)
                self.boton_just_session.setVisible(not toggle)
            else:
                self.disconnect_system_wide_button.setVisible(toggle)
                self.boton_just.setVisible(not toggle)
    
    def match_core_profiles(self, profiles_dict):
        new_dict = {}

        for idx, profile in profiles_dict.items():
            new_profile = {}

            protocol = profile.connection.code

            location = f'{profile.location.country_code}_{profile.location.code}'

            new_profile['location'] = location
            
            if protocol == 'wireguard':
                new_profile['protocol'] = 'wireguard'
            else:
                new_profile['protocol'] = 'hidetor'

            connection_type = 'browser-only' if isinstance(profile, SessionProfile) else 'system-wide'

            if protocol == 'wireguard':
                new_profile['connection'] = connection_type
            elif protocol == 'tor':
                new_profile['connection'] = protocol
            else:
                new_profile['connection'] = 'just proxy'

            if isinstance(profile, SessionProfile):
                browser = profile.application_version.application_code
            else:
                browser = 'unknown'
            if browser != 'unknown':
                new_profile['browser'] = browser
                new_profile['browser_version'] = profile.application_version.version_number
                new_profile['browser_supported'] = profile.application_version.supported
            else:
                new_profile['browser'] = 'unknown browser'
                new_profile['browser_supported'] = False

            resolution = profile.resolution if hasattr(profile, 'resolution') else 'None'
            new_profile['dimentions'] = resolution

            new_profile['name'] = profile.name

            new_dict[f'Profile_{idx}'] = new_profile

        return new_dict
    
    def create(self):
        self.boton_just.setEnabled(False)
        self.boton_just_session.setEnabled(False)
        self.boton_edit.setEnabled(False)
        if hasattr(self, 'verification_button'):
            self.verification_button.setEnabled(False)
        self.profiles_data = self.match_core_profiles(ProfileController.get_all())

        self.number_of_profiles = len(self.profiles_data)
        self.profile_info.update(self.profiles_data)

        self.button_group = QButtonGroup(self)
        self.buttons = []
        
        for profile_name, profile_value in self.profiles_data.items():
            self.create_profile_widget(profile_name, profile_value)
        
        self.update_scroll_widget_size()

    def refresh_profiles_data(self):
        self.profiles_data = self.match_core_profiles(ProfileController.get_all())
        self.number_of_profiles = len(self.profiles_data)
        self.profile_info.update(self.profiles_data)
        for profile_name, profile_value in self.profiles_data.items():
            self.create_profile_widget(profile_name, profile_value)
        self.update_scroll_widget_size()

    def update_scroll_widget_size(self):
        if self.number_of_profiles == 0:
            return
        
        rows = (self.number_of_profiles + 1) // 2
        height = rows * 120
        self.scroll_widget.setFixedSize(370, height)

    def create_profile_widget(self, key, value):
        profile_id = int(key.split('_')[1])  

        parent_label = self.create_parent_label(profile_id)
        button = self.create_profile_button(parent_label, profile_id, key)
        
        self.profile_button_map[profile_id] = button
        
        self.create_profile_name_label(parent_label, value["name"])
        self.create_profile_icons(parent_label, value)

    def create_parent_label(self, profile_id):
        parent_label = QLabel(self.scroll_widget)
        profile_list = list(self.profiles_data.keys())
        index = profile_list.index(f'Profile_{profile_id}')
        row, column = divmod(index, 2) 
        
        parent_label.setGeometry(column * 179, row * 120, 175, 100)
        parent_label.setVisible(True)
        return parent_label

    def create_profile_button(self, parent_label, profile_id, key):
        button = QPushButton(parent_label)
        button.setGeometry(0, 0, 175, 60)
        button.setStyleSheet("""
            QPushButton {
                background-color: transparent;
                border: none;
            }
            QPushButton:hover {
                background-color: rgba(200, 200, 200, 50);
            }
            QPushButton:checked {
                background-color: rgba(200, 200, 200, 80);
            }
        """)
        
        icon = QIcon(self.button_states.get(profile_id, self.not_connected_profile))
        button.setIcon(icon)
        button.setIconSize(QtCore.QSize(175, 60))
        
        button.show()
        button.setCheckable(True)
        self.button_group.addButton(button)
        self.buttons.append(button)
        
        button.clicked.connect(lambda checked, pid=profile_id: self.print_profile_details(f"Profile_{pid}"))
        
        profile = ProfileController.get(profile_id)
        if profile and profile.location and profile.location.operator:
            verification_icon = QPushButton(parent_label)
            icon_size = 23
            button_width = 175
            icon_x = button_width - icon_size - 50
            icon_y = 0
            verification_icon.setGeometry(icon_x, icon_y, icon_size, icon_size)
            verification_icon.setIcon(QIcon(os.path.join(self.btn_path, "verification_icon.png")))
            verification_icon.setIconSize(QSize(icon_size, icon_size))
            verification_icon.setStyleSheet(f"""
                QPushButton {{
                    background: transparent;
                    border: none;
                }}
                QPushButton:hover {{
                    background: rgba(255, 255, 255, 0.2);
                    border-radius: 3px;
                }}
                QPushButton:disabled {{
                    opacity: 0.3;
                }}
            """)
            verification_icon.setCursor(QtCore.Qt.CursorShape.PointingHandCursor)
            verification_icon.setEnabled(self.connection_manager.is_synced())
            verification_icon.clicked.connect(lambda checked, pid=profile_id: self.show_profile_verification(pid))
            verification_icon.show()
        
        return button

    def create_profile_name_label(self, parent_label, name):
        child_label = QLabel(parent_label)
        child_label.setGeometry(0, 65, 175, 30)
        child_label.setText(name)
        child_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        child_label.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents)
        child_label.show()

    def create_profile_icons(self, parent_label, value):
        connection_type = value.get('connection', '')
        if connection_type in ['tor', 'just proxy']:
            self.create_tor_proxy_icons(parent_label, value, connection_type)
        else:
            self.create_other_icons(parent_label, value, connection_type)

    def create_tor_proxy_icons(self, parent_label, value, connection_type):
        for j, label_name in enumerate(['protocol', 'location', 'browser']):
            child_label = QLabel(parent_label)
            child_label.setObjectName(f"label_{j}")
            child_label.setGeometry(3 + j * 60, 5, 50, 50)
            child_label.setObjectName("label_profiles")
            child_label.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents)
            child_label.setStyleSheet("background-color: rgba(128, 128, 128, 0.5); border-radius: 25px;")
            image_path = self.get_icon_path(label_name, value, connection_type)
            pixmap = QPixmap(image_path)
            if pixmap.isNull() and label_name == 'location':
                fallback_path = os.path.join(self.btn_path, "default_location_mini.png")
                pixmap = QPixmap(fallback_path)
                if pixmap.isNull():
                    pixmap = QPixmap(50, 50)
                    pixmap.fill(QtGui.QColor(200, 200, 200))  
            if pixmap.isNull() and label_name == 'browser':
                fallback_path = os.path.join(self.btn_path, "default_browser_mini.png")
                pixmap = QPixmap(fallback_path)
                if pixmap.isNull():
                    pixmap = QPixmap(50, 50)
                    pixmap.fill(QtGui.QColor(200, 200, 200))  
            child_label.setPixmap(pixmap)
            child_label.show()

    def create_other_icons(self, parent_label, value, connection_type):
        for j, label_name in enumerate(['protocol', 'location', 'browser']):
            child_label = QLabel(parent_label)
            child_label.setObjectName(f"label_{j}")
            child_label.setGeometry(3 + j * 60, 5, 50, 50)
            child_label.setObjectName("label_profiles")
            child_label.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents)
            child_label.setStyleSheet("background-color: rgba(128, 128, 128, 0.5); border-radius: 25px;")

            image_path = self.get_icon_path(label_name, value, connection_type)
            pixmap = QPixmap(image_path)
            if pixmap.isNull() and label_name == 'location':
                fallback_path = os.path.join(self.btn_path, "default_location_mini.png")
                pixmap = QPixmap(fallback_path)
                if pixmap.isNull():
                    pixmap = QPixmap(50, 50)
                    pixmap.fill(QtGui.QColor(200, 200, 200))  
            if pixmap.isNull() and label_name == 'browser':
                fallback_path = os.path.join(self.btn_path, "default_browser_mini.png")
                pixmap = QPixmap(fallback_path)
                if pixmap.isNull():
                    pixmap = QPixmap(50, 50)
                    pixmap.fill(QtGui.QColor(200, 200, 200)) 

            if label_name == 'browser' and not value.get('browser_supported', True) and value.get('browser') != 'unknown browser':
                warning_pixmap = QPixmap(os.path.join(self.btn_path, 'warning.png'))
                painter = QPainter(pixmap)
                painter.drawPixmap(pixmap.width() - 22, pixmap.height() - 21, warning_pixmap)
                painter.end()

            child_label.setPixmap(pixmap)
            child_label.show()

    def get_icon_path(self, label_name, value, connection_type):
        if label_name == 'protocol':
            if connection_type == 'tor':
                return os.path.join(self.btn_path, "toricon_mini.png")
            elif connection_type == 'just proxy':
                return os.path.join(self.btn_path, "just proxy_mini.png")

            return os.path.join(self.btn_path, "wireguard_mini.png")
        elif label_name == 'browser':
            if connection_type == 'system-wide':
                return os.path.join(self.btn_path, "wireguard_system_wide.png")
            else:
                return os.path.join(self.btn_path, f"{value[label_name]} latest_mini.png")
            
        return os.path.join(self.btn_path, f"icon_mini_{value[label_name]}.png")


    def print_profile_details(self, profile_name):
        self.reverse_id =  int(profile_name.split('_')[1])
        
        target_button = self.profile_button_map.get(self.reverse_id)
        if target_button:
            self.connection_manager.set_profile_button_objects(self.reverse_id, target_button)
        else:
            print(f"No button found for profile {self.reverse_id}")
        is_connected = self.connection_manager.is_profile_connected(int(self.reverse_id)) 
        if is_connected:
            self.boton_edit.setEnabled(False)
        else:
            self.boton_edit.setEnabled(True)

        profile = self.profile_info.get(profile_name)
        self.boton_launch.setEnabled(True)
        self.boton_just.setEnabled(True)
        self.boton_just_session.setEnabled(True)
        self.boton_create.setEnabled(True)
        if hasattr(self, 'buttons'):
            for button in self.buttons:
                parent = button.parent()
                if parent:
                    verification_icons = parent.findChildren(QPushButton)
                    for icon in verification_icons:
                        if icon.geometry().width() == 20 and icon.geometry().height() == 20:
                            icon.setEnabled(self.connection_manager.is_synced())
        #self.boton_settings.setEnabled(True)

        
        # Eliminar labels adicionales anteriores
        for label in self.additional_labels:
            label.deleteLater()
        
        # Limpiar la lista de labels adicionales
        self.additional_labels.clear()

        

        self.change_connect_button()

        if profile:
            self.update_status.current_profile_id = self.reverse_id
            profile_number = profile_name.split("_")[1]  # Extraer el número del perfil del nombre del perfil
            name = profile.get("name", "")
            protocol = profile.get("protocol", "")
            location = profile.get("location", "")
            connection = profile.get("connection", "") 
            country_garaje = profile.get("country_garaje", "")
 

            if protocol.lower() in ["wireguard", "open", "lokinet","residential", "hidetor"]:

                label_principal = QLabel(self)
                label_principal.setGeometry(0, 90, 400, 300)
                pixmap=QPixmap(os.path.join(self.btn_path, f"{protocol}_{location}.png"))
                label_principal.setPixmap(pixmap)
                label_principal.setScaledContents(True)


                label_principal.show()
                self.additional_labels.append(label_principal)
                
                if protocol.lower() == "wireguard" and ConfigurationController.get_endpoint_verification_enabled():
                    profile_obj = ProfileController.get(self.reverse_id)
                    is_profile_enabled = self.connection_manager.is_profile_connected(self.reverse_id)
                    if profile_obj and profile_obj.connection and profile_obj.connection.code == 'wireguard' and is_profile_enabled:
                        verified_icon = QLabel(self)
                        verified_icon.setGeometry(0, 60, 400, 40)
                        verified_pixmap = QPixmap(os.path.join(self.btn_path, "verified_profile.png"))
                        verified_icon.setPixmap(verified_pixmap)
                        verified_icon.setScaledContents(True)
                        verified_icon.show()
                        self.additional_labels.append(verified_icon)

            if protocol.lower() == "hidetor":

                label_principal.setGeometry(0, 80, 400, 300)
                label_background = QLabel(self)
                label_background.setGeometry(0, 60, 410, 354)  
                if connection == 'just proxy':
                    image_path = os.path.join(self.btn_path, f"icon_{location}.png")    
                else:
                    image_path = os.path.join(self.btn_path, f"hdtor_{location}.png")
                pixmap = QPixmap(image_path)
                label_background.setPixmap(pixmap)
                label_background.show()
                label_background.setScaledContents(True)
                label_background.lower()
                self.additional_labels.append(label_background)


            if protocol.lower() == "wireguard" and connection.lower() == "browser-only":

                # Redimensionar el QLabel principal
                label_principal.setGeometry(0, 80, 400, 300)
                
                # Crear QLabel con la imagen os.path.join(self.btn_path, "browser only.png") detrás del label_principal
                label_background = QLabel(self)
                label_background.setGeometry(0, 60, 410, 354)  # Geometría según necesidades
                is_supported = profile.get('browser_supported', False)
                image_name = "browser only.png" if is_supported else "unsupported_browser_only.png"
                pixmap = QPixmap(os.path.join(self.btn_path, image_name))
                label_background.setPixmap(pixmap)
                label_background.show()
                label_background.setScaledContents(True)
                label_background.lower()
                self.additional_labels.append(label_background)
                
            if protocol.lower() == "residential" and connection.lower() == "tor":

                label_background = QLabel(self)
                label_background.setGeometry(0, 60, 410, 354)
                pixmap = QPixmap(os.path.join(self.btn_path, "browser_tor.png"))
                label_background.setPixmap(pixmap)
                label_background.show()
                label_background.setScaledContents(True)
                #label_background.setStyleSheet("background-color: blue;")
                self.additional_labels.append(label_background)

                label_garaje = QLabel(self)
                label_garaje.setGeometry(5, 110, 400, 300)
                pixmap = QPixmap(os.path.join(self.btn_path, f"{country_garaje} garaje.png"))
                label_garaje.setPixmap(pixmap)
                label_garaje.show()
                label_garaje.setScaledContents(True)
                #label_garaje.setStyleSheet("background-color: red;")
                self.additional_labels.append(label_garaje)

                label_tor = QLabel(self)
                label_tor.setGeometry(330, 300, 75, 113)
                pixmap = QPixmap(os.path.join(self.btn_path, "tor 86x130.png"))
                label_tor.setPixmap(pixmap)
                label_tor.show()
                label_tor.setScaledContents(True)
                self.additional_labels.append(label_tor)
            if protocol.lower() == "residential" and connection.lower() == "just proxy":
                
                label_background = QLabel(self)
                label_background.setGeometry(0, 60, 410, 354)
                pixmap = QPixmap(os.path.join(self.btn_path, "browser_just_proxy.png"))
                label_background.setPixmap(pixmap)
                label_background.show()
                label_background.setScaledContents(True)
                #label_background.setStyleSheet("background-color: blue;")
                self.additional_labels.append(label_background)

                label_garaje = QLabel(self)
                label_garaje.setGeometry(5, 110, 400, 300)
                pixmap = QPixmap(os.path.join(self.btn_path, f"{country_garaje} garaje.png"))
                label_garaje.setPixmap(pixmap)
                label_garaje.show()
                label_garaje.setScaledContents(True)
                #label_garaje.setStyleSheet("background-color: red;")
                self.additional_labels.append(label_garaje)

            # Actualizar perfil para editar
            editar_profile = {"profile_number": profile_number, "name": name, "protocol": protocol}
            self.page_stack.currentWidget().add_selected_profile(editar_profile)
            
            self.current_profile_location = location

    def show_profile_verification(self, profile_id):
        profile = ProfileController.get(profile_id)
        if not profile or not profile.location:
            return
        
        location_key = f'{profile.location.country_code}_{profile.location.code}'
        location_info = self.connection_manager.get_location_info(location_key)
        if not location_info:
            return
        
        location_icon_name = None
        btn_path = self.btn_path
        
        for icon_file in os.listdir(btn_path):
            if icon_file.startswith('button_') and icon_file.endswith('.png'):
                icon_name = icon_file.replace('button_', '').replace('.png', '')
                test_loc = self.connection_manager.get_location_info(icon_name)
                if test_loc and test_loc.country_code == location_info.country_code and test_loc.code == location_info.code:
                    location_icon_name = icon_name
                    break
        
        if location_icon_name:
            verification_page = LocationVerificationPage(self.page_stack, self.update_status, location_icon_name, self)
            self.page_stack.addWidget(verification_page)
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(verification_page))

    def launch(self): 
        pass
    
    
    def connect(self): 
        self.boton_just.setEnabled(False)
        self.boton_just_session.setEnabled(False)

        profile = ProfileController.get(int(self.reverse_id))
        is_tor = self.update_status.get_current_connection() == 'tor'
        if profile.connection.code == 'tor' and not profile.application_version.installed and not is_tor:
            message = f'You are using a Tor profile, but the associated browser is not installed. If you want the browser to be downloaded with Tor, you must switch to a Tor connection. Otherwise, proceed with a clearweb connection.'

        else:
            self.get_billing_code_by_id()
            return
        
        self.popup = self.update_status._create_confirmation_popup(message, button_text='Proceed')
        self.popup.finished.connect(lambda result: self._handle_popup_result(result))
        self.popup.show()
        
        
    def _handle_popup_result(self, result, change_screen=False):
        if result:
            if change_screen:
                self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(IdPage)))
            else:
                self.get_billing_code_by_id()
        else:
            self.popup.close()

    def disconnect(self): 
        self.disconnect_button.setEnabled(False)
        self.disconnect_system_wide_button.setEnabled(False)
        self.update_status.update_status('Disconnecting...')
        profile_data = {
            'id':  int(self.reverse_id)
        }
        profile = ProfileController.get(int(self.reverse_id))
        is_session_profile = isinstance(profile, SessionProfile)
        if not is_session_profile:
            connected_profiles = self.connection_manager.get_connected_profiles()
            if len(connected_profiles) > 1:
                message = f'Profile{"" if len(connected_profiles) == 1 else "s"} {", ".join(str(profile_id) for profile_id in connected_profiles)} are still connected.\nAll connected session profiles will be disconnected. \nDo you want to proceed?'
                self.update_status._show_disconnect_confirmation(connected_profiles, button_text='Disable', message=message)
                self.disconnect_button.setEnabled(True)
                self.disconnect_system_wide_button.setEnabled(True)
                return
        self.worker_thread = WorkerThread('DISABLE_PROFILE', profile_data=profile_data)
        self.worker_thread.finished.connect(self.on_disconnect_done)
        self.worker_thread.start()

    def on_disconnect_done(self):
        self.disconnect_button.setEnabled(True)
        self.disconnect_system_wide_button.setEnabled(True)
        pass

    def create_prof(self):   
        settings_page = self.page_stack.findChild(Settings)
        if settings_page and settings_page.is_fast_registration_enabled():
            if not self.connection_manager.is_synced():
                self.update_status.update_status('Syncing in progress..')
                self.update_status.sync()
                self.update_status.worker_thread.sync_output.connect(self.on_sync_complete_for_fast_registration)
            else:
                self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(FastRegistrationPage)))
            return
        

        if not self.connection_manager.is_synced():
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(SyncScreen)))
        else:
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(ProtocolPage)))
        
        

    def on_sync_complete_for_fast_registration(self, available_locations, available_browsers, status, is_tor, locations, all_browsers):
        if status:
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(FastRegistrationPage)))
        else:
            self.update_status.update_status('Sync failed. Please try again later.')


    def change_connect_button(self):
        profile = ProfileController.get(int(self.reverse_id))
        is_connected = self.connection_manager.is_profile_connected(int(self.reverse_id))
        is_session_profile = isinstance(profile, SessionProfile)

        self.update_button_visibility(is_connected, is_session_profile)
        self.update_status_message(profile, is_connected)

    def update_button_visibility(self, is_connected, is_session_profile):
        self.boton_just_session.setVisible(not is_connected and is_session_profile)
        self.boton_just.setVisible(not is_connected and not is_session_profile)
        self.disconnect_button.setVisible(is_connected and is_session_profile)
        self.disconnect_system_wide_button.setVisible(is_connected and not is_session_profile)

    def update_status_message(self, profile, is_connected):
        if is_connected:
            message = Worker.generate_profile_message(profile, is_enabled=True)
            self.update_status.enable_marquee(message)
        else:
            message = Worker.generate_profile_message(profile, is_enabled=True, idle=True)
            self.update_status.update_status(message)
            

    def edit_prof(self):   
        settings_page = self.page_stack.findChild(Settings)
        if settings_page and settings_page.is_auto_sync_enabled() and not self.connection_manager.is_synced():
            self.update_status.update_status('Syncing in progress..')
            self.update_status.sync()
            self.update_status.worker_thread.sync_output.connect(self.on_sync_complete_for_edit_profile)
        else:
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(EditorPage)))
 

    def on_sync_complete_for_edit_profile(self, available_locations, available_browsers, status, is_tor, locations, all_browsers):
        if status:
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(EditorPage)))
        else:
            self.update_status.update_status('Sync failed. Please try again later.')




    def settings_gui(self):   
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(Settings)))
    def eliminacion(self):
        current_state = {
            'is_tor_mode': self.is_tor_mode,
            'is_animating': self.is_animating,
            'animation_step': self.animation_step
        }
        
        self.main_window.toggle_bg.setParent(None)
        self.main_window.toggle_handle.setParent(None)
        self.main_window.on_label.setParent(None)
        self.main_window.off_label.setParent(None)
        
        for widget in self.scroll_widget.findChildren(QLabel):
            widget.setParent(None)
        
        for widget in self.scroll_widget.findChildren(QPushButton):
            widget.setParent(None)
            
        self.profile_info.clear()
        self.profile_button_map.clear()
        self.button_states.clear()
        self.buttons.clear()

        self.main_window.toggle_bg.setParent(self.main_window.toggle_button)
        self.main_window.toggle_handle.setParent(self.main_window.toggle_button)
        self.main_window.on_label.setParent(self.main_window.toggle_button)
        self.main_window.off_label.setParent(self.main_window.toggle_button)
        
        self.main_window.toggle_bg.show()
        self.main_window.toggle_handle.show()
        self.main_window.on_label.show()
        self.main_window.off_label.show()
        
        self.is_tor_mode = current_state['is_tor_mode']
        self.is_animating = current_state['is_animating']
        self.animation_step = current_state['animation_step']

        self.create()

    def get_billing_code_by_id(self, force: bool = False):
        profile_id = self.update_status.current_profile_id
        profile_data = {
            'id': profile_id,
            'force': force
        }
        self.update_status.update_status('Attempting to connect...')
        
        self.enabling_profile(profile_data)

    def enabling_profile(self, profile_data):
        '''
        if self.worker is not None:
            self.worker.update_signal.disconnect(self.update_gui_main_thread)
            self.worker.change_page.disconnect(self.change_app_page)
        '''
        self.worker = Worker(profile_data)
        self.worker.update_signal.connect(self.update_gui_main_thread)
        self.worker.change_page.connect(self.change_app_page)

        thread = threading.Thread(target=self.worker.run)
        thread.start()

    def DisplayInstallScreen(self, package_name):
        install_page = self.page_stack.findChild(InstallSystemPackage)
        install_page.configure(package_name=package_name, distro='debian')
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(install_page))

    def handle_enable_force_result(self, result):
        if result:
            profile_data = {'id': self.reverse_id, 'ignore_profile_state_conflict': True}
            if hasattr(self, '_pending_endpoint_verification_ignore') and self._pending_endpoint_verification_ignore:
                profile_data['ignore_endpoint_verification'] = True
            self.enabling_profile(profile_data)
        else:
            pass
        if hasattr(self, '_pending_profile_state_conflict_ignore'):
            delattr(self, '_pending_profile_state_conflict_ignore')
        if hasattr(self, '_pending_endpoint_verification_ignore'):
            delattr(self, '_pending_endpoint_verification_ignore')
        self.popup.close()
    
    def handle_endpoint_verification_result(self, result, action, profile_id):
        if action == "continue":
            profile_data = {'id': profile_id, 'ignore_endpoint_verification': True}
            if hasattr(self, '_pending_profile_state_conflict_ignore') and self._pending_profile_state_conflict_ignore:
                profile_data['ignore_profile_state_conflict'] = True
            self.enabling_profile(profile_data)
        elif action == "sync":
            self._pending_endpoint_verification_ignore = True
            self.update_status.update_status("Syncing...")
            self.worker_thread = WorkerThread('SYNC')
            self.worker_thread.finished.connect(lambda: self.handle_sync_after_verification(profile_id))
            self.worker_thread.sync_output.connect(self.update_status.update_values)
            self.worker_thread.start()
        else:
            self.update_status.update_status("Profile enable aborted")
        if hasattr(self, 'popup'):
            self.popup.close()
    
    def handle_sync_after_verification(self, profile_id):
        profile_data = {'id': profile_id, 'ignore_endpoint_verification': True}
        if hasattr(self, '_pending_profile_state_conflict_ignore') and self._pending_profile_state_conflict_ignore:
            profile_data['ignore_profile_state_conflict'] = True
        self.enabling_profile(profile_data)

    def update_gui_main_thread(self, text, is_enabled, profile_id, profile_type, profile_connection):
        if text == "ENDPOINT_VERIFICATION_ERROR":
            message = "Operator verification failed. Do you want to continue anyway?"
            self.popup = EndpointVerificationPopup(self, message=message)
            self.popup.finished.connect(lambda result, action: self.handle_endpoint_verification_result(result, action, profile_id))
            self.popup.show()
            return
        
        if text == "PROFILE_STATE_CONFLICT_ERROR":
            message = f'The profile is already enabled. Do you want to force enable it anyway?'
            self._pending_profile_state_conflict_ignore = True
            self.popup = self.update_status._create_confirmation_popup(message, button_text='Proceed')
            self.popup.finished.connect(lambda result: self.handle_enable_force_result(result))
            self.popup.show()
            return
        
        
        if profile_id < 0:
            self.DisplayInstallScreen(text)
            return
        if is_enabled:
            self.update_status.enable_marquee(str(text))
        else:
            self.update_status.update_status(str(text))
        if profile_id is not None:
            self.on_finished_update_gui(is_enabled, profile_id, profile_type, profile_connection)
        self.boton_just.setEnabled(True)
        self.boton_just_session.setEnabled(True)

    def change_app_page(self, text, Is_changed):
        self.update_status.update_status(str(text))
        if Is_changed:
            current_connection = self.update_status.get_current_connection()
            profile = ProfileController.get(int(self.reverse_id))
            if current_connection != 'tor' and profile.connection.code == 'tor':
                message = f'You are using a Tor profile, but the profile subscription is missing or expired. If you want the billing to be done thourgh Tor, you must switch to a Tor connection. Otherwise, proceed with a clearweb connection.'
                self.popup = self.update_status._create_confirmation_popup(message, button_text='Proceed')
                self.popup.finished.connect(lambda result: self._handle_popup_result(result, True))
                self.popup.show()
            else:
                self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(IdPage)))

        self.boton_just.setEnabled(True)
        self.boton_just_session.setEnabled(True)

    def on_finished_update_gui(self, is_enabled, profile_id, profile_type, profile_connection):
        try: 
            if is_enabled:
                self.connection_manager.add_connected_profile(profile_id)
                if profile_type == 1:
                    target_button: QPushButton = self.connection_manager.get_profile_button_objects(profile_id)
                    icon_path = self.connected_tor_profile if profile_connection == 'tor' else self.connected_profile
                    target_button.setIcon(QIcon(icon_path))
                    self.button_states[profile_id] = icon_path
                else:
                    target_button: QPushButton = self.connection_manager.get_profile_button_objects(profile_id)
                    target_button.setIcon(QIcon(self.system_wide_connected_profile))
                    self.update_status.update_image(appearance_value='background_connected')
                    self.button_states[profile_id] = self.system_wide_connected_profile
                    self.IsSystem += 1

                self.show_disconnect_button(True, profile_type, target_button)
                self.boton_edit.setEnabled(False)
                
                if profile_id == self.reverse_id:
                    profile_obj = ProfileController.get(profile_id)
                    if profile_obj and profile_obj.connection and profile_obj.connection.code == 'wireguard' and ConfigurationController.get_endpoint_verification_enabled():
                        self.print_profile_details(f"Profile_{profile_id}")
            else:
                self.connection_manager.remove_connected_profile(profile_id)
                
                if profile_type == 1:
                    target_button: QPushButton = self.connection_manager.get_profile_button_objects(profile_id)
                    target_button.setIcon(QIcon(self.not_connected_profile)) 
                    if profile_id in self.button_states:
                        del self.button_states[profile_id]
                else:
                    self.IsSystem -= 1
                    target_button: QPushButton = self.connection_manager.get_profile_button_objects(profile_id)
                    target_button.setIcon(QIcon(self.not_connected_profile)) 
                    if profile_id in self.button_states:
                        del self.button_states[profile_id]
                    if self.IsSystem == 0:
                        self.update_status.update_image()

                self.show_disconnect_button(False, profile_type, target_button)
                self.boton_edit.setEnabled(True)
        except IndexError:
            self.update_status.update_status('An error occurred while updating profile state.')


class ConnectionManager:
    def __init__(self):
        self._connected_profiles = set()
        self._is_synced = False
        self._is_profile_being_enabled = {}
        self.profile_button_objects = {}
        self.available_resolutions = ['800x600', '1024x760', '1152x1080', '1280x1024', '1920x1080', '2560x1440', '2560x1600', '1920x1440', '1792x1344', '2048x1152']
        self._location_list = []
        self._browser_list = []

    def get_profile_button_objects(self, profile_id):
        return self.profile_button_objects.get(profile_id, None)
    
    def set_profile_button_objects(self, profile_id, profile_button_objects):
        self.profile_button_objects[profile_id] = profile_button_objects
    
    def get_available_resolutions(self, profile_id):
        profile = ProfileController.get(profile_id)
        if profile and hasattr(profile, 'resolution') and profile.resolution:
            self.available_resolutions.append(profile.resolution)
        return self.available_resolutions
    
    def add_custom_resolution(self, resolution):
        self.available_resolutions.append(resolution)
    
    def add_connected_profile(self, profile_id):
        self._connected_profiles.add(profile_id)

    def remove_connected_profile(self, profile_id):
        self._connected_profiles.discard(profile_id)

    def is_profile_connected(self, profile_id):
        return profile_id in self._connected_profiles

    def get_connected_profiles(self):
        return list(self._connected_profiles)

    def set_synced(self, status):
        self._is_synced = status

    def is_synced(self):
        return self._is_synced
    

    def get_location_info(self, location_key):
        if not location_key:
            return None
        try:
            country_code, location_code = location_key.split('_')
            for location in self._location_list:
                if location.country_code == country_code and location.code == location_code:
                    return location
                    
            return None
        except (ValueError, AttributeError):
            return None

    def store_locations(self, locations):
        self._location_list = locations  

    def store_browsers(self, browsers):
        self._browser_list = browsers

    def get_browser_list(self):
        return self._browser_list


    
    def get_location_list(self):
        if self.is_synced():
            location_names = [f'{location.country_code}_{location.code}' for location in self._location_list]
            return location_names
        else:
            return []
        
    


class InstallSystemPackage(Page):
    def __init__(self, page_stack, main_window=None, parent=None):
        super().__init__("InstallPackage", page_stack, main_window, parent)
        self.btn_path = main_window.btn_path
        self.update_status = main_window
        self.package_name = ""
        self.install_command = ""
        self.manual_install_command = ""
        self.is_sync = False
        self.ui_elements = []
        self.permanent_elements = []
        self.current_distro = "debian"
        self.distro_buttons = {}
        
        self._setup_permanent_ui()
        self._setup_distro_buttons()

        self.auto_install_package_commands = {
            'all': {
                'debian': 'pkexec apt install -y bubblewrap iproute2 microsocks proxychains4 ratpoison tor wireguard xserver-xephyr',
                'arch': 'pkexec pacman -S bubblewrap iproute2 microsocks proxychains-ng tor wireguard-tools xorg-server-xephyr',
                'fedora': 'pkexec dnf -y install bubblewrap iproute proxychains4 ratpoison tor wireguard-tools xorg-x11-server-Xephyr'
            },
            'bwrap': {
                'debian': 'pkexec apt -y install bubblewrap',
                'arch': 'pkexec pacman -S bubblewrap',
                'fedora': 'pkexec dnf -y install bubblewrap'
            },
            'ip': {
                'debian': 'pkexec apt -y install iproute2',
                'arch': 'pkexec pacman -S iproute2',
                'fedora': 'pkexec dnf -y install iproute'
            },
            'microsocks': {
                'debian': 'pkexec apt -y install microsocks',
                'arch': 'pkexec pacman -S microsocks',
                'fedora': 'zenity --warning --text="An essential dependency (microsocks) is not included in your distribution\'s default repository. Please build it from source or contact support."'
            },
            'proxychains4': {
                'debian': 'pkexec apt -y install proxychains4',
                'arch': 'pkexec pacman -S proxychains-ng',
                'fedora': 'pkexec dnf -y install proxychains4'
            },
            'ratpoison': {
                'debian': 'pkexec apt -y install ratpoison',
                'arch': 'zenity --warning --text="An essential dependency (ratpoison) is not included in your distribution\'s default repository. Please build it from source or contact support."',
                'fedora': 'pkexec dnf -y install ratpoison'
            },
            'tor': {
                'debian': 'pkexec apt -y install tor',
                'arch': 'pkexec pacman -S tor',
                'fedora': 'pkexec dnf -y install tor'
            },
            'wg-quick': {
                'debian': 'pkexec apt -y install wireguard',
                'arch': 'pkexec pacman -S wireguard-tools',
                'fedora': 'pkexec dnf -y install wireguard-tools'
            },
            'Xephyr': {
                'debian': 'pkexec apt -y install xserver-xephyr',
                'arch': 'pkexec pacman -S xorg-server-xephyr',
                'fedora': 'pkexec dnf -y install xorg-x11-server-Xephyr'
            }
        }

        self.manual_install_package_commands = {
            'all': {
                'debian': 'sudo apt install -y bubblewrap iproute2 microsocks proxychains4 ratpoison tor wireguard xserver-xephyr',
                'arch': 'sudo pacman -S bubblewrap iproute2 microsocks proxychains-ng tor wireguard-tools xorg-server-xephyr',
                'fedora': 'sudo dnf -y install bubblewrap iproute proxychains4 ratpoison tor wireguard-tools xorg-x11-server-Xephyr'
            },
            'bwrap': {
                'debian': 'sudo apt -y install bubblewrap',
                'arch': 'sudo pacman -S bubblewrap',
                'fedora': 'sudo dnf -y install bubblewrap'
            },
            'ip': {
                'debian': 'sudo apt -y install iproute2',
                'arch': 'sudo pacman -S iproute2',
                'fedora': 'sudo dnf -y install iproute'
            },
            'microsocks': {
                'debian': 'sudo apt -y install microsocks',
                'arch': 'sudo pacman -S microsocks',
                'fedora': '# Package not available.'
            },
            'proxychains4': {
                'debian': 'sudo apt -y install proxychains4',
                'arch': 'sudo pacman -S proxychains-ng',
                'fedora': 'sudo dnf -y install proxychains4'
            },
            'ratpoison': {
                'debian': 'sudo apt -y install ratpoison',
                'arch': '# Package not available.',
                'fedora': 'sudo dnf -y install ratpoison'
            },
            'tor': {
                'debian': 'sudo apt -y install tor',
                'arch': 'sudo pacman -S tor',
                'fedora': 'sudo dnf -y install tor'
            },
            'wg-quick': {
                'debian': 'sudo apt -y install wireguard',
                'arch': 'sudo pacman -S wireguard-tools',
                'fedora': 'sudo dnf -y install wireguard-tools'
            },
            'Xephyr': {
                'debian': 'sudo apt -y install xserver-xephyr',
                'arch': 'sudo pacman -S xorg-server-xephyr',
                'fedora': 'sudo dnf -y install xorg-x11-server-Xephyr'
            }
        }

    def _setup_permanent_ui(self):
        self.title.setGeometry(20, 50, 300, 60)
        self.title.setText("Package Installation")
        self.title.setStyleSheet("font-size: 22px; font-weight: bold;")
        self.permanent_elements.append(self.title)
        
        self.display.setGeometry(QtCore.QRect(100, 160, 580, 435))
        self.permanent_elements.append(self.display)

    def _setup_distro_buttons(self):
        distros = ["debian", "arch", "fedora"]
        
        for i, distro in enumerate(distros):
            btn = QPushButton(self)
            btn.setGeometry(360 + i*140, 40, 120, 49)
            btn.setIcon(QIcon(os.path.join(self.btn_path, f"{distro}.png")))
            btn.setIconSize(QSize(120, 49))
            btn.setCheckable(True)
            btn.clicked.connect(lambda checked, d=distro: self.switch_distro(d))
            self.distro_buttons[distro] = btn
            self.permanent_elements.append(btn)

        self.distro_buttons[self.current_distro].setChecked(True)

    def switch_distro(self, distro):
        self.current_distro = distro
        
        for d, btn in self.distro_buttons.items():
            btn.setChecked(d == distro)
        
        if self.package_name:
            self.update_command()
            self.setup_ui()  

    def update_command(self):
        
        if self.package_name in self.auto_install_package_commands:
            if self.is_sync:
                self.install_command = self.auto_install_package_commands['tor_sync'][self.current_distro]
                self.manual_install_command = self.manual_install_package_commands['tor_sync'][self.current_distro]
            else:
                self.install_command = self.auto_install_package_commands[self.package_name][self.current_distro]
                self.manual_install_command = self.manual_install_package_commands[self.package_name][self.current_distro]
        else:
            self.install_command = ""
            self.manual_install_command = ""

    def configure(self, package_name, distro, is_sync=False):
        self.package_name = package_name
        self.current_distro = distro
        self.is_sync = is_sync
        self.update_command()
        self.setup_ui()
        return self

    def setup_ui(self):
        self.button_back.setVisible(False)
        self.button_go.setVisible(True)
        if not self.package_name:  
            return
        
        self.clear_ui()
        
        
        
        self._setup_auto_install()
        self._setup_manual_install()
        
        self._setup_status_and_nav()
        
        for element in self.ui_elements:
            element.setParent(self)
            element.setVisible(True)
            element.raise_()  

    def clear_ui(self):
        for element in self.ui_elements:
            element.setParent(None)  
            element.deleteLater()
        self.ui_elements.clear()
        
        self.command_box = None
        self.status_label = None
        self.install_button = None
        self.check_button = None

    def _setup_auto_install(self):
        auto_install_label = QLabel(f"Automatic Installation for {self.current_distro}", self)
        auto_install_label.setGeometry(80, 130, 580, 30)
        auto_install_label.setStyleSheet("font-size: 18px; font-weight: bold;")
        auto_install_label.setVisible(True)
        self.ui_elements.append(auto_install_label)
        
        auto_install_desc = QLabel("Click the button below to automatically install the missing packages:", self)
        auto_install_desc.setStyleSheet("font-size: 14px; font-weight: bold;")
        auto_install_desc.setGeometry(80, 170, 650, 30)
        auto_install_desc.setVisible(True)
        self.ui_elements.append(auto_install_desc)

        self.install_button = QPushButton(self)
        self.install_button.setGeometry(135, 210, 100, 40)
        self.install_button.setIcon(QIcon(os.path.join(self.btn_path, "install.png")))
        self.install_button.setIconSize(self.install_button.size())
        self.install_button.clicked.connect(self.install_package)
        self.install_button.setVisible(True)
        self.ui_elements.append(self.install_button)

        if self.current_distro == 'arch':
            auto_install_label.setGeometry(50, 110, 580, 30)
            auto_install_desc.setGeometry(50, 140, 650, 30)
            
            self.install_button.setGeometry(150, 185, 100, 40)

            self.check_button = QPushButton(self)
            self.check_button.setGeometry(270, 185, 100, 40)
            self.check_button.setIcon(QIcon(os.path.join(self.btn_path, "check.png")))
            self.check_button.setIconSize(self.check_button.size())
            self.check_button.clicked.connect(self.check_package)
            self.check_button.setVisible(True)
            self.ui_elements.append(self.check_button)

    def _setup_manual_install(self):
        if self.current_distro != 'arch':
            manual_install_label = QLabel(f"Manual Installation for {self.current_distro}", self)
            manual_install_label.setGeometry(80, 290, 650, 30)
            manual_install_label.setStyleSheet("font-size: 18px; font-weight: bold;")
            manual_install_label.setVisible(True)
            self.ui_elements.append(manual_install_label)

            manual_install_desc = QLabel("Run this command in your terminal:", self)
            manual_install_desc.setStyleSheet("font-size: 14px; font-weight: bold;")
            manual_install_desc.setGeometry(80, 330, 380, 30)
            manual_install_desc.setVisible(True)
            

            self.ui_elements.append(manual_install_desc)

        

        self.command_box = QLabel(self.manual_install_command, self)

        self.command_box.setGeometry(80, 370, 380, 40)

        if self.current_distro == 'arch':
            self.command_box.setGeometry(50, 280, 380, 40)

        metrics = self.command_box.fontMetrics()
        text_width = metrics.horizontalAdvance(self.manual_install_command) + 100
        available_width = self.command_box.width() - 20
        font_size = 18
        MIN_FONT_SIZE = 10
        while text_width > available_width:
            if font_size <= MIN_FONT_SIZE:
                break
            font_size -= 1
            text_width -= 10
        
        self.command_box.setStyleSheet(f"""
                background-color: #2b2b2b;
                color: #ffffff;
                padding: 10px;
                border-radius: 5px;
                font-family: monospace;
                font-size: {font_size}px;
            """)
        
        self.command_box.mousePressEvent = lambda _: self.copy_command()
        self.command_box.setVisible(True)
        self.ui_elements.append(self.command_box)

        if self.current_distro == 'arch':
            # Pacman commands section
            pacman_label = QLabel("Pacman Installation:", self)
            pacman_label.setGeometry(50, 240, 650, 30)
            pacman_label.setStyleSheet("font-size: 18px; font-weight: bold; color: #00ffff;")
            pacman_label.setVisible(True)
            self.ui_elements.append(pacman_label)

            # AUR commands section
            aur_label = QLabel("AUR / Yay Installation:", self)
            aur_label.setGeometry(50, 350, 300, 30)
            aur_label.setStyleSheet("font-size: 18px; font-weight: bold; color: #00ffff;")
            self.ui_elements.append(aur_label)

            # Yay command
            self.yay_command_box = QLabel("sudo yay -S ratpoison", self)
            self.yay_command_box.setGeometry(50, 390, 300, 40)
            self._setup_command_box_style(self.yay_command_box)
            self.yay_command_box.mousePressEvent = lambda _: self.copy_command("sudo yay -S ratpoison", self.yay_command_box)
            self.ui_elements.append(self.yay_command_box)

            # Manual AUR command
            aur_command = "git clone https://aur.archlinux.org/ratpoison.git\ncd ratpoison\nmakepkg -si --skippgpcheck"
            self.aur_command_box = QLabel(aur_command, self)
            self.aur_command_box.setGeometry(370, 390, 380, 60)
            self._setup_command_box_style(self.aur_command_box)
            self.aur_command_box.setWordWrap(True)
            self.aur_command_box.mousePressEvent = lambda _: self.copy_command(aur_command, self.aur_command_box)
            self.ui_elements.append(self.aur_command_box)


        else:
            self.command_box = QLabel(self.manual_install_command, self)
            self.command_box.setGeometry(80, 370, 380, 40)
            metrics = self.command_box.fontMetrics()
            text_width = metrics.horizontalAdvance(self.manual_install_command) + 100
            available_width = self.command_box.width() - 20
            font_size = 18
            MIN_FONT_SIZE = 10
            while text_width > available_width:
                if font_size <= MIN_FONT_SIZE:
                    break
                font_size -= 1
                text_width -= 10
            
            self.command_box.setStyleSheet(f"""
                background-color: #2b2b2b;
                color: #ffffff;
                padding: 10px;
                border-radius: 5px;
                font-family: monospace;
                font-size: {font_size}px;
            """)
            
            self.command_box.mousePressEvent = lambda _: self.copy_command()
            self.command_box.setVisible(True)
            self.ui_elements.append(self.command_box)


    def _setup_command_box_style(self, command_box):
        metrics = command_box.fontMetrics()
        text_width = metrics.horizontalAdvance(command_box.text()) + 100
        available_width = command_box.width() - 20
        font_size = 18
        MIN_FONT_SIZE = 10
        while text_width > available_width:
            if font_size <= MIN_FONT_SIZE:
                break
            font_size -= 1
            text_width -= 10
        
        command_box.setStyleSheet(f"""
            background-color: #2b2b2b;
            color: #ffffff;
            padding: 10px;
            border-radius: 5px;
            font-family: monospace;
            font-size: {font_size}px;
        """)
        command_box.setVisible(True)

    def copy_yay_command(self):
        clipboard = QApplication.clipboard()
        clipboard.setText("sudo yay -S ratpoison")
        
        original_style = self.yay_command_box.styleSheet()
        self.yay_command_box.setStyleSheet(original_style + "background-color: #27ae60;")
        QTimer.singleShot(200, lambda: self.yay_command_box.setStyleSheet(original_style))
        self.update_status.update_status("Yay command copied to clipboard")

    def _setup_status_and_nav(self):
        if self.current_distro != 'arch':
            self.check_button = QPushButton(self)
            self.check_button.setGeometry(130, 430, 100, 40)
            self.check_button.setIcon(QIcon(os.path.join(self.btn_path, "check.png")))
            self.check_button.setIconSize(self.check_button.size())
            self.check_button.clicked.connect(self.check_package)
            self.ui_elements.append(self.check_button)
        
        self.button_go.clicked.connect(self.go_next)
        self.button_back.clicked.connect(self.go_next)
        
        self.status_label = QLabel("", self)
        self.status_label.setGeometry(300, 430, 250, 40)
        if self.current_distro == 'arch':
            self.status_label.setGeometry(450, 185, 250, 40)
        self.ui_elements.append(self.status_label)

    def copy_command(self, command=None, command_box=None):
        if command_box is None:
            command_box = self.command_box

        clipboard = QApplication.clipboard()
        if command:
            clipboard.setText(command)
        else:
            clipboard.setText(self.manual_install_command)
        
        original_style = command_box.styleSheet()
        command_box.setStyleSheet(original_style + "background-color: #27ae60;")
        QTimer.singleShot(200, lambda: command_box.setStyleSheet(original_style))
        self.update_status.update_status("Command copied to clipboard")
    def install_package(self):
        if not self.install_command:
            self.update_status.update_status(f"Installation not supported for {self.current_distro}")
            return
        
        if subprocess.getstatusoutput('pkexec --help')[0] == 127:
            self.update_status.update_status("polkit toolkit is not installed")
            self.install_button.setDisabled(True)
            return
        
        self.worker_thread = WorkerThread('INSTALL_PACKAGE', 
                                        package_command=self.install_command,
                                        package_name=self.package_name)
        self.worker_thread.text_output.connect(self.update_status.update_status)
        self.worker_thread.finished.connect(self.installation_complete)
        self.worker_thread.start()

    def installation_complete(self, success):
        if success:
            self.check_package()

    def check_package(self):
        try:
            if self.package_name.lower() == 'all':
                packages = ['bwrap', 'ip', 'microsocks', 'proxychains4', 'ratpoison', 'tor', 'Xephyr', 'wg']
                for package in packages:
                    if subprocess.getstatusoutput(f'{package} --help')[0] == 127:
                        self.status_label.setText(f"{package} is not installed")
                        self.status_label.setStyleSheet("color: red;")
                        return
                self.status_label.setText("All packages installed!")
                self.status_label.setStyleSheet("color: green;")
            elif self.package_name.lower() == 'wireguard':
                self.install_name = 'wg'
            elif self.package_name.lower() == 'bubblewrap':
                self.install_name = 'bwrap'
            elif self.package_name.lower() == 'xserver-xephyr':
                self.install_name = 'Xephyr'
            else:
                self.install_name = self.package_name
                if subprocess.getstatusoutput(f'{self.install_name.lower()} --help')[0] == 127:
                    self.status_label.setText(f"{self.package_name} is not installed")
                    self.status_label.setStyleSheet("color: red;")
                else:
                    self.status_label.setText(f"{self.package_name} is installed!")
                    self.status_label.setStyleSheet("color: green;")
        except Exception:
            self.status_label.setText("Check failed")
            self.status_label.setStyleSheet("color: red;")

    def go_next(self):
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage)))

class ProtocolPage(Page):
    def __init__(self, page_stack, main_window=None, parent=None):
        super().__init__("Protocol", page_stack,main_window, parent)
        self.main_window = main_window
        self.selected_protocol = None
        self.btn_path = main_window.btn_path
        self.selected_protocol_icon = None        
        self.connection_manager = main_window.connection_manager
        self.button_back.setVisible(True)
        self.update_status = main_window
        self.button_go.clicked.connect(self.go_selected)
        self.coming_soon_label = QLabel("Coming soon", self)
        self.coming_soon_label.setGeometry(210, 50, 200, 40)
        self.coming_soon_label.setStyleSheet("font-size: 22px;")

        self.coming_soon_label.setVisible(False)
        self.title.setGeometry(585, 40, 185, 40); self.title.setText("Pick a Protocol")
        self.display.setGeometry(QtCore.QRect(0, 50, 580, 435))#relacion 4:3        
        self.create_interface_elements()
        

    def create_interface_elements(self):
        self.buttonGroup = QButtonGroup(self)
        self.buttons = []
        for j, (object_type,icon_name, page_class, geometry) in enumerate([
            (QPushButton,"wireguard", WireGuardPage, (585, 90,185,75)),
            (QPushButton,"residential", ResidentialPage, (585, 90+30+75,185,75)),
            (QPushButton,"hidetor", HidetorPage, (585, 90+30+75+30+75,185,75))
        ]):
            boton = object_type(self)
            boton.setGeometry(*geometry)
            boton.setIconSize(boton.size())
            boton.setCheckable(True)
            boton.setDisabled(True)
            boton.setIcon(QIcon(os.path.join(self.btn_path, f"{icon_name}_button.png"))) 
            self.buttons.append(boton)
            self.buttonGroup.addButton(boton, j)
            boton.clicked.connect(lambda _, page=page_class, protocol=icon_name: self.show_protocol(page, protocol))
            
    def enable_protocol_buttons(self):
        for button in self.buttons:
            button.setDisabled(False)

    def update_swarp_json(self):
        self.update_status.write_data({"protocol": self.selected_protocol_icon})

    def show_protocol(self, page_class, protocol):
        self.update_status.clear_data()
        self.display.setPixmap(QPixmap(os.path.join(self.btn_path, f"{protocol}.png")).scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio))
        self.selected_protocol_icon = protocol
        self.selected_page_class = page_class

        if protocol in ["wireguard", "hidetor"]:
            self.button_go.setVisible(True)
            self.coming_soon_label.setVisible(False)

        else:
            self.button_go.setVisible(False)
            self.coming_soon_label.setVisible(True)
        self.update_swarp_json()

    def go_selected(self):
        if self.selected_page_class:
            selected_page = self.selected_page_class
            if selected_page == HidetorPage:
                self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(HidetorPage)))
            else:
                self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(selected_page)))            

            self.display.clear()
            for boton in self.buttons:
                boton.setChecked(False)
            
            self.button_go.setVisible(False)

    def find_menu_page(self):
        for i in range(self.page_stack.count()):
            page = self.page_stack.widget(i)
            if isinstance(page, MenuPage):
                return page
        return None

class WireGuardPage(Page):
    browser_label_created = False  # Variable de clase para verificar si el QLabel ya se ha creado
    def __init__(self, page_stack, main_window, parent=None):
        super().__init__("Wireguard", page_stack, main_window, parent)
        self.buttonGroup = QButtonGroup(self)
        self.btn_path = main_window.btn_path  
        self.update_status = main_window
        self.buttons = []
        self.selected_protocol = None
        self.selected_protocol_icon = None        
        self.button_back.setVisible(True)
        self.button_go.clicked.connect(self.go_selected)
        self.additional_labels=[ ]
        self.title.setGeometry(585, 40, 185, 40); self.title.setText("Pick a Protocol")
        #self.display.setGeometry(QtCore.QRect(15, 50, 550, 411))#relacion 4:3        
        #self.display.setPixmap(QPixmap(os.path.join(self.btn_path, f"{wireguard}.png")).scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio))
        self.sudo_warning = QLabel("Requires Sudo", self)
        self.sudo_warning.setGeometry(165, 90, 300, 40)
        self.sudo_warning.setStyleSheet("""
            font-size: 24px;
            font-weight: bold;
            color: cyan;
        """)
        self.sudo_warning.setVisible(False)

        self.create_interface_elements()

    def create_interface_elements(self):


        for j, (object_type, icon_name, page_class, geometry) in enumerate([
            (QPushButton, "system-wide", LocationPage, (585, 90, 185, 75)),
            (QPushButton, "browser-only", LocationPage, (585, 90+30+75+30+75, 185, 75)),
            (QLabel, None, None, (570, 170, 210, 105)),
            (QLabel, None, None, (570, 385, 210, 115))
        ]):
            if object_type == QPushButton:
                boton = object_type(self)
                boton.setGeometry(*geometry)
                boton.setIconSize(boton.size())
                boton.setCheckable(True)
                boton.setIcon(QIcon(os.path.join(self.btn_path, f"{icon_name}.png"))) 
                self.buttons.append(boton)
                self.buttonGroup.addButton(boton, j)
                # Usamos argumentos por defecto para capturar los valores
                boton.clicked.connect(lambda _, page=page_class, protocol=icon_name: self.show_protocol(page, protocol))
            elif object_type == QLabel:
                label = object_type(self)
                label.setGeometry(*geometry)
                label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                label.setWordWrap(True)
                if geometry == (570, 170, 210, 105):
                    text1 = "VPN for the whole PC\n($1/month - 1 location)"
                    label.setText(text1)
                elif geometry == (570, 385, 210, 115):
                    text2 = "1 Profile.\n1 Country.\nIsolated VPN for just the browser\n(1$/month)"
                    label.setText(text2)

            # Conexión de la señal clicked del botón con la función correspondiente

    def update_swarp_json(self):
        inserted_data = {
            "protocol": "wireguard",
            "connection": self.selected_protocol_icon
        }
        self.update_status.write_data(inserted_data)
 
        
    def show_protocol(self, page_class, protocol):
        if protocol == "browser-only":
            self.sudo_warning.setVisible(False)
        else:
            self.sudo_warning.setVisible(True)
        self.protocol_chosen = protocol
        self.selected_protocol_icon = protocol
        self.selected_page_class = page_class

        self.button_go.setVisible(True)
        self.update_swarp_json()
        # Eliminar labels adicionales anteriores
        for label in self.additional_labels:
            label.deleteLater()
        self.additional_labels.clear()
        if protocol == "system-wide":


                # Crear QLabel con la imagen os.path.join(self.btn_path, "browser only.png") detrás del label_principal
                label_principal = QLabel(self)
                label_principal.setGeometry(0, 60, 540, 460)  # Geometría según necesidades
                pixmap = QPixmap(os.path.join(self.btn_path, "wireguard.png"))
                label_principal.setPixmap(pixmap)
                label_principal.show()
                label_principal.setScaledContents(True)
                label_principal.lower()  # Colocar label_background debajo del label_principal
                self.additional_labels.append(label_principal)

        if protocol == "browser-only":
                # Crear QLabel principal
                label_principal = QLabel(self)
                label_principal.setGeometry(0, 80, 530, 380)
                pixmap = QPixmap(os.path.join(self.btn_path, "wireguard.png"))
                label_principal.setPixmap(pixmap)
                label_principal.show()
                label_principal.setScaledContents(True)

                label_principal.show()
                self.additional_labels.append(label_principal)

                # Crear QLabel con la imagen os.path.join(self.btn_path, "browser only.png") detrás del label_principal
                label_background = QLabel(self)
                label_background.setGeometry(0, 60, 540, 460)  # Geometría según necesidades
                pixmap = QPixmap(os.path.join(self.btn_path, "browser only.png"))
                label_background.setPixmap(pixmap)
                label_background.show()
                label_background.setScaledContents(True)
                label_background.lower()  # Colocar label_background debajo del label_principal
                self.additional_labels.append(label_background)

    def go_selected(self):
        if self.selected_page_class:
            if self.protocol_chosen == 'system-wide':
                self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(LocationPage)))
            else:
                selected_page = self.selected_page_class
                self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(selected_page)))            

            self.display.clear()
            for boton in self.buttons:
                boton.setChecked(False)
            
            self.button_go.setVisible(False)
    def reverse(self):
        self.display.clear()
        for boton in self.buttons:
            boton.setChecked(False)
        
        self.button_go.setVisible(False)
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(ProtocolPage)))
class lokinetPage(Page):
    def __init__(self, page_stack, parent=None):
        super().__init__("Lokinet", page_stack, parent)
        self.create_interface_elements()
    def create_interface_elements(self):
        pass
class OpenPage(Page):
    def __init__(self, page_stack, parent=None):
        super().__init__("Opne", page_stack, parent)
        pass


class HidetorPage(Page):
    def __init__(self, page_stack, main_window, parent=None):
        super().__init__("HideTor", page_stack, main_window, parent)
        self.selected_location_icon = None
        self.connection_manager = main_window.connection_manager
        self.update_status = main_window
        self.button_next.clicked.connect(self.go_selected)
        self.button_reverse.setVisible(True)
        self.button_reverse.clicked.connect(self.reverse)
        self.display.setGeometry(QtCore.QRect(5, 10, 390, 520))
        self.title.setGeometry(395, 40, 380, 40); self.title.setText("Pick a location")
        

    def create_interface_elements(self, available_locations):
        self.buttonGroup = QButtonGroup(self)
        self.buttons = []

        for j, (object_type, icon_name, geometry) in enumerate(available_locations):
            boton = object_type(self)
            boton.setGeometry(*geometry)
            boton.setIconSize(boton.size())
            boton.setCheckable(True)
            locations = self.connection_manager.get_location_info(icon_name)
            if icon_name == 'my_14':
               boton.setVisible(False)
            icon_path = os.path.join(self.btn_path, f"button_{icon_name}.png")
            boton.setIcon(QIcon(icon_path))
            fallback_path = os.path.join(self.btn_path, "default_location_button.png")
            provider = locations.operator.name if locations and hasattr(locations, 'operator') else None
            if boton.icon().isNull():
                if locations and hasattr(locations, 'country_name'):
                    base_image = LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', fallback_path, provider)
                    boton.setIcon(QIcon(base_image))
                else:
                    base_image = LocationPage.create_location_button_image('', fallback_path, provider)
                    boton.setIcon(QIcon(base_image))
            else:
                if locations and hasattr(locations, 'country_name'):
                    base_image = LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', fallback_path, provider, icon_path)
                    boton.setIcon(QIcon(base_image))
                else:
                    base_image = LocationPage.create_location_button_image('', fallback_path, provider, icon_path)
                    boton.setIcon(QIcon(base_image))
            self.buttons.append(boton)
            self.buttonGroup.addButton(boton, j)
            boton.location_icon_name = icon_name
            boton.setCursor(QtCore.Qt.CursorShape.PointingHandCursor)
            boton.clicked.connect(lambda checked, loc=icon_name: self.show_location(loc))

    def update_swarp_json(self):
        inserted_data = {
            "location": self.selected_location_icon,
            "connection": "tor"
        }
        self.update_status.write_data(inserted_data)

    def show_location(self, location):
        tor_hide_img = f'hdtor_{location}'
        self.display.setPixmap(QPixmap(os.path.join(self.btn_path, f"{tor_hide_img}.png")).scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio))
        self.selected_location_icon = location  
        self.button_next.setVisible(True)
        self.update_swarp_json()
        

    def reverse(self):
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(ProtocolPage)))

    def go_selected(self):
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(BrowserPage)))

    def show_location_verification(self, location_icon_name):
        verification_page = LocationVerificationPage(self.page_stack, self.update_status, location_icon_name, self)
        self.page_stack.addWidget(verification_page)
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(verification_page))

class ResidentialPage(Page):
    def __init__(self, page_stack, main_window, parent=None):
        super().__init__("Wireguard", page_stack, main_window, parent)
        self.title.setGeometry(585, 40, 185, 40); self.title.setText("Pick a Protocol")
        self.update_status = main_window
        self.connection_choice = None
        self.button_reverse.setVisible(True)
        self.button_reverse.clicked.connect(self.reverse)
        self.button_go.clicked.connect(self.go_selected)

        self.display_1 = QLabel(self)
        self.display_1.setGeometry(QtCore.QRect(15, 50, 550, 465))#relacion 4:3        
        self.display_1.setPixmap(QPixmap(os.path.join(self.btn_path, "browser only.png")))
        self.label = QLabel(self)
        self.label.setGeometry(440, 370, 86,130)
        self.label.setPixmap(QPixmap(os.path.join(self.btn_path, "tor 86x130.png")))
        self.label.hide()                



    def showEvent(self, event):
        super().showEvent(event)
        self.create_interface_elements()


    def create_interface_elements(self):
        self.buttonGroup = QButtonGroup(self)
        self.buttons = []

        for j, (object_type, icon_name, page_class, geometry) in enumerate([
            (QPushButton, "tor", self.set_connection_choice('tor'), (585, 90, 185, 75)),
            (QPushButton, "just proxy", self.set_connection_choice('just proxy'), (585, 90+30+75+30+75, 185, 75)),
            (QLabel, None, None, (570, 170, 210, 105)),
            (QLabel, None, None, (570, 385, 210, 115))
        ]):
            if object_type == QPushButton:
                boton = object_type(self)
                boton.setGeometry(*geometry)
                boton.setIconSize(boton.size())
                boton.setCheckable(True)
                boton.setIcon(QIcon(os.path.join(self.btn_path, f"{icon_name}_button.png")))
                self.buttons.append(boton)
                self.buttonGroup.addButton(boton, j)
                
                boton.show()

                # Conectar el botón a la función show_residential
                boton.clicked.connect(lambda checked,page=page_class, name=icon_name: self.show_residential(name,page))
            elif object_type == QLabel:
                label = object_type(self)
                label.setGeometry(*geometry)
                label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                label.setWordWrap(True)
                label.show()
                if geometry == (570, 170, 210, 105):
                    text1 = "Connect to tor first\nThen the residential proxy\nThis hides Tor from websites"
                    label.setText(text1)
                elif geometry == (570, 385, 210, 115):
                    text2 = "Connect directly\nTo the Proxy\nin a browser\nThis has no encryption"
                    label.setText(text2)


    def set_connection_choice(self, connection_choice):
        pass
        

    def show_residential(self, icon_name,page_class):
        self.connection_choice = icon_name
        self.selected_page_class = page_class

        if icon_name == "tor":
            self.label.show()
        if icon_name == "just proxy":
            self.label.hide()

        self.button_go.setVisible(True)

        
    def go_selected(self):
        self.update_swarp_json(self.connection_choice)
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(HidetorPage)))
        self.button_go.setVisible(False)

    def update_swarp_json(self, icon_name):
        inserted_data = {
            "connection": icon_name
        }
        self.update_status.write_data(inserted_data)


    def reverse(self):
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(ProtocolPage)))
        
class TorPage(Page):
    def __init__(self, page_stack, main_window, parent=None):
        super().__init__("TorPage", page_stack, main_window, parent)
        self.update_status = main_window
        self.button_back.setVisible(True)
        self.title.setGeometry(585, 40, 185, 40); self.title.setText("Pick a Country")       
        self.display.setGeometry(QtCore.QRect(0, 100, 540, 405))#relacion 4:3
        self.display0=QLabel(self)
        self.display0.setGeometry(QtCore.QRect(0, 50, 600, 465))#relacion 4:3        
        self.display0.setPixmap(QPixmap(os.path.join(self.btn_path, "browser only.png")))
        self.display0.lower()  # Colocar display2 debajo de otros widgets

        self.button_go.clicked.connect(self.go_selected)

        self.button_reverse.setVisible(True)
        self.button_reverse.clicked.connect(self.reverse_selected)



        self.label = QLabel(self)
        self.label.setGeometry(440, 370, 86,130)
        pixmap = QPixmap(os.path.join(self.btn_path, "tor 86x130.png"))  # Reemplaza "ruta/a/la/imagen.png" por la ruta de tu imagen
        self.label.setPixmap(pixmap)
                
        self.label.hide()
        
    def showEvent(self, event):
        super().showEvent(event)
        self.extraccion()

    def extraccion(self):
        self.data_profile = {}
        profile = self.update_status.read_data()
        profile_1 = profile.get('Profile_1')
        self.verificate()

    def verificate(self, value= 'tor'):
        # Verificar el valor de key
        if value == "just proxy":
            self.display0.show() 
            self.label.hide()  
        elif value == "tor":
            self.display0.show()
            self.label.show()  # Colocar display2 debajo de otros widgets

        else:
            pass
        self.buttonGroup = QButtonGroup(self)
        self.buttons = []
        '''
        for j, (object_type, icon_name, geometry) in enumerate([
            (QPushButton, "brazil", (585, 90, 185, 75)),
            (QPushButton, "germany", (585, 170, 185, 75)),
            (QPushButton, "eeuu", (585, 250, 185, 75)),
            (QPushButton, "united kingdom", (585, 330, 185, 75)),
            (QPushButton, "hong kong", (585, 410, 185, 75))
        ]):
            boton = object_type(self)
            boton.setGeometry(*geometry)
            boton.setIconSize(boton.size())
            boton.setCheckable(True)
            boton.setIcon(QIcon(os.path.join(self.btn_path, f"{{icon_name}}_button.png")))
            self.buttons.append(boton)
            self.buttonGroup.addButton(boton, j)
            boton.clicked.connect(lambda _, dimentions=icon_name: self.show_dimentions(dimentions))
            
            boton.show()
        '''
    def show_dimentions(self, dimentions):
        self.display.setPixmap(QPixmap(os.path.join(self.btn_path, f"{dimentions} garaje.png")).scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio))
        self.selected_dimentions_icon = dimentions
        self.button_go.setVisible(True)
        self.update_swarp_json() 

    def update_swarp_json(self):
        inserted_data = {
            "country_garaje": self.selected_dimentions_icon
        }
        self.update_status.write_data(inserted_data)


    def reverse_selected(self):
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(ResidentialPage)))    

    def go_selected(self):
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(BrowserPage)))            


        self.display.clear()
        for boton in self.buttons:
            boton.setChecked(False)
        
        self.button_go.setVisible(False)


class TorLocationPage(Page):
    def __init__(self, page_stack, parent=None):
        super().__init__("TorPage", page_stack, parent)
        pass
class ConnectionPage(Page):
    def __init__(self, page_stack, parent=None):
        super().__init__("Connection", page_stack, parent)

        self.create_interface_elements()


    def create_interface_elements(self):
        self.display.setGeometry(QtCore.QRect(5, 50, 390, 430))
        self.title.setGeometry(QtCore.QRect(465, 40, 300, 20))
        self.title.setText("Pick a TOR") 
        
        labels_info = [
            ("server",  None,   (410, 115)),
            ("",        "rr2",  (560, 115)),
            ("port",    None,   (410, 205)),
            ("",        "rr2",  (560, 205)),
            ("username",None,   (410, 295)),
            ("",        "rr2",  (560, 295)),
            ("password",None,   (410, 385)),
            ("",        "rr2",  (560, 385))
        ]

        for j, (text, image_name, position) in enumerate(labels_info):
            label = QLabel(self)
            label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
            if image_name:  # Si hay un nombre de imagen, usar el tamaño predeterminado (220x50)
                label.setGeometry(position[0], position[1], 220, 50)
            else:  # Si no hay una imagen, usar el tamaño personalizado (130x30)
                label.setGeometry(position[0], position[1], 140, 50)
            label.setStyleSheet("background-color: rgba(255, 255, 255, 51); padding: 3px;")

            if image_name:  # Si hay un nombre de imagen, crear una QLabel con la imagen
                pixmap = QPixmap(os.path.join(self.btn_path, f"{image_name}.png"))
                label.setPixmap(pixmap)
                label.setScaledContents(True)  # Escalar contenido para ajustarlo al tamaño del QLabel
            else:  # Si no hay una imagen, crear una QLabel con el texto
                label.setText(text)
class LocationPage(Page):
    def __init__(self, page_stack, main_window, parent=None):
        super().__init__("Location", page_stack, main_window, parent)
        self.selected_location_icon = None
        self.update_status = main_window
        self.button_reverse.setVisible(True)
        self.connection_manager = main_window.connection_manager
        self.button_reverse.clicked.connect(self.reverse)
        self.display.setGeometry(QtCore.QRect(5, 10, 390, 520))
        self.title.setGeometry(395, 40, 380, 40); self.title.setText("Pick a location")
        
        self.initial_display = QLabel(self)
        self.initial_display.setGeometry(5, 22, 355, 485)  
        self.initial_display.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.initial_display.setWordWrap(True)
        
        self.verification_button = QPushButton("Verification", self)
        self.verification_button.setGeometry(330, 40, 130, 40)
        self.verification_button.setStyleSheet(f"""
            QPushButton {{
                background-color: rgba(30, 30, 35, 0.9);
                border: 1px solid rgba(100, 100, 120, 0.6);
                border-radius: 5px;
                color: rgb(255, 255, 255);
                font-size: 14px;
                padding: 5px 10px;
            }}
            QPushButton:hover {{
                background-color: rgba(50, 50, 60, 0.95);
                border: 1px solid rgba(150, 150, 180, 0.8);
            }}
            QPushButton:disabled {{
                background-color: rgba(20, 20, 25, 0.5);
                border: 1px solid rgba(60, 60, 70, 0.4);
                opacity: 0.4;
            }}
        """)
        self.verification_button.setCursor(QtCore.Qt.CursorShape.PointingHandCursor)
        self.verification_button.setEnabled(False)
        self.verification_button.show()

    def showEvent(self, event):
        super().showEvent(event)
        self.button_next.setVisible(False)
        for button in self.buttons:
            button.setChecked(False)
        if hasattr(self, 'verification_button'):
            self.verification_button.setEnabled(False)

    def create_interface_elements(self, available_locations):
        self.buttonGroup = QButtonGroup(self)
        self.buttons = []
        
        for j, (object_type, icon_name, geometry) in enumerate(available_locations):
            boton = object_type(self)
            boton.setGeometry(*geometry)    
            boton.setIconSize(boton.size())
            boton.setCheckable(True)

            locations = self.connection_manager.get_location_info(icon_name)
            icon_path = os.path.join(self.btn_path, f"button_{icon_name}.png")
            boton.setIcon(QIcon(icon_path))
            fallback_path = os.path.join(self.btn_path, "default_location_button.png")
            provider = locations.operator.name if locations and hasattr(locations, 'operator') else None
            if boton.icon().isNull():
                if locations and hasattr(locations, 'country_name'):
                    base_image = LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', fallback_path, provider)
                    boton.setIcon(QIcon(base_image))
                else:
                    base_image = LocationPage.create_location_button_image('', fallback_path, provider)
                    boton.setIcon(QIcon(base_image))
            else:
                if locations and hasattr(locations, 'country_name'):
                    base_image = LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', fallback_path, provider, icon_path)
                    boton.setIcon(QIcon(base_image))
                else:
                    base_image = LocationPage.create_location_button_image('', fallback_path, provider, icon_path)
                    boton.setIcon(QIcon(base_image))

            self.buttons.append(boton)
            self.buttonGroup.addButton(boton, j)
            boton.location_icon_name = icon_name
            boton.setCursor(QtCore.Qt.CursorShape.PointingHandCursor)
            boton.clicked.connect(lambda checked, loc=icon_name: self.show_location(loc))

    def update_swarp_json(self, get_connection=False):
        profile_data = self.update_status.read_data()
        self.connection_type = profile_data.get("connection", "")
        if get_connection:
            return self.connection_type
        inserted_data = {
            "location": self.selected_location_icon
        }
        self.update_status.write_data(inserted_data)


    def show_location(self, location):
        self.initial_display.hide()
        self.display.setPixmap(QPixmap(os.path.join(self.btn_path, f"icon_{location}.png")).scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio))
        self.selected_location_icon = location  
        self.button_next.setVisible(True)
        self.button_next.clicked.connect(self.go_selected)  
        self.update_swarp_json()
        
        try:
            self.verification_button.clicked.disconnect()
        except TypeError:
            pass
        
        self.verification_button.clicked.connect(lambda: self.show_location_verification(location))
        self.verification_button.setEnabled(True)


    def reverse(self):
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(ProtocolPage)))

    def go_selected(self):
        if self.connection_type == "system-wide":
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(ResumePage)))
        else:
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(BrowserPage)))

    def show_location_verification(self, location_icon_name):
        verification_page = LocationVerificationPage(self.page_stack, self.update_status, location_icon_name, self)
        self.page_stack.addWidget(verification_page)
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(verification_page))

    @staticmethod
    def create_location_button_image(location_name, fallback_image_path, provider=None, existing_icon_path=None):
        if existing_icon_path:
            base_image = QPixmap(existing_icon_path)
            if base_image.isNull():
                base_image = QPixmap(fallback_image_path)
            draw_location_text = False
        else:
            base_image = QPixmap(fallback_image_path)
            draw_location_text = True
        
        if base_image.isNull():
            return base_image
        
        painter = QPainter(base_image)
        try:
            if draw_location_text:
                font_size = 12
                app_font = QApplication.font()
                app_font.setPointSize(font_size)
                app_font.setWeight(QFont.Weight.Bold)
                text_length = len(location_name)

                if text_length <= 10:
                    font_stretch = 100
                    text_width_scale = 1.1
                    text_height_scale = 1.4
                elif text_length <= 15:
                    font_stretch = 90
                    text_width_scale = 1.0
                    text_height_scale = 2
                else:
                    font_stretch = 100
                    text_width_scale = 1.1
                    text_height_scale = 4.5
                app_font.setStretch(font_stretch)
                painter.setFont(app_font)
                painter.setPen(QColor(0, 255, 255))
                
                text_rect = painter.fontMetrics().boundingRect(location_name)
                max_width = 110

                while text_rect.width() > max_width:
                    font_size -= 1
                    app_font.setPointSize(font_size)
                    app_font.setWeight(QFont.Weight.Bold)
                    painter.setFont(app_font)
                    text_rect = painter.fontMetrics().boundingRect(location_name)

                x = ((base_image.width() - text_rect.width()) // 2) - 30
                y = ((base_image.height() + text_rect.height()) // 2) - 15

                from PyQt6.QtGui import QTransform
                transform = QTransform()
                transform.scale(text_width_scale, text_height_scale)
                painter.setTransform(transform)

                x_scaled = int(x / text_width_scale)
                y_scaled = int(y / text_height_scale)

                shadow_offset = 1
                painter.setPen(QColor(0, 0, 0))
                painter.drawText(x_scaled + shadow_offset, y_scaled + shadow_offset, location_name)

                painter.setPen(QColor(0, 255, 255))
                painter.drawText(x_scaled, y_scaled, location_name)

                painter.setTransform(QTransform())

            if provider:
                provider_label_font = QApplication.font()
                provider_label_font.setPointSize(8)
                provider_label_font.setWeight(QFont.Weight.Bold)
                painter.setFont(provider_label_font)
                painter.setPen(QColor(128, 128, 128))

                provider_label = "Provider:"
                provider_label_rect = painter.fontMetrics().boundingRect(provider_label)
                
                provider_text_font = QApplication.font()
                provider_text_font.setPointSize(7)
                provider_text_font.setWeight(QFont.Weight.Normal)
                painter.setFont(provider_text_font)
                provider_text_rect = painter.fontMetrics().boundingRect(provider)

                provider_x = ((base_image.width() - max(provider_label_rect.width(), provider_text_rect.width())) // 2) - 30
                provider_y = 50
                px = int(provider_x)
                py = int(provider_y)
                
                painter.setFont(provider_label_font)
                painter.drawText(px + 20, py + 2, provider_label)
                painter.setFont(provider_text_font)
                painter.drawText(px + 5, py + provider_label_rect.height() + 2, provider)
        finally:
            painter.end()
        return base_image

class BrowserPage(Page):
    def __init__(self, page_stack, main_window, parent=None):
        super().__init__("Browser", page_stack, main_window, parent)
        self.btn_path = main_window.btn_path
        self.update_status = main_window
        self.selected_browser_icon = None
        self.display.setGeometry(QtCore.QRect(5, 10, 390, 520))
        self.title.setGeometry(395, 40, 380, 40)
        self.title.setText("Pick a Browser")       
        self.button_back.setVisible(True)

    def create_interface_elements(self, available_browsers):
        self._setup_scroll_area()
        button_widget = self._create_button_widget()
        self._populate_button_widget(button_widget, available_browsers)
        self.scroll_area.setWidget(button_widget)

    def _setup_scroll_area(self):
        self.scroll_area = QScrollArea(self)
        self.scroll_area.setGeometry(400, 90, 385, 400)
        self.scroll_area.setWidgetResizable(True)
        self.scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        self._apply_scroll_area_style()

    def _apply_scroll_area_style(self):
        self.scroll_area.setStyleSheet("""
            QScrollArea { 
                background: transparent; 
                border: none; 
            }
            QScrollBar:vertical {
                border: 1px solid white;
                background: white;
                width: 10px;
                margin: 0px 0px 0px 0px;
            }
            QScrollBar::handle:vertical {
                background: cyan;
                min-height: 0px;
            }
            QScrollBar::add-line:vertical {
                height: 0px;
                subcontrol-position: bottom;
                subcontrol-origin: margin;
            }
            QScrollBar::sub-line:vertical {
                height: 0px;
                subcontrol-position: top;
                subcontrol-origin: margin;
            }
        """)

    def _create_button_widget(self):
        button_widget = QWidget()
        button_widget.setStyleSheet("background: transparent;")
        self.buttonGroup = QButtonGroup(self)
        self.buttons = []
        return button_widget

    def _populate_button_widget(self, button_widget, available_browsers):

        dimensions = self._get_button_dimensions()
        total_height = self._create_browser_buttons(button_widget, available_browsers, dimensions)
        self._set_final_widget_size(button_widget, dimensions, total_height)

    def _get_button_dimensions(self):
        return {
            'width': 185,
            'height': 75,
            'spacing': 20,
            'x_offset': 195
        }

    def _create_browser_buttons(self, button_widget, browser_icons, dims):
        total_height = 0
        for browser_tuple in browser_icons:
            _, browser_string, geometry = browser_tuple
            x_coord = geometry[0] - 395  
            y_coord = geometry[1] - 90   
            self._create_single_button(button_widget, browser_string, x_coord, y_coord, dims)
            total_height = max(total_height, y_coord + dims['height'])
        return total_height

    def _create_single_button(self, parent, icon_name, x_coord, y_coord, dims):
        button = QPushButton(parent)
        button.setFixedSize(dims['width'], dims['height'])
        button.move(x_coord, y_coord)
        button.setIconSize(button.size())
        button.setCheckable(True)

        browser_name, version = icon_name.split(':')
        button.setIcon(QIcon(BrowserPage.create_browser_button_image(f"{browser_name} {version}", self.btn_path)))
        if button.icon().isNull():
            fallback_path = os.path.join(self.btn_path, "default_browser_button.png")
            button.setIcon(QIcon(BrowserPage.create_browser_button_image(f"{browser_name} {version}", fallback_path, True)))
        self._apply_button_style(button)
        
        self.buttons.append(button)
        self.buttonGroup.addButton(button)
        button.clicked.connect(lambda _, b=icon_name: self.show_browser(b.replace(':', ' ')))

    @staticmethod
    def create_browser_button_image(browser_text, btn_path, is_fallback=False):

        if ':' in browser_text:
            browser_name, version = browser_text.split(':', 1)
        else:
            browser_name, version = browser_text.split()[0], ' '.join(browser_text.split()[1:])
        if is_fallback:
            base_image = QPixmap(btn_path)
        else:
            base_image = QPixmap(os.path.join(btn_path, f"{browser_name}_button.png"))
        
        if base_image.isNull():
            base_image = QPixmap(185, 75)
            base_image.fill(QColor(44, 62, 80))
        
        painter = QPainter(base_image)
        if painter.isActive():
            BrowserPage._setup_version_font(painter, version, base_image)
            if is_fallback:
                BrowserPage._setup_browser_name(painter, browser_name, base_image)
            painter.end()
        return base_image

    @staticmethod
    def _setup_browser_name(painter, browser_name, base_image):
        font_size = 13
        app_font = QApplication.font()
        app_font.setPointSize(font_size)
        app_font.setWeight(QFont.Weight.Bold)
        painter.setFont(app_font)
        painter.setPen(QColor(0, 255, 255))
        text_rect = painter.fontMetrics().boundingRect(browser_name)
        while text_rect.width() > base_image.width() * 0.6 and font_size > 6:
            font_size -= 1

        x = (base_image.width() - text_rect.width()) // 2 - 30
        y = (base_image.height() + text_rect.height()) // 2 - 10
        painter.drawText(x, y, browser_name)
    

    @staticmethod
    def _setup_version_font(painter, version, base_image):
        font_size = 11
        painter.setFont(QFont('Arial', font_size))
        painter.setPen(QColor(0x88, 0x88, 0x88))
        text_rect = painter.fontMetrics().boundingRect(version)
        while text_rect.width() > base_image.width() * 0.6 and font_size > 6:
            font_size -= 1
            painter.setFont(QFont('Arial', font_size))
            text_rect = painter.fontMetrics().boundingRect(version)

        x = (base_image.width() - text_rect.width()) // 2 - 27
        y = (base_image.height() + text_rect.height()) // 2 + 10
        painter.drawText(x, y, version)

    def _apply_button_style(self, button):
        button.setStyleSheet("""
            QPushButton {
                background: transparent;
                border: none;
            }
            QPushButton:hover {
                background-color: rgba(200, 200, 200, 30);
            }
            QPushButton:checked {
                background-color: rgba(200, 200, 200, 50);
            }
        """)

    def _set_final_widget_size(self, widget, dims, total_height):
        widget.setFixedSize(dims['width'] * 2 + 5, total_height + dims['spacing'])

    def show_browser(self, browser):
        browser_name, version = browser.split()[0], ' '.join(browser.split()[1:])
        try:
            base_image = self._create_browser_display_image(browser_name, version)
            self.display.setPixmap(base_image.scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio))
        except Exception:
            pass
        self.selected_browser_icon = browser
        self.button_next.setVisible(True)
        self.update_swarp_json()

    def _create_browser_display_image(self, browser_name, version):
        base_image = QPixmap(os.path.join(self.btn_path, f"{browser_name}_icon.png"))
        painter = QPainter(base_image)
        painter.setFont(QFont('Arial', 25))
        painter.setPen(QColor(0, 255, 255))
        
        text_rect = painter.fontMetrics().boundingRect(version)
        x = (base_image.width() - text_rect.width()) // 2
        y = base_image.height() - 45
        
        painter.drawText(x, y, version)
        painter.end()
        return base_image

    def update_swarp_json(self):
        inserted_data = {
            "browser": self.selected_browser_icon
        }

        self.update_status.write_data(inserted_data)
class ScreenPage(Page):
    def __init__(self, page_stack, main_window, parent=None):
        super().__init__("Screen", page_stack, main_window, parent)
        self.selected_dimentions = None
        self.update_status = main_window
        self.selected_dimentions_icon = None        
        self.button_back.setVisible(True)
        self.title.setGeometry(585, 40, 200, 40); self.title.setText("Pick a Resolution")       
        self.display.setGeometry(QtCore.QRect(5, 50, 580, 435))
        self.showing_larger_resolutions = False
        self.larger_resolution_buttons = []
        self.create_interface_elements()

    def create_interface_elements(self):
        self.buttonGroup = QButtonGroup(self)
        self.buttons = []
        for j, (object_type, icon_name, geometry) in enumerate([
            (QPushButton, "800x600", (595, 90, 180, 70)),
            (QPushButton, "1024x760", (595, 170, 180, 70)),
            (QPushButton, "1152x1080", (595, 250, 180, 70)),
            (QPushButton, "1280x1024", (595, 330, 180, 70)),
            (QPushButton, "1920x1080", (595, 410, 180, 70))
        ]):
            boton = object_type(self)
            boton.setGeometry(*geometry)
            boton.setIconSize(boton.size())
            boton.setCheckable(True)
            boton.setIcon(QIcon(self.create_resolution_button_image(icon_name)))
            self.buttons.append(boton)
            self.buttonGroup.addButton(boton, j)
            boton.clicked.connect(lambda _, dimentions=icon_name: self.show_dimentions(dimentions))

        self.larger_resolutions_button = QPushButton(self)
        self.larger_resolutions_button.setGeometry(100, 450, 185, 50)
        self.larger_resolutions_button.setIconSize(self.larger_resolutions_button.size())
        self.larger_resolutions_button.setIcon(QIcon(self.create_resolution_button_image("Larger Resolutions")))
        self.larger_resolutions_button.clicked.connect(self.show_larger_resolutions)

        self.custom_resolution_button = QPushButton(self)
        self.custom_resolution_button.setGeometry(300, 450, 195, 50)
        self.custom_resolution_button.setIconSize(self.custom_resolution_button.size())
        self.custom_resolution_button.setIcon(QIcon(self.create_resolution_button_image("Custom Resolution")))
        self.custom_resolution_button.clicked.connect(self.show_custom_resolution_dialog)

    def create_resolution_button_image(self, resolution_text):
        template_path = os.path.join(self.btn_path, "resolution_template_button.png")
        
        if os.path.exists(template_path):
            base_image = QPixmap(template_path)
            if 'Resolution' in resolution_text:
                base_image = base_image.scaled(195, 50)
                font_size = 10
            else:
                base_image = base_image.scaled(187, 75)
                font_size = 13
        else:
            base_image = QPixmap(185, 75)
            base_image.fill(QColor(44, 62, 80))
            font_size = 13
        
        painter = QPainter(base_image)
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)
        
        font = QFont()
        font.setPointSize(font_size)
        font.setBold(True)
        painter.setFont(font)
        
        painter.setPen(QColor(0, 255, 255))
        
        text_rect = base_image.rect()
        painter.drawText(text_rect, Qt.AlignmentFlag.AlignCenter | Qt.AlignmentFlag.AlignVCenter, resolution_text)
        
        painter.end()
        return base_image

    def show_larger_resolutions(self):
        if self.showing_larger_resolutions:
            self.hide_larger_resolutions()
        else:
            self.hide_standard_resolutions()
            self.showing_larger_resolutions = True
            self.larger_resolutions_button.setIcon(QIcon(self.create_resolution_button_image("Standard Resolutions")))
            
            larger_resolutions = [
                ("2560x1600", (595, 90, 180, 70)),
                ("2560x1440", (595, 170, 180, 70)),
                ("1920x1440", (595, 250, 180, 70)),
                ("1792x1344", (595, 330, 180, 70)),
                ("2048x1152", (595, 410, 180, 70))
            ]
            
            for i, (resolution, geometry) in enumerate(larger_resolutions):
                button = QPushButton(self)
                button.setGeometry(*geometry)
                button.setIconSize(button.size())
                button.setCheckable(True)
                button.setVisible(True)
                button.setIcon(QIcon(self.create_resolution_button_image(resolution)))
                button.clicked.connect(lambda _, res=resolution: self.show_dimentions(res))
                self.larger_resolution_buttons.append(button)
                self.buttonGroup.addButton(button, len(self.buttons) + i)

    def hide_larger_resolutions(self):
        for button in self.larger_resolution_buttons:
            self.buttonGroup.removeButton(button)
            button.deleteLater()
        self.larger_resolution_buttons.clear()
        self.showing_larger_resolutions = False
        self.larger_resolutions_button.setIcon(QIcon(self.create_resolution_button_image("Larger Resolutions")))
        self.show_standard_resolutions()

    def hide_standard_resolutions(self):
        for button in self.buttons:
            button.setVisible(False)

    def show_standard_resolutions(self):
        for button in self.buttons:
            button.setVisible(True)

    def show_custom_resolution_dialog(self):
        dialog = QDialog(self)
        dialog.setWindowTitle("Custom Resolution")
        dialog.setFixedSize(300, 150)
        dialog.setModal(True)
        dialog.setStyleSheet("""
            QDialog {
                background-color: #2c3e50;
                border: 2px solid #00ffff;
                border-radius: 10px;
            }
            QLabel {
                color: white;
                font-size: 12px;
            }
            QLineEdit {
                background-color: #34495e;
                color: white;
                border: 1px solid #00ffff;
                border-radius: 5px;
                padding: 5px;
                font-size: 12px;
            }
            QPushButton {
                background-color: #2c3e50;
                color: white;
                border: 2px solid #00ffff;
                border-radius: 5px;
                padding: 8px;
                font-size: 12px;
            }
            QPushButton:hover {
                background-color: #34495e;
            }
        """)

        layout = QVBoxLayout()

        input_layout = QHBoxLayout()
        width_label = QLabel("Width:")
        width_input = QLineEdit()
        width_input.setPlaceholderText("1920")
        height_label = QLabel("Height:")
        height_input = QLineEdit()
        height_input.setPlaceholderText("1080")

        input_layout.addWidget(width_label)
        input_layout.addWidget(width_input)
        input_layout.addWidget(height_label)
        input_layout.addWidget(height_input)

        button_layout = QHBoxLayout()
        ok_button = QPushButton("OK")
        cancel_button = QPushButton("Cancel")

        button_layout.addWidget(ok_button)
        button_layout.addWidget(cancel_button)

        layout.addLayout(input_layout)
        layout.addLayout(button_layout)
        dialog.setLayout(layout)

        def validate_and_accept():
            try:
                width = int(width_input.text())
                height = int(height_input.text())
                
                if width <= 0 or height <= 0:
                    QMessageBox.warning(dialog, "Invalid Resolution", "Width and height must be positive numbers.")
                    return
                
                if width > 10000 or height > 10000:
                    QMessageBox.warning(dialog, "Invalid Resolution", "Resolution too large. Maximum 10000x10000.")
                    return
                
                custom_resolution = f"{width}x{height}"
                self.show_dimentions(custom_resolution)
                dialog.accept()
                
            except ValueError:
                QMessageBox.warning(dialog, "Invalid Input", "Please enter valid numbers for width and height.")

        ok_button.clicked.connect(validate_and_accept)
        cancel_button.clicked.connect(dialog.reject)

        dialog.exec()

    def update_swarp_json(self):
        inserted_data = {
            "dimentions": self.selected_dimentions_icon
        }

        self.update_status.write_data(inserted_data)

    def show_dimentions(self, dimentions):
        try:
            image_path = os.path.join(self.btn_path, f"{dimentions}.png")
            if os.path.exists(image_path):
                self.display.setPixmap(QPixmap(image_path).scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio))
            else:
                self.create_resolution_preview_image(dimentions)
        except:
            self.display.clear()
        
        self.selected_dimentions_icon = dimentions
        self.button_next.setVisible(True)
        self.update_swarp_json()

    def create_resolution_preview_image(self, resolution_text):
        template_path = os.path.join(self.btn_path, "resolution_template.png")
        
        if os.path.exists(template_path):
            base_image = QPixmap(template_path)
            base_image = base_image.scaled(580, 435, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)
        else:
            base_image = QPixmap(580, 435)
            base_image.fill(QColor(44, 62, 80))
        
        painter = QPainter(base_image)
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)
        
        try:
            width, height = map(int, resolution_text.split('x'))
            gcd = self._gcd(width, height)
            aspect_ratio = f"{width//gcd}:{height//gcd}"
        except:
            aspect_ratio = ""
        
        font = QFont()
        font.setPointSize(24)
        font.setBold(True)
        painter.setFont(font)
        painter.setPen(QColor(0, 255, 255))
        
        text_rect = base_image.rect()
        painter.drawText(text_rect, Qt.AlignmentFlag.AlignCenter, resolution_text)
        
        if aspect_ratio:
            font.setPointSize(16)
            painter.setFont(font)
            painter.setPen(QColor(200, 200, 200)) 
            
            aspect_rect = QRect(text_rect.x(), text_rect.y() + 80, text_rect.width(), 40)
            painter.drawText(aspect_rect, Qt.AlignmentFlag.AlignCenter, f"({aspect_ratio})")
        
        painter.end()
        
        self.display.setPixmap(base_image)
    
    def _gcd(self, a, b):
        while b:
            a, b = b, a % b
        return a

class ResumePage(Page):
    def __init__(self, page_stack, main_window=None, parent=None):
        super().__init__("Resume", page_stack, main_window, parent)
        self.update_status = main_window
        self.connection_manager = main_window.connection_manager
        self.btn_path = main_window.btn_path
        self.labels_creados = []
        self.additional_labels = []
        self.button_go.clicked.connect(self.copy_profile)
        self.button_back.setVisible(True)
        self.title.setGeometry(585, 40, 185, 40); self.title.setText("Profile Summary")  
        self.display.setGeometry(QtCore.QRect(5, 50, 580, 435))#relacion 4:3     
        self.buttonGroup = QButtonGroup(self)   
        self.button_back.clicked.connect(self.reverse)
        self.create_arrow()
        self.create_interface_elements()

    def reverse(self):
        if self.connection_type == "system-wide":
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(LocationPage)))
        else:
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(ScreenPage)))

    def show_location_verification(self, location_icon_name):
        verification_page = LocationVerificationPage(self.page_stack, self.update_status, location_icon_name, self)
        self.page_stack.addWidget(verification_page)
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(verification_page))

    def create_arrow(self):
        self.arrow_label = QLabel(self)
        self.arrow_label.setGeometry(400, 115, 200, 200)  
        arrow_pixmap = QPixmap(os.path.join(self.btn_path, "arrow.png"))  

        self.arrow_label.setPixmap(arrow_pixmap)
        self.arrow_label.setScaledContents(True)

        
        self.arrow_label.raise_()  

    def showEvent(self, event):
        super().showEvent(event)
        self.arrow_label.show()
        self.arrow_label.raise_() 

    def create_interface_elements(self):
        for j, (object_type, icon_name, geometry) in enumerate([
            (QLineEdit, None, (130, 73, 300, 24)),
            (QLabel, None, (0,0,0,0))  
        ]):

            if object_type == QLabel:
                label = object_type(self)
                label.setGeometry(*geometry)
                icon_path = os.path.join(self.btn_path, f"{icon_name}_button.png")
                if os.path.exists(icon_path):
                    label.setPixmap(QPixmap(icon_path))
                    locations = self.connection_manager.get_location_info(icon_name)
                    provider = locations.operator.name if locations and hasattr(locations, 'operator') else None
                    if label.pixmap().isNull():
                        if locations and hasattr(locations, 'country_name'):
                            label.setPixmap(LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', os.path.join(self.btn_path, "default_location_button.png"), provider))
                        else:
                            label.setPixmap(LocationPage.create_location_button_image('', os.path.join(self.btn_path, "default_location_button.png"), provider))
                    else:
                        if locations and hasattr(locations, 'country_name'):
                            label.setPixmap(LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', os.path.join(self.btn_path, "default_location_button.png"), provider, icon_path))
                        else:
                            label.setPixmap(LocationPage.create_location_button_image('', os.path.join(self.btn_path, "default_location_button.png"), provider, icon_path))
            elif object_type == QLineEdit:
                self.line_edit = object_type(self)  # Define line_edit como un atributo de la clase ResumePage
                self.line_edit.setGeometry(*geometry)
                self.line_edit.setMaxLength(13)
                self.line_edit.textChanged.connect(self.toggle_button_visibility)
                self.line_edit.setStyleSheet("background-color: transparent; border: none; color: cyan;")
                self.line_edit.setPlaceholderText("Enter profile name")
                self.line_edit.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.create()

    def create(self):
        for label in self.additional_labels:
            label.deleteLater()
        self.additional_labels.clear()

        profile_1 = self.update_status.read_data()
        self.connection_type = profile_1.get("connection", "")
        connection_exists = 'connection' in profile_1

        if connection_exists and profile_1['connection'] not in ["tor", "just proxy"]:
            items = ["protocol", "connection", "location", "browser", "dimentions"]
            initial_y = 90
            label_height = 80
        elif connection_exists:  # si la conexión existe pero su texto es 'tor' o 'just proxy'
            items = ["protocol", "connection", "location", "browser", "dimentions"]
            initial_y = 90
            label_height = 80
        else:
            items = ["protocol", "location", "browser", "dimentions"]
            initial_y = 90
            label_height = 105
        for i, item in enumerate(items):
            text = profile_1.get(item, "")
            if text:
                if item == 'browser':
                    base_image = BrowserPage.create_browser_button_image(text, self.btn_path)
                    geometry = (585, initial_y + i * label_height, 185, 75)
                    parent_label = QLabel(self)
                    parent_label.setGeometry(*geometry)
                    parent_label.setPixmap(base_image)
                    if parent_label.pixmap().isNull():
                        fallback_path = os.path.join(self.btn_path, "default_browser_button.png")
                        base_image = BrowserPage.create_browser_button_image(text, fallback_path, True)
                        parent_label.setPixmap(base_image)
                    parent_label.show()
                    self.labels_creados.append(parent_label)
                elif item == 'location':
                    icon_path = os.path.join(self.btn_path, f"button_{text}.png")
                    geometry = (585, initial_y + i * label_height, 185, 75)
                    parent_label = QPushButton(self)
                    parent_label.setGeometry(*geometry)
                    parent_label.setFlat(True)
                    parent_label.setStyleSheet("background: transparent; border: none;")
                    location_pixmap = QPixmap(icon_path)
                    locations = self.connection_manager.get_location_info(text)
                    provider = locations.operator.name if locations and hasattr(locations, 'operator') else None
                    fallback_path = os.path.join(self.btn_path, "default_location_button.png")
                    if location_pixmap.isNull():
                        if locations and hasattr(locations, 'country_name'):
                            base_image = LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', fallback_path, provider)
                            parent_label.setIcon(QIcon(base_image))
                        else:
                            base_image = LocationPage.create_location_button_image('', fallback_path, provider)
                            parent_label.setIcon(QIcon(base_image))
                    else:
                        if locations and hasattr(locations, 'country_name'):
                            base_image = LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', fallback_path, provider, icon_path)
                            parent_label.setIcon(QIcon(base_image))
                        else:
                            base_image = LocationPage.create_location_button_image('', fallback_path, provider, icon_path)
                            parent_label.setIcon(QIcon(base_image))
                    parent_label.setIconSize(QSize(185, 75))
                    parent_label.location_icon_name = text
                    parent_label.setCursor(QtCore.Qt.CursorShape.PointingHandCursor)
                    parent_label.clicked.connect(lambda checked, loc=text: self.show_location_verification(loc))
                    parent_label.show()
                    self.labels_creados.append(parent_label)
                elif item == 'dimentions':
                    base_image = ScreenPage.create_resolution_button_image(self, text)
                    geometry = (585, initial_y + i * label_height, 185, 75)
                    parent_label = QLabel(self)
                    parent_label.setGeometry(*geometry)
                    parent_label.setPixmap(base_image)
                    parent_label.show()
                    self.labels_creados.append(parent_label)
                else:
                    icon_path = os.path.join(self.btn_path, f"{text}_button.png")
                    geometry = (585, initial_y + i * label_height, 185, 75)
                    parent_label = QLabel(self)
                    parent_label.setGeometry(*geometry)
                    parent_label.setPixmap(QPixmap(icon_path))
                    parent_label.show()
                    self.labels_creados.append(parent_label)

        if connection_exists:

            if profile_1.get("connection", "") == "system-wide":
                image_path = os.path.join(self.btn_path, f"wireguard_{profile_1.get('location', '')}.png")
                main_label = QLabel(self)
                main_label.setGeometry(10, 130, 500, 375)
                main_label.setPixmap(QPixmap(image_path))
                main_label.setScaledContents(True)
                main_label.show()   
                self.labels_creados.append(main_label)              

                
            if profile_1.get("connection", "") == "just proxy":
                image_path = os.path.join(self.btn_path, f"icon_{profile_1.get('location', '')}.png")
                main_label = QLabel(self)
                main_label.setGeometry(10, 105, 530, 398)
                main_label.setPixmap(QPixmap(image_path))
                main_label.setScaledContents(True)
                main_label.show()   
                self.labels_creados.append(main_label)        
            if profile_1.get("connection", "") == "tor":
                image_path = os.path.join(self.btn_path, f"hdtor_{profile_1.get('location', '')}.png")
                main_label = QLabel(self)
                main_label.setGeometry(10, 105, 530, 398)
                main_label.setPixmap(QPixmap(image_path))
                main_label.setScaledContents(True)
                main_label.show()   
                self.labels_creados.append(main_label)  
            if profile_1.get("connection", "") == "browser-only":
                image_name = "browser only.png"
                image_path = os.path.join(self.btn_path, image_name)
                label_background = QLabel(self)
                label_background.setGeometry(10, 50, 535, 460)
                label_background.setPixmap(QPixmap(image_path))
                label_background.setScaledContents(True)
                label_background.show()
                label_background.lower()
                self.labels_creados.append(label_background)
                image_path = os.path.join(self.btn_path, f"wireguard_{profile_1.get('location', '')}.png")
                main_label = QLabel(self)
                main_label.setGeometry(10, 130, 500, 375)
                main_label.setPixmap(QPixmap(image_path))
                main_label.setScaledContents(True)
                main_label.show()
                self.labels_creados.append(main_label)       
        else:   
                image_path = os.path.join(self.btn_path, f"icon_{profile_1.get('location', '')}.png")
                main_label = QLabel(self)
                main_label.setGeometry(10, 130, 500, 375)
                main_label.setPixmap(QPixmap(image_path))
                main_label.setScaledContents(True)
                main_label.show()   
                self.labels_creados.append(main_label)    

        if hasattr(self, 'arrow_label'):
            self.arrow_label.raise_()

    def toggle_button_visibility(self):
        self.button_go.setVisible(bool(self.line_edit.text()))

    def find_menu_page(self):
        for i in range(self.page_stack.count()):
            page = self.page_stack.widget(i)
            if isinstance(page, MenuPage):
                return page
        return None
    
    def copy_profile(self):
        # Obtener el nombre del perfil ingresado en el QLineEdit
        profile_name = self.line_edit.text()
        menu_page = self.find_menu_page()
        if menu_page:
            number_of_profiles = menu_page.number_of_profiles

        # Abrir y cargar los datos de swarp.json
        profile_data = self.update_status.read_data()

        
        # Verificar si los campos necesarios están llenos
        required_fields = [profile_data.get("protocol"),  profile_name]
        if not all(required_fields):
            print("Error: Some required fields are empty!")
            return
        
        # Actualizar el nombre del perfil con el texto ingresado
        profile_data["name"] = profile_name
        profile_data["visible"] = "yes"
        


        #profile_id = int(number_of_profiles) + 1 
        profiles = ProfileController.get_all()
        profile_id = self.get_next_available_id(profiles)
        new_profile = profile_data

        self.create_core_profiles(new_profile, profile_id)
        
        
        main = self.update_status
        if hasattr(main, 'navigate_after_profile_created'):
            main.navigate_after_profile_created()
        else:
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage)))
        
        self.update_status.clear_data()

        # Limpiar el QLineEdit
        self.line_edit.clear()
        self.display.clear()
        self.button_go.setVisible(False)

    def get_next_available_id(self, profiles: dict) -> int:
        if not profiles:
            return 1
            
        existing_ids = sorted(profiles.keys())
        
        for i in range(1, max(existing_ids) + 2):
            if i not in existing_ids:
                return i
                
        return None

    def create_core_profiles(self, profile, id):
        if profile.get('connection') != 'system-wide':
            browser_info = profile.get('browser', '').split()
            if len(browser_info) < 2:
                self.update_status.update_status('Application version not supported')
                return

            application = f"{browser_info[0].lower()}:{browser_info[1]}"
        else:
            application = ''
        
        parts = profile.get('location').split('_')
        country_code = parts[0]  
        location_code = parts[1]
        if profile.get('protocol') == 'wireguard':
            connection_type = 'wireguard'
        elif profile.get('protocol') == 'hidetor' or profile.get('protocol') == 'residential':
            if profile.get('connection') == 'tor':
                connection_type = 'tor'
            elif profile.get('connection') == 'just proxy':
                connection_type = 'system'
        else:
            self.update_status.update_status('Connection type not supported')
            return

        profile_data = {
            'id': int(id),
            'name': profile.get('name'),
            'country_code': country_code,
            'code': location_code,
            'application': application,
            'connection_type': connection_type,
            'resolution': profile.get('dimentions', ''),
        }
        profile_type = 'system' if profile.get('connection') == 'system-wide' else 'session'
        action = f'CREATE_{profile_type.upper()}_PROFILE'

        
        self.handle_core_action_create_profile(action, profile_data, profile_type)
        

    def eliminacion(self):
        for label in self.labels_creados:
            label.deleteLater()

        # Limpia la lista de referencia
        

        self.labels_creados = []
        self.create()
        if hasattr(self, 'arrow_label'):
            self.arrow_label.show()
            self.arrow_label.raise_()

    def handle_core_action_create_profile(self, action, profile_data=None, profile_type=None):

        self.worker_thread = WorkerThread(action, profile_data, profile_type)
        self.worker_thread.text_output.connect(self.update_output)
        self.worker_thread.start()
        self.worker_thread.wait()

    def update_output(self, text):
        self.update_status.update_status(text)


    def on_profile_creation(self, result):
            
        if self.worker_thread:
            self.worker_thread.quit()
            self.worker_thread.wait()
            self.worker_thread = None
class EditorPage(Page):
    def __init__(self, page_stack, main_window):
        super().__init__("Editor", page_stack, main_window)
        self.page_stack = page_stack
        self.update_status = main_window
        self.connection_manager = main_window.connection_manager
        self.labels = []  # Lista para almacenar los labels dinámicamente
        self.buttons = []  # Lista para almacenar los labels dinámicamente
        self.title.setGeometry(570, 40, 185, 40); self.title.setText("Edit Profile")  

        
        self.button_apply.setVisible(True)
        self.button_apply.clicked.connect(self.go_selected)
        
        self.button_back.setVisible(True)
        try:
            self.button_back.clicked.disconnect()
        except TypeError:
            pass
        self.button_back.clicked.connect(self.go_back)

        self.name_handle = QLabel(self)
        self.name_handle.setGeometry(110, 70, 400, 30)
        self.name_handle.setStyleSheet('color: #cacbcb;')
        self.name_handle.setText("Profile Name:")

        self.name_hint = QLabel(self)
        self.name_hint.setGeometry(265, 100, 190, 20)
        self.name_hint.setStyleSheet('color: #888888; font-size: 10px; font-style: italic;')
        self.name_hint.setText("Click here to edit profile name")
        self.name_hint.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)

        self.name = QLineEdit(self)
        self.name.setPlaceholderText("Enter name")
        self.name.setGeometry(265, 70, 190, 30)
        self.name.setStyleSheet("color: cyan; border: 1px solid #666666; border-radius: 3px; background-color: rgba(0, 0, 0, 0.3);")
        self.name.setCursor(QtCore.Qt.CursorShape.IBeamCursor)  
        self.name.focusInEvent = lambda event: self.name_hint.hide()
        self.name.focusOutEvent = lambda event: self.name_hint.show() if not self.name.text() else self.name_hint.hide()
        
        self.name.textChanged.connect(lambda text: self.name_hint.hide() if text else self.name_hint.show())

        self.temp_changes = {}
        self.original_values = {}
        self.display.setGeometry(QtCore.QRect(0, 60, 540, 405)) 
        self.display.hide()

        self.garaje=QLabel(self)
        self.garaje.setGeometry(QtCore.QRect(0, 70, 540, 460))

   
        self.brow_disp=QLabel(self)
        self.brow_disp.setGeometry(QtCore.QRect(0, 50, 540, 460))  
        self.brow_disp.setPixmap(QPixmap(os.path.join(self.btn_path, "browser only.png")))
        self.brow_disp.hide()
        self.brow_disp.lower()
       
    def update_name_value(self):
        original_name = self.data_profile.get('name', '')
        new_name = self.name.text()
        if original_name != new_name:
            self.update_temp_value('name', new_name)
        else:
            pass
        
    def go_back(self):
        selected_profiles_str = ', '.join([f"Profile_{profile['profile_number']}" for profile in self.page_stack.widget(0).selected_profiles])
        if self.has_unsaved_changes(selected_profiles_str):
            self.show_unsaved_changes_popup()
        else:
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage)))

    def find_menu_page(self):
        for i in range(self.page_stack.count()):
            page = self.page_stack.widget(i)
            if isinstance(page, MenuPage):
                return page
        return None
    
    def find_resume_page(self):
        for i in range(self.page_stack.count()):
            page = self.page_stack.widget(i)
            if isinstance(page, ResumePage):
                return page
        return None
    
    def find_protocol_page(self):
        for i in range(self.page_stack.count()):
            page = self.page_stack.widget(i)
            if isinstance(page, ProtocolPage):
                return page
        return None
    
    def showEvent(self, event):
        super().showEvent(event)
        self.extraccion()

    def extraccion(self):
        self.data_profile = {}
        for label in self.labels:
            label.deleteLater()
        self.labels = []
        for button in self.buttons:
            button.deleteLater()
        self.buttons = []        

        selected_profiles_str = ', '.join([f"Profile_{profile['profile_number']}" for profile in self.page_stack.widget(0).selected_profiles])
        menu_page = self.find_menu_page()
        if menu_page:
            new_profiles = ProfileController.get_all()
            self.profiles_data = menu_page.match_core_profiles(profiles_dict=new_profiles)
            self.data_profile = self.profiles_data[selected_profiles_str].copy()  
            
            profile_id = int(selected_profiles_str.split('_')[1])
            self.data_profile['id'] = profile_id
            
            if selected_profiles_str in self.temp_changes:
                for key, value in self.temp_changes[selected_profiles_str].items():
                    self.data_profile[key] = value

        self.name.textChanged.connect(self.update_name_value)
        self.verificate(self.data_profile, selected_profiles_str)

    def verificate(self, data_profile, selected_profile_str):
        protocol = data_profile.get("protocol", "")

        try:
            if protocol == "wireguard":
                self.process_and_show_labels(data_profile, {
                    "protocol": ['wireguard', 'residential', 'hidetor'],
                    "connection": ['browser-only', 'system-wide'],
                    "location": self.connection_manager.get_location_list(),
                    "browser": self.connection_manager.get_browser_list(),
                    "dimentions": self.connection_manager.get_available_resolutions(data_profile.get('id', ''))
                }, selected_profile_str)
            
            elif protocol == "residential" or protocol == "hidetor":
                self.process_and_show_labels(data_profile, {
                    "protocol": ['residential', 'wireguard', 'hidetor'],
                    "connection": ['tor', 'just proxy'],
                    "location": self.connection_manager.get_location_list(),
                    "browser": self.connection_manager.get_browser_list(),
                    "dimentions": self.connection_manager.get_available_resolutions(data_profile.get('id', ''))
                }, selected_profile_str)
            
            elif protocol == "lokinet":
                self.process_and_show_labels(data_profile, {
                    "protocol": ['lokinet']
                }, selected_profile_str)
            elif protocol == "open":
                self.process_and_show_labels(data_profile, {
                    "protocol": ['open']
                }, selected_profile_str)

        except Exception as e:
            print(f'An error occurred in verificate: {e}')

    def process_and_show_labels(self, data_profile, parameters, selected_profile_str):
        protocol = data_profile.get('protocol', "")
        connection= data_profile.get('connection', "")
        location = data_profile.get('location', "")
        country_garaje = location
        name = data_profile.get('name', "")
        self.name.setText(name)
        if protocol=="hidetor":
            if connection == "just proxy":
                self.display.setPixmap(QPixmap(os.path.join(self.btn_path, f"icon_{location}.png")))
            else:
                self.display.setPixmap(QPixmap(os.path.join(self.btn_path, f"hdtor_{location}.png")))
            self.display.show()
            self.display.setGeometry(0, 100, 400, 394)
            
            self.display.setScaledContents(True)
            
            self.garaje.hide()
            self.brow_disp.hide()
            

        if protocol=="wireguard":
            self.display.setGeometry(0, 60, 540, 405)
            self.display.show()
            self.display.setPixmap(QPixmap(os.path.join(self.btn_path, f"wireguard_{location}.png")))
            self.garaje.hide()
            if connection == "browser-only":
                is_supported = data_profile.get('browser_supported', False)
                image_name = "browser only.png" if is_supported else "unsupported_browser_only.png"
                self.brow_disp.setPixmap(QPixmap(os.path.join(self.btn_path, image_name)))
                self.brow_disp.show()
            else:
                self.brow_disp.hide()

        if protocol=="residential":
            self.display.setGeometry(0, 60, 540, 405)
            self.brow_disp.show()
            self.garaje.show()

            self.display.hide()
            if country_garaje:  
                country_garaje = 'brazil'
                self.garaje.setPixmap(QPixmap(os.path.join(self.btn_path, f"{country_garaje} garaje.png")))               

        for i, key in enumerate(parameters.keys()):
            if key == 'browser':
                browser_value = f"{data_profile.get(key, '')}"
                split_value = browser_value.split(':', 1)
                browser_type = split_value[0]
                browser_version = split_value[1] if len(split_value) > 1 else ''
                browser_value = f"{browser_type} {browser_version}"
                if browser_version == '':
                    browser_version  = data_profile.get('browser_version', '') 
                    browser_value = f"{browser_type} {browser_version}"
                if connection == 'system-wide' or not browser_value.strip():
                    base_image = QPixmap()  
                else:
                    base_image = BrowserPage.create_browser_button_image(browser_value, self.btn_path)
                    if base_image.isNull():
                        fallback_path = os.path.join(self.btn_path, "default_browser_button.png")
                        base_image = BrowserPage.create_browser_button_image(browser_value, fallback_path, True)
            elif key == 'location':
                current_value = f"{data_profile.get(key, '')}"
                image_path = os.path.join(self.btn_path, f"button_{current_value}.png")
                base_image = QPixmap(image_path)
                locations = self.connection_manager.get_location_info(current_value)
                provider = locations.operator.name if locations and hasattr(locations, 'operator') else None
                fallback_path = os.path.join(self.btn_path, "default_location_button.png")
                if base_image.isNull():
                    if locations and hasattr(locations, 'country_name'):
                        base_image = LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', fallback_path, provider)
                    else:
                        base_image = LocationPage.create_location_button_image(current_value, fallback_path, provider)
                else:
                    if locations and hasattr(locations, 'country_name'):
                        base_image = LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', fallback_path, provider, image_path)
                    else:
                        base_image = LocationPage.create_location_button_image(current_value, fallback_path, provider, image_path)

            elif key == 'dimentions':
                current_value = f"{data_profile.get(key, '')}"
                if current_value != 'None':
                    base_image = ScreenPage.create_resolution_button_image(self, current_value)
            else:    
                image_path = os.path.join(self.btn_path, f"{data_profile.get(key, '')}_button.png")
                current_value = data_profile.get(key, '')
                base_image = QPixmap(image_path)
                

            label = QLabel(key, self)
            label.setGeometry(565, 90 + i * 80, 185, 75)
            label.setPixmap(base_image)
            label.setScaledContents(True)
            label.show()
            self.labels.append(label)
            
            try:
                if key == 'browser':
                    value_index = [item.replace(':', ' ') for item in parameters[key]].index(browser_value)
                else:  
                    value_index = parameters[key].index(current_value)
            except ValueError:
                value_index = 0

            # Botón para mostrar el valor anterior
            prev_button = QPushButton(self)
            prev_button.setGeometry(535, 90 + i * 80, 30, 75)
            prev_button.clicked.connect(lambda _, k=key, idx=value_index: self.show_previous_value(k, idx, parameters))
            prev_button.show()
            icon_path = os.path.join(self.btn_path, f"UP_button.png")
            icon = QPixmap(icon_path)
            transform = QTransform().rotate(180)
            rotated_icon = icon.transformed(transform)

            # Establecer el ícono girado en el botón
            prev_button.setIcon(QIcon(rotated_icon))
            prev_button.setIconSize(prev_button.size())

            if (key == 'location' or key == 'browser') and not self.connection_manager.is_synced():
                w = prev_button.width()
                h = prev_button.height()
                outline_pix = QPixmap(w, h)
                outline_pix.fill(Qt.GlobalColor.transparent)
                painter = QPainter(outline_pix)
                painter.setRenderHint(QPainter.RenderHint.Antialiasing)
                pen = QtGui.QPen(QColor(0, 255, 0))
                pen.setWidth(3)
                painter.setPen(pen)
                painter.setBrush(Qt.BrushStyle.NoBrush)
                left_points = [QPointF(w*0.65, h*0.15), QPointF(w*0.25, h*0.50), QPointF(w*0.65, h*0.85)]
                painter.drawPolygon(QtGui.QPolygonF(left_points))
                painter.end()
                prev_button.setIcon(QIcon(outline_pix))
                prev_button.setIconSize(prev_button.size())
            
            # Apply green styling for location and browser buttons to indicate sync requirement
            if (key == 'location' or key == 'browser') and not self.connection_manager.is_synced():
                prev_button.setStyleSheet("""
                    QPushButton {
                        background-color: transparent;
                        border: none;
                    }
                    QPushButton:hover {
                        background-color: rgba(0, 255, 0, 0.1);
                        border-radius: 3px;
                    }
                    QPushButton:pressed {
                        background-color: rgba(0, 255, 0, 0.2);
                        border-radius: 3px;
                    }
                """)
            
            self.buttons.append(prev_button)

            # Botón para mostrar el valor siguiente
            next_button = QPushButton( self)
            next_button.setGeometry(750, 90 + i * 80, 30, 75)
            next_button.clicked.connect(lambda _, k=key, idx=value_index: self.show_next_value(k, idx, parameters))
            next_button.show()
            self.buttons.append(next_button)
            next_button.setIcon(QIcon( os.path.join(self.btn_path, f"UP_button.png")))
            next_button.setIconSize(next_button.size())
            if (key == 'location' or key == 'browser') and not self.connection_manager.is_synced():
                w = next_button.width()
                h = next_button.height()
                outline_pix_r = QPixmap(w, h)
                outline_pix_r.fill(Qt.GlobalColor.transparent)
                painter_r = QPainter(outline_pix_r)
                painter_r.setRenderHint(QPainter.RenderHint.Antialiasing)
                pen_r = QtGui.QPen(QColor(0, 255, 0))
                pen_r.setWidth(3)
                painter_r.setPen(pen_r)
                painter_r.setBrush(Qt.BrushStyle.NoBrush)
                right_points = [QPointF(w*0.35, h*0.15), QPointF(w*0.75, h*0.50), QPointF(w*0.35, h*0.85)]
                painter_r.drawPolygon(QtGui.QPolygonF(right_points))
                painter_r.end()
                next_button.setIcon(QIcon(outline_pix_r))
                next_button.setIconSize(next_button.size())
            
            # Apply green styling for location and browser buttons to indicate sync requirement
            if (key == 'location' or key == 'browser') and not self.connection_manager.is_synced():
                next_button.setStyleSheet("""
                    QPushButton {
                        background-color: transparent;
                        border: none;
                    }
                    QPushButton:hover {
                        background-color: rgba(0, 255, 0, 0.1);
                        border-radius: 3px;
                    }
                    QPushButton:pressed {
                        background-color: rgba(0, 255, 0, 0.2);
                        border-radius: 3px;
                    }
                """)
            
            prev_button.setVisible(True)
            next_button.setVisible(True)
            if key == 'protocol' or (protocol == 'wireguard' and key == 'connection'):
                prev_button.setDisabled(True)
                next_button.setDisabled(True)

            if connection == 'system-wide' and key == 'location':
                prev_button.setDisabled(True)
                next_button.setDisabled(True)

            if connection == 'system-wide' and (key == 'browser' or key == 'dimentions'):
                prev_button.setVisible(False)
                next_button.setVisible(False)

    def on_sync_complete_for_edit_profile(self, available_locations, available_browsers, status, is_tor, locations, all_browsers):
        if status:
            self.update_status.update_status('Sync complete.')
            self.extraccion()
        else:
            self.update_status.update_status('Sync failed. Please try again later.')

    def show_previous_value(self, key: str, index: int, parameters: dict) -> None:
        if key == 'browser' or key == 'location':
            if not self.connection_manager.is_synced():
                self.update_status.update_status('Syncing in progress..')
                self.update_status.sync()
                self.update_status.worker_thread.sync_output.connect(self.on_sync_complete_for_edit_profile)
                return

        previous_index = (index - 1) % len(parameters[key])
        previous_value = parameters[key][previous_index]
        self.update_temp_value(key, previous_value)
            

    def show_next_value(self, key: str, index: int, parameters: dict) -> None:
        if key == 'browser' or key == 'location':
            if not self.connection_manager.is_synced():
                self.update_status.update_status('Syncing in progress..')
                self.update_status.sync()
                self.update_status.worker_thread.sync_output.connect(self.on_sync_complete_for_edit_profile)
                return
                
        next_index = (index + 1) % len(parameters[key])
        next_value = parameters[key][next_index]

        self.update_temp_value(key, next_value)

    def update_temp_value(self, key: str, new_value: str) -> None:
        selected_profiles_str = ', '.join([f"Profile_{profile['profile_number']}" for profile in self.page_stack.widget(0).selected_profiles])
        if selected_profiles_str not in self.temp_changes:
            self.temp_changes[selected_profiles_str] = {}
            self.original_values[selected_profiles_str] = self.data_profile.copy()
            
        self.temp_changes[selected_profiles_str][key] = new_value
        self.extraccion()

    def has_unsaved_changes(self, profile_str: str) -> bool:
        return profile_str in self.temp_changes and bool(self.temp_changes[profile_str])

    def show_apply_changes_popup(self, selected_profiles_str: str) -> bool:
        if selected_profiles_str not in self.temp_changes:
            return False
        temp_changes = self.temp_changes[selected_profiles_str]
        current_data = self.original_values[selected_profiles_str]

        current_browser = f"{current_data.get('browser', '')} {current_data.get('browser_version', '')}"


        if 'location' in temp_changes and temp_changes['location'] != current_data.get('location'):
            message = "A new location would require a new subscription code.\nDo you want to proceed with erasing the old one?"
        elif 'browser' in temp_changes and temp_changes['browser'] != current_browser:
            message = "Changing the browser would delete all data associated with it. Proceed?"
        else:
            return False
        
        self.popup = ConfirmationPopup(
            self,
            message=message,
            action_button_text="Continue",
            cancel_button_text="Cancel"
        )
        self.popup.setWindowModality(Qt.WindowModality.ApplicationModal)
        self.popup.finished.connect(lambda result: self.handle_apply_changes_response(result))
        self.popup.show()
        return True
    
    def show_unsaved_changes_popup(self) -> None:
        self.popup = ConfirmationPopup(
            self,
            message="You have unsaved changes. Do you want to continue?",
            action_button_text="Continue",
            cancel_button_text="Cancel"
        )
        self.popup.setWindowModality(Qt.WindowModality.ApplicationModal)
        self.popup.finished.connect(lambda result: self.handle_unsaved_changes_response(result))
        self.popup.show()

    def handle_apply_changes_response(self, result: bool) -> None:
        if result:
            self.commit_changes()
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage)))

    def handle_unsaved_changes_response(self, result: bool) -> None:
        if result:
            self.temp_changes.clear()
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage)))

    def go_selected(self) -> None:
        selected_profiles_str = ', '.join([f"Profile_{profile['profile_number']}" 
                                         for profile in self.page_stack.widget(0).selected_profiles])
        
        if selected_profiles_str in self.temp_changes and self.temp_changes[selected_profiles_str]:
            needs_confirmation = self.show_apply_changes_popup(selected_profiles_str)
            if not needs_confirmation:
                self.commit_changes()
                self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage)))
                
        else:
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage)))



    def commit_changes(self) -> None:
        selected_profiles_str = ', '.join([f"Profile_{profile['profile_number']}" for profile in self.page_stack.widget(0).selected_profiles])
        if selected_profiles_str in self.temp_changes:
            for key, new_value in self.temp_changes[selected_profiles_str].items():
                self.update_core_profiles(key, new_value)
            
            self.temp_changes.pop(selected_profiles_str, None)
            self.original_values.pop(selected_profiles_str, None)

    def update_core_profiles(self, key, new_value):
        profile = ProfileController.get(int(self.update_status.current_profile_id))
        self.update_res = False
        if key == 'dimentions':
            profile.resolution = new_value
            self.update_res = True

        elif key  == 'name':
            profile.name = new_value

        elif key == 'connection':
            if new_value == 'tor':
                profile.connection.code = new_value
                profile.connection.masked = True
            elif new_value == 'just proxy':
                profile.connection.code = 'system'
                profile.connection.masked = True
            else:
                self.update_status.update_status('System wide profiles not supported atm')

        elif key == 'browser':
            browser_type, browser_version = new_value.split(':', 1)
            profile.application_version.application_code = browser_type
            profile.application_version.version_number = browser_version


        elif key == 'protocol':
            if self.data_profile.get('connection') == 'system-wide':
                self.edit_to_session()
            else:
                profile.connection.code = 'wireguard' if new_value == 'wireguard' else 'tor'
                profile.connection.masked = False if new_value == 'wireguard' else True

        else:
            location = self.connection_manager.get_location_info(new_value)


            if location:
                profile.location.code = location.code
                profile.location.country_code = location.country_code  
                profile.location.time_zone = location.time_zone
                profile.subscription = None


        ProfileController.update(profile)




            
        

    '''
    def edit_to_system(self):
        id = int(self.update_status.current_profile_id)
        profile = self.data_profile
        if profile.get('location') == 'The Netherlands':
            location = 'nl'
        elif profile.get('location') == 'Moldova':
            location = 'md'
        elif profile.get('location') == 'US (Ohio)':
            location = 'us'
        else:
            pass
        if profile.get('connection') == 'tor':
            connection_type = 'tor'
        elif profile.get('connection') == 'just proxy':
            connection_type = 'system'
        else:
            connection_type = 'wireguard'

        profile_data = {
        'id': int(id),
        'name': profile.get('name'),
        'location_code': location,
        'connection_type': connection_type,
    }

        resume_page = self.find_resume_page()
        if resume_page:
            resume_page.handle_core_action_create_profile('CREATE_SYSTEM_PROFILE', profile_data, 'system')
    '''

    def edit_to_session(self):
        id = int(self.update_status.current_profile_id)
        profile = self.data_profile
        default_app = 'firefox:123.0'
        default_resolution = '1024x760'
        location_code = self.connection_manager.get_location_info(profile.get('location'))
            
        connection_type = 'tor'

        profile_data = {
            'id': int(id),
            'name': profile.get('name'),
            'country_code': location_code.country_code,
            'code': location_code.code,
            'application': default_app ,
            'connection_type': connection_type,
            'resolution': default_resolution,
        }
        resume_page = self.find_resume_page()
        if resume_page:
            resume_page.handle_core_action_create_profile('CREATE_SESSION_PROFILE', profile_data, 'session')

class LocationVerificationPage(Page):
    def __init__(self, page_stack, main_window, location_icon_name, previous_page, parent=None):
        super().__init__("LocationVerification", page_stack, main_window, parent)
        self.location_icon_name = location_icon_name
        self.previous_page = previous_page
        self.connection_manager = main_window.connection_manager
        self.font_style = f"font-family: '{main_window.open_sans_family}';"
        self.verification_info = {}
        self.verification_checkmarks = {}
        self.verification_full_values = {}
        self.verification_labels = {}
        self.verification_copy_buttons = {}
        self.verification_display_names = {
            "operator_name": "Operator Name",
            "provider_name": "Provider Name",
            "nostr_public_key": "Nostr Key",
            "hydraveil_public_key": "HydraVeil Key",
            "nostr_attestation_event_reference": "Nostr Verification"
        }
        self.setup_ui()

    def setup_ui(self):
        location_display = QLabel(self)
        location_display.setGeometry(10, 0, 390, 520)
        location_display.setAlignment(Qt.AlignmentFlag.AlignCenter)
        
        icon_path = os.path.join(self.btn_path, f"icon_{self.location_icon_name}.png")
        location_pixmap = QPixmap(icon_path)
        fallback_path = os.path.join(self.btn_path, "default_location_button.png")
        
        if location_pixmap.isNull():
            location_pixmap = QPixmap(fallback_path)
        
        location_display.setPixmap(location_pixmap.scaled(390, 520, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation))
        location_display.show()

        title = QLabel("Operator Information", self)
        title.setGeometry(350, 50, 350, 30)
        title.setStyleSheet(f"color: #808080; font-size: 20px; font-weight: bold; {self.font_style}")
        title.show()

        info_items = [
            ("Operator Name", "operator_name", 130),
            ("Provider Name", "provider_name", 180),
            ("Nostr Key", "nostr_public_key", 230),
            ("HydraVeil Key", "hydraveil_public_key", 280),
            ("Nostr Verification", "nostr_attestation_event_reference", 330),
        ]

        label_x = 350
        label_width = 150
        label_height = 30
        value_x = 510
        value_width = 210
        value_height = 30
        checkmark_x = 725
        checkmark_width = 30
        checkmark_height = 30
        copy_button_x = 750
        copy_button_width = 30
        copy_button_height = 30

        for label_text, key, y_pos in info_items:
            label_widget = QLabel(label_text + ":", self)
            label_widget.setGeometry(label_x, y_pos, label_width, label_height)
            label_widget.setStyleSheet(f"color: white; font-size: 18px; {self.font_style}")
            label_widget.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)
            label_widget.show()
            self.verification_labels[key] = label_widget

            value_widget = QLabel("N/A", self)
            value_widget.setGeometry(value_x, y_pos, value_width, value_height)
            value_widget.setStyleSheet(f"color: white; font-size: 16px; {self.font_style}")
            value_widget.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)
            value_widget.show()

            checkmark_widget = QLabel("✓", self)
            checkmark_widget.setGeometry(checkmark_x, y_pos, checkmark_width, checkmark_height)
            checkmark_widget.setStyleSheet(f"color: #4CAF50; font-size: 28px; font-weight: bold; {self.font_style}")
            checkmark_widget.setAlignment(Qt.AlignmentFlag.AlignCenter)
            checkmark_widget.hide()

            self.verification_info[key] = value_widget
            self.verification_checkmarks[key] = checkmark_widget

            copy_button = QPushButton(self)
            copy_button.setGeometry(copy_button_x, y_pos, copy_button_width, copy_button_height)
            copy_button.setIcon(QIcon(os.path.join(self.btn_path, "paste_button.png")))
            copy_button.setIconSize(QSize(24, 24))
            copy_button.setStyleSheet(f"""
                QPushButton {{
                    background: transparent;
                    border: none;
                }}
                QPushButton:hover {{
                    background: rgba(255, 255, 255, 0.1);
                    border-radius: 4px;
                }}
            """)
            copy_button.clicked.connect(lambda checked=False, k=key: self.copy_verification_value(k))
            copy_button.show()
            self.verification_copy_buttons[key] = copy_button

        self.back_button = QPushButton(self)
        self.back_button.setGeometry(720, 525, 48, 35)
        self.back_button.setIcon(QIcon(os.path.join(self.btn_path, "back.png")))
        self.back_button.setIconSize(QSize(48, 35))
        self.back_button.setStyleSheet(f"""
            QPushButton {{
                background: transparent;
                border: none;
            }}
            QPushButton:hover {{
                background: rgba(255, 255, 255, 0.1);
                border-radius: 4px;
            }}
        """)
        self.back_button.clicked.connect(self.go_back)
        self.back_button.show()

        self.update_verification_info()

    def truncate_text_by_width(self, text, widget, max_width):
        if not text or text == "N/A":
            return text
        
        metrics = widget.fontMetrics()
        text_width = metrics.horizontalAdvance(text)
        
        if text_width <= max_width:
            return text
        
        ellipsis = "..."
        ellipsis_width = metrics.horizontalAdvance(ellipsis)
        available_width = max_width - ellipsis_width
        
        if available_width <= 0:
            return ellipsis
        
        start_chars = 1
        end_chars = 1
        
        while True:
            start_text = text[:start_chars]
            end_text = text[-end_chars:]
            combined_width = metrics.horizontalAdvance(start_text + ellipsis + end_text)
            
            if combined_width <= max_width:
                if start_chars + end_chars >= len(text):
                    return text
                start_chars += 1
                if start_chars + end_chars >= len(text):
                    return text
                end_chars += 1
            else:
                if start_chars > 1:
                    start_chars -= 1
                if end_chars > 1:
                    end_chars -= 1
                break
        
        if start_chars + end_chars >= len(text):
            return text
        
        return text[:start_chars] + ellipsis + text[-end_chars:]

    def update_verification_info(self):
        locations = self.connection_manager.get_location_info(self.location_icon_name)
        value_width = 210
        
        if not locations:
            for key, widget in self.verification_info.items():
                widget.setText("N/A")
                self.verification_full_values[key] = "N/A"
                if key in self.verification_checkmarks:
                    self.verification_checkmarks[key].hide()
            return

        operator = None
        if locations.operator:
            operator = locations.operator

        if operator:
            operator_name = operator.name or "N/A"
            self.verification_full_values["operator_name"] = operator_name
            display_operator = self.truncate_text_by_width(operator_name, self.verification_info["operator_name"], value_width)
            self.verification_info["operator_name"].setText(display_operator)
            
            provider_name = locations.provider_name if locations and hasattr(locations, 'provider_name') and locations.provider_name else "N/A"
            self.verification_full_values["provider_name"] = provider_name
            display_provider = self.truncate_text_by_width(provider_name, self.verification_info["provider_name"], value_width)
            self.verification_info["provider_name"].setText(display_provider)
            
            nostr_key = operator.nostr_public_key or "N/A"
            self.verification_full_values["nostr_public_key"] = nostr_key
            display_nostr = self.truncate_text_by_width(nostr_key, self.verification_info["nostr_public_key"], value_width)
            self.verification_info["nostr_public_key"].setText(display_nostr)
            
            hydraveil_key = operator.public_key or "N/A"
            self.verification_full_values["hydraveil_public_key"] = hydraveil_key
            display_hydraveil = self.truncate_text_by_width(hydraveil_key, self.verification_info["hydraveil_public_key"], value_width)
            self.verification_info["hydraveil_public_key"].setText(display_hydraveil)
            
            nostr_verification = operator.nostr_attestation_event_reference or "N/A"
            self.verification_full_values["nostr_attestation_event_reference"] = nostr_verification
            display_nostr_verif = self.truncate_text_by_width(nostr_verification, self.verification_info["nostr_attestation_event_reference"], value_width)
            self.verification_info["nostr_attestation_event_reference"].setText(display_nostr_verif)
        else:
            self.verification_info["operator_name"].setText("N/A")
            self.verification_full_values["operator_name"] = "N/A"
            self.verification_info["provider_name"].setText("N/A")
            self.verification_full_values["provider_name"] = "N/A"
            self.verification_info["nostr_public_key"].setText("N/A")
            self.verification_full_values["nostr_public_key"] = "N/A"
            self.verification_info["hydraveil_public_key"].setText("N/A")
            self.verification_full_values["hydraveil_public_key"] = "N/A"
            self.verification_info["nostr_attestation_event_reference"].setText("N/A")
            self.verification_full_values["nostr_attestation_event_reference"] = "N/A"
        
        for key, widget in self.verification_info.items():
            if key in self.verification_checkmarks:
                full_value = self.verification_full_values.get(key, "")
                if full_value and full_value != "N/A":
                    self.verification_checkmarks[key].show()
                else:
                    self.verification_checkmarks[key].hide()

    def copy_verification_value(self, key):
        full_value = self.verification_full_values.get(key, "")
        if full_value and full_value != "N/A":
            clipboard = QApplication.clipboard()
            clipboard.setText(full_value)
            display_name = self.verification_display_names.get(key, "Verification value")
            self.custom_window.update_status(f"{display_name} copied to clipboard")

    def go_back(self):
        if self.previous_page:
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.previous_page))

class Settings(Page):
    def __init__(self, page_stack, main_window, parent=None):
        super().__init__("Settings", page_stack, main_window, parent)
        self.font_style = f"font-family: '{self.custom_window.open_sans_family}';"

        self.update_status = main_window
        self.update_logging = main_window
        self.button_reverse.setVisible(True)
        self.button_reverse.setEnabled(True)
        self.button_reverse.clicked.connect(self.reverse)
        self.title.setGeometry(585, 40, 185, 40)
        self.title.setText("Settings")
        self.setup_ui()

    def setup_ui(self):
        main_container = QWidget(self)
        main_container.setGeometry(0, 0, 800, 520)
        
        self.layout = QHBoxLayout(main_container)
        self.layout.setContentsMargins(0, 60, 0, 0)

        self.left_panel = QWidget()
        self.left_panel.setFixedWidth(200)
        self.left_layout = QVBoxLayout(self.left_panel)
        self.left_layout.setContentsMargins(0, 0, 0, 0)
        self.left_layout.setSpacing(0)

        self.content_widget = QWidget()
        self.content_layout = QStackedLayout(self.content_widget)

        self.layout.addWidget(self.left_panel)
        self.layout.addWidget(self.content_widget)

        self.setup_menu_buttons()
        self.setup_pages()

    def setup_menu_buttons(self):
        menu_items = [
            ("Overview", self.show_account_page),
            ("Subscriptions", self.show_subscription_page),
            ("Create/Edit", self.show_registrations_page),
            ("Verification", self.show_verification_page),
            ("Delete Profile", self.show_delete_page),
            ("Error Logs", self.show_logs_page),
            ("Debug Help", self.show_debug_page)
        ]

        
            
        self.menu_buttons = []
        for text, callback in menu_items:
            btn = QPushButton(text)
            btn.setFixedHeight(40)
            btn.setCursor(Qt.CursorShape.PointingHandCursor)
            btn.setCheckable(True)
            btn.clicked.connect(callback)
            
            btn.setStyleSheet(f"""
                QPushButton {{
                    text-align: left;
                    padding-left: 20px;
                    border: none;
                    background: transparent;
                    color: #808080;
                    font-size: 14px;
                    {self.font_style}
                }}
                QPushButton:checked {{
                    background: rgba(255, 255, 255, 0.1);
                    color: white;
                    border-left: 3px solid #007AFF;
                }}
                QPushButton:hover:!checked {{
                    background: rgba(255, 255, 255, 0.05);
                }}
            """)
            
            self.left_layout.addWidget(btn)
            self.menu_buttons.append(btn)
        
        self.left_layout.addStretch()

    def create_delete_page(self):
        page = QWidget()
        layout = QVBoxLayout(page)
        layout.setContentsMargins(20, 20, 20, 20)
        layout.setSpacing(15)

        title = QLabel("DELETE PROFILE")
        title.setStyleSheet(f"color: #808080; font-size: 12px; font-weight: bold; {self.font_style}")
        layout.addWidget(title)

        self.delete_scroll_area = QScrollArea()
        self.delete_scroll_area.setFixedSize(510, 300)
        self.delete_scroll_area.setWidgetResizable(True)
        self.delete_scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        self.delete_scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
        self.delete_scroll_area.setStyleSheet("""
            QScrollArea {
                background-color: transparent; 
                border: none;
            }
            QScrollBar:vertical {
                background-color: rgba(128, 128, 128, 0.3);
                width: 12px;
                border-radius: 6px;
            }
            QScrollBar::handle:vertical {
                background-color: rgba(0, 255, 255, 0.7);
                border-radius: 6px;
                min-height: 20px;
            }
            QScrollBar::handle:vertical:hover {
                background-color: rgba(0, 255, 255, 0.9);
            }
            QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
                background-color: transparent;
                height: 0px;
            }
        """)
        
        self.delete_scroll_widget = QWidget()
        self.delete_scroll_widget.setStyleSheet("background-color: transparent;")
        self.delete_scroll_area.setWidget(self.delete_scroll_widget)
        
        self.profile_buttons = QButtonGroup()
        self.profile_buttons.setExclusive(True)
        
        self.create_delete_profile_buttons()
        
        layout.addWidget(self.delete_scroll_area)
        
        self.delete_button = QPushButton("Delete")
        self.delete_button.setEnabled(False)
        self.delete_button.setFixedSize(120, 40)
        self.delete_button.setStyleSheet(f"""
            QPushButton {{
                background: #ff4d4d;
                color: white;
                border: none;
                border-radius: 5px;
                font-weight: bold;
                {self.font_style}
            }}
            QPushButton:disabled {{
                background: #666666;
            }}
            QPushButton:hover:!disabled {{
                background: #ff3333;
            }}
        """)
        self.delete_button.clicked.connect(self.delete_selected_profile)
        self.profile_buttons.buttonClicked.connect(self.on_profile_selected)
        
        button_layout = QHBoxLayout()
        button_layout.addStretch()
        button_layout.addWidget(self.delete_button)
        button_layout.addStretch()
        
        layout.addStretch()
        layout.addLayout(button_layout)
        
        return page

    def create_delete_profile_buttons(self):
        profiles = ProfileController.get_all()
        
        for index, (profile_id, profile) in enumerate(profiles.items()):
            row = index // 2
            col = index % 2
            
            btn = QPushButton(f"Profile {profile_id}\n{profile.name}")
            btn.setCheckable(True)
            btn.setFixedSize(180, 60)
            btn.setParent(self.delete_scroll_widget)
            btn.setGeometry(col * 220 + 50, row * 100, 180, 60)
            btn.setStyleSheet(f"""
                QPushButton {{
                    background: rgba(255, 255, 255, 0.1);
                    border: none;
                    color: white;
                    border-radius: 5px;
                    text-align: center;
                    {self.font_style}
                }}
                QPushButton:checked {{
                    background: rgba(255, 255, 255, 0.3);
                    border: 2px solid #007AFF;
                }}
                QPushButton:hover:!checked {{
                    background: rgba(255, 255, 255, 0.2);
                }}
            """)
            self.profile_buttons.addButton(btn, profile_id)
        
        if profiles:
            rows = (len(profiles) + 1) // 2
            height = rows * 100
            self.delete_scroll_widget.setFixedSize(510, height)

    def create_debug_page(self):
        page = QWidget()
        layout = QVBoxLayout(page)
        layout.setContentsMargins(20, 20, 20, 20)
        layout.setSpacing(15)

        title = QLabel("DEBUG HELP")
        title.setStyleSheet(f"color: #808080; font-size: 12px; font-weight: bold; {self.font_style}")
        layout.addWidget(title)

        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_area.setStyleSheet(f"""
            QScrollArea {{
                border: none;
                background: transparent;
            }}
            QScrollArea > QWidget > QWidget {{
                background: transparent;
            }}
        """)

        scroll_content = QWidget()
        scroll_layout = QVBoxLayout(scroll_content)
        scroll_layout.setSpacing(15)

        profile_selection_group = QGroupBox("Profile Selection")
        profile_selection_group.setStyleSheet(f"""
            QGroupBox {{
                color: white;
                font-weight: bold;
                border: 1px solid rgba(255, 255, 255, 0.1);
                border-radius: 8px;
                padding: 15px;
                font-size: 10px;
                margin-top: 15px;
                {self.font_style}
            }}
            QGroupBox::title {{
                subcontrol-origin: margin;
                left: 10px;
                padding: 0 5px;
            }}
        """)
        profile_selection_layout = QVBoxLayout(profile_selection_group)

        profile_label = QLabel("Select System-wide Profile:")
        profile_label.setStyleSheet(f"color: white; font-size: 12px; {self.font_style}")
        profile_selection_layout.addWidget(profile_label)

        self.debug_profile_selector = QComboBox()
        self.debug_profile_selector.setStyleSheet(self.get_combobox_style())
        self.debug_profile_selector.currentTextChanged.connect(self.on_debug_profile_selected)
        profile_selection_layout.addWidget(self.debug_profile_selector)

        scroll_layout.addWidget(profile_selection_group)

        ping_group = QGroupBox("Ping Test")
        ping_group.setStyleSheet(f"""
            QGroupBox {{
                color: white;
                font-weight: bold;
                border: 1px solid rgba(255, 255, 255, 0.1);
                border-radius: 8px;
                padding: 15px;
                font-size: 10px;
                margin-top: 15px;
                {self.font_style}
            }}
            QGroupBox::title {{
                subcontrol-origin: margin;
                left: 10px;
                padding: 0 5px;
            }}
        """)
        ping_layout = QVBoxLayout(ping_group)

        self.ping_instruction_label = QLabel("")
        self.ping_instruction_label.setStyleSheet(f"color: white; font-size: 12px; {self.font_style}")
        self.ping_instruction_label.setWordWrap(True)
        self.ping_instruction_label.hide()
        ping_layout.addWidget(self.ping_instruction_label)

        ping_buttons_layout = QHBoxLayout()
        
        self.copy_ping_button = QPushButton("Copy Ping Command")
        self.copy_ping_button.setFixedSize(140, 40)
        self.copy_ping_button.setStyleSheet(f"""
            QPushButton {{
                font-size: 12px;
                background: #007AFF;
                color: white;
                border: none;
                border-radius: 5px;
                font-weight: bold;
                {self.font_style}
            }}
            QPushButton:hover {{
                background: #0056CC;
            }}
            QPushButton:disabled {{
                background: #666666;
            }}
        """)
        self.copy_ping_button.clicked.connect(self.copy_ping_command)
        self.copy_ping_button.setEnabled(False)
        ping_buttons_layout.addWidget(self.copy_ping_button)

        self.test_ping_button = QPushButton("Test Ping")
        self.test_ping_button.setFixedSize(120, 40)
        self.test_ping_button.setStyleSheet(f"""
            QPushButton {{
                font-size: 12px;
                background: #4CAF50;
                color: white;
                border: none;
                border-radius: 5px;
                font-weight: bold;
                {self.font_style}
            }}
            QPushButton:hover {{
                background: #45a049;
            }}
            QPushButton:disabled {{
                background: #666666;
            }}
        """)
        self.test_ping_button.clicked.connect(self.test_ping_connection)
        self.test_ping_button.setEnabled(False)
        ping_buttons_layout.addWidget(self.test_ping_button)

        ping_layout.addLayout(ping_buttons_layout)

        self.ping_result_label = QLabel("")
        self.ping_result_label.setStyleSheet(f"color: white; font-size: 12px; font-weight: bold; {self.font_style}")
        self.ping_result_label.setWordWrap(True)
        self.ping_result_label.hide()
        ping_layout.addWidget(self.ping_result_label)

        scroll_layout.addWidget(ping_group)


        command_group = QGroupBox("CLI Commands")
        command_group.setStyleSheet(f"""
            QGroupBox {{
                color: white;
                font-weight: bold;
                border: 1px solid rgba(255, 255, 255, 0.1);
                border-radius: 8px;
                padding: 15px;
                font-size: 10px;
                margin-top: 15px;
                {self.font_style}
            }}
            QGroupBox::title {{
                subcontrol-origin: margin;
                left: 10px;
                padding: 0 5px;
            }}
        """)
        command_layout = QVBoxLayout(command_group)

        self.cli_command = QLineEdit()
        self.cli_command.setReadOnly(True)
        self.cli_command.setText("Select a profile above to see command")
        self.cli_command.setStyleSheet(f"""
            QLineEdit {{
                color: white;
                background: rgba(255, 255, 255, 0.1);
                border: 1px solid rgba(255, 255, 255, 0.2);
                border-radius: 4px;
                padding: 8px;
                font-family: 'Courier New', monospace;
                font-size: 12px;
            }}
        """)
        command_layout.addWidget(self.cli_command)




        cli_buttons_layout = QHBoxLayout()
        
        cli_copy_button = QPushButton("Copy CLI Command")
        cli_copy_button.setFixedSize(140, 40)
        cli_copy_button.setStyleSheet(f"""
            QPushButton {{
                font-size: 12px;
                background: #007AFF;
                color: white;
                border: none;
                border-radius: 5px;
                font-weight: bold;
                {self.font_style}
            }}
            QPushButton:hover {{
                background: #0056CC;
            }}
            QPushButton:disabled {{
                background: #666666;
            }}
        """)
        cli_copy_button.clicked.connect(self.copy_cli_command)
        cli_copy_button.setEnabled(False)
        cli_buttons_layout.addWidget(cli_copy_button)


        
        command_layout.addLayout(cli_buttons_layout)

        find_buttons_layout = QHBoxLayout()
        
 
        
        command_layout.addLayout(find_buttons_layout)

        scroll_layout.addWidget(command_group)

        self.cli_copy_button = cli_copy_button

        wg_quick_group = QGroupBox("Direct Systemwide Wireguard")
        wg_quick_group.setStyleSheet(f"""
            QGroupBox {{
                color: white;
                font-weight: bold;
                border: 1px solid rgba(255, 255, 255, 0.1);
                border-radius: 8px;
                padding: 15px;
                font-size: 10px;
                margin-top: 15px;
                {self.font_style}
            }}
            QGroupBox::title {{
                subcontrol-origin: margin;
                left: 10px;
                padding: 0 5px;
            }}
        """)
        wg_quick_layout = QVBoxLayout(wg_quick_group)

        wg_quick_subtitle = QLabel("This uses your Linux system's Wireguard")
        wg_quick_subtitle.setStyleSheet(f"font-size: 10px; color: #CCCCCC; {self.font_style}")
        wg_quick_subtitle.setWordWrap(True)
        wg_quick_layout.addWidget(wg_quick_subtitle)

        self.wg_quick_up_command = QLineEdit()
        self.wg_quick_up_command.setReadOnly(True)
        self.wg_quick_up_command.setText("Select a profile above to see commands")
        self.wg_quick_up_command.setStyleSheet(f"""
            QLineEdit {{
                color: black;
                background: white;
                border: 1px solid rgba(255, 255, 255, 0.2);
                border-radius: 4px;
                padding: 8px;
                font-family: 'Courier New', monospace;
                font-size: 12px;
            }}
        """)
        wg_quick_layout.addWidget(self.wg_quick_up_command)

        copy_wg_up_button = QPushButton("Copy UP command")
        copy_wg_up_button.setFixedSize(140, 40)
        copy_wg_up_button.setStyleSheet(f"""
            QPushButton {{
                font-size: 10px;
                background: #4CAF50;
                color: white;
                border: none;
                border-radius: 5px;
                font-weight: bold;
                {self.font_style}
            }}
            QPushButton:hover {{
                background: #45a049;
            }}
        """)
        copy_wg_up_button.clicked.connect(self.copy_wg_quick_up_command)
        copy_wg_up_button.setEnabled(False)
        wg_quick_layout.addWidget(copy_wg_up_button)

        self.wg_quick_down_command = QLineEdit()
        self.wg_quick_down_command.setReadOnly(True)
        self.wg_quick_down_command.setText("Select a profile above to see commands")
        self.wg_quick_down_command.setStyleSheet(f"""
            QLineEdit {{
                color: black;
                background: white;
                border: 1px solid rgba(255, 255, 255, 0.2);
                border-radius: 4px;
                padding: 8px;
                font-family: 'Courier New', monospace;
                font-size: 12px;
            }}
        """)
        wg_quick_layout.addWidget(self.wg_quick_down_command)

        copy_wg_down_button = QPushButton("Copy DOWN command")
        copy_wg_down_button.setFixedSize(140, 40)
        copy_wg_down_button.setStyleSheet(f"""
            QPushButton {{
                font-size: 10px;
                background: #F44336;
                color: white;
                border: none;
                border-radius: 5px;
                font-weight: bold;
                {self.font_style}
            }}
            QPushButton:hover {{
                background: #d32f2f;
            }}
        """)
        copy_wg_down_button.clicked.connect(self.copy_wg_quick_down_command)
        copy_wg_down_button.setEnabled(False)
        wg_quick_layout.addWidget(copy_wg_down_button)

        self.wg_quick_up_button = copy_wg_up_button
        self.wg_quick_down_button = copy_wg_down_button
        

        self.wg_quick_up_command_widget = self.wg_quick_up_command
        self.wg_quick_down_command_widget = self.wg_quick_down_command

        scroll_layout.addWidget(wg_quick_group)


        self.update_debug_profile_list()

        scroll_area.setWidget(scroll_content)
        layout.addWidget(scroll_area)
        
        return page

    def copy_cli_command(self):
        clipboard = QApplication.clipboard()
        clipboard.setText(self.cli_command.text())
        self.update_status.update_status("CLI command copied to clipboard")

    def execute_cli_command(self):
        try:
            command = self.cli_command.text().split()
            subprocess.Popen(command)
            self.update_status.update_status("CLI command executed")
        except Exception as e:
            self.update_status.update_status(f"Error executing command: {str(e)}")

    def copy_find_command(self, command_text):
        clipboard = QApplication.clipboard()
        clipboard.setText(command_text)
        self.update_status.update_status("Find command copied to clipboard")

    def execute_find_command(self, command_text):
        try:
            command = command_text.split()
            subprocess.Popen(command)
            self.update_status.update_status("Find command executed")
        except Exception as e:
            self.update_status.update_status(f"Error executing find command: {str(e)}")

    def update_debug_profile_list(self):
        self.debug_profile_selector.clear()
        profiles = ProfileController.get_all()
        system_profiles = {pid: profile for pid, profile in profiles.items() if isinstance(profile, SystemProfile)}
        
        if system_profiles:
            for profile_id, profile in system_profiles.items():
                self.debug_profile_selector.addItem(f"Profile {profile_id}: {profile.name}", profile_id)
        else:
            self.debug_profile_selector.addItem("No system-wide profiles found", None)

    def on_debug_profile_selected(self, text):
        profile_id = self.debug_profile_selector.currentData()
        if profile_id is None:
            self.ping_instruction_label.hide()
            self.copy_ping_button.setEnabled(False)
            self.test_ping_button.setEnabled(False)
            self.ping_result_label.hide()
            self.cli_command.setText("Select a profile above to see command")
            self.cli_copy_button.setEnabled(False)
            if hasattr(self, 'wg_quick_up_command_widget'):
                self.wg_quick_up_command_widget.setText("Select a profile above to see commands")
                self.wg_quick_down_command_widget.setText("Select a profile above to see commands")
                self.wg_quick_up_button.setEnabled(False)
                self.wg_quick_down_button.setEnabled(False)
            return

        profile = ProfileController.get(profile_id)

        

        if profile and isinstance(profile, SystemProfile):
            app_path = os.environ.get('APPIMAGE') or "/path/to/hydra-veil"
            self.cli_command.setText(f"'{app_path}' --cli profile enable -i {profile_id}")
            self.cli_copy_button.setEnabled(True)
            ip_address = self.extract_endpoint_ip(profile)
            if ip_address:
                self.ping_instruction_label.setText(f"Step 1, Can you Ping it? Copy-paste the command below into your terminal. This VPN Node's IP address is {ip_address}")
                self.ping_instruction_label.show()
                self.copy_ping_button.setEnabled(True)
                self.test_ping_button.setEnabled(True)
                self.ping_result_label.hide()
                
                
                
                if hasattr(self, 'wg_quick_up_command_widget'):
                    self.wg_quick_up_command_widget.setText(f"sudo wg-quick up '/etc/hydra-veil/profiles/{profile_id}/wg.conf'")
                    self.wg_quick_down_command_widget.setText(f"sudo wg-quick down '/etc/hydra-veil/profiles/{profile_id}/wg.conf'")
                    self.wg_quick_up_button.setEnabled(True)
                    self.wg_quick_down_button.setEnabled(True)
            else:
                self.ping_instruction_label.setText("Could not extract IP address from WireGuard configuration")
                self.ping_instruction_label.show()
                self.copy_ping_button.setEnabled(False)
                self.test_ping_button.setEnabled(False)
                self.ping_result_label.hide()

                if hasattr(self, 'wg_quick_up_command_widget'):
                    self.wg_quick_up_command_widget.setText("Could not load profile configuration")
                    self.wg_quick_down_command_widget.setText("Could not load profile configuration")
                    self.wg_quick_up_button.setEnabled(False)
                    self.wg_quick_down_button.setEnabled(False)

    def extract_endpoint_ip(self, profile):
        try:
            profile_path = Constants.HV_PROFILE_CONFIG_HOME + f'/{profile.id}'
            wg_conf_path = f'{profile_path}/wg.conf.bak'
            if not os.path.exists(wg_conf_path):
                return None
            
            with open(wg_conf_path, 'r') as f:
                content = f.read()
            
            for line in content.split('\n'):
                if line.strip().startswith('Endpoint = '):
                    endpoint = line.strip().split(' = ')[1]
                    ip_address = endpoint.split(':')[0]
                    return ip_address
            return None
        except Exception:
            return None
    def copy_ping_command(self):
        profile_id = self.debug_profile_selector.currentData()
        if profile_id is None:
            return

        profile = ProfileController.get(profile_id)
        if profile and isinstance(profile, SystemProfile):
            ip_address = self.extract_endpoint_ip(profile)
            if ip_address:
                ping_command = f"ping {ip_address}"
                clipboard = QApplication.clipboard()
                clipboard.setText(ping_command)
                self.update_status.update_status("Ping command copied to clipboard")

    def test_ping_connection(self):
        profile_id = self.debug_profile_selector.currentData()
        if profile_id is None:
            return

        profile = ProfileController.get(profile_id)
        if profile and isinstance(profile, SystemProfile):
            ip_address = self.extract_endpoint_ip(profile)
            if ip_address:
                self.test_ping_button.setEnabled(False)
                self.ping_result_label.setText("Testing ping...")
                self.ping_result_label.setStyleSheet(f"color: #FFA500; font-size: 12px; font-weight: bold; {self.font_style}")
                self.ping_result_label.show()
                
                def ping_test():
                    try:
                        if sys.platform == "win32":
                            result = subprocess.run(['ping', '-n', '4', ip_address], 
                                                  capture_output=True, text=True, timeout=10)
                        else:
                            result = subprocess.run(['ping', '-c', '4', ip_address], 
                                                  capture_output=True, text=True, timeout=10)
                        if result.returncode == 0:
                            self.ping_result_label.setText("✅ Ping successful - Connection is working!")
                            self.ping_result_label.setStyleSheet(f"color: #4CAF50; font-size: 12px; font-weight: bold; {self.font_style}")
                        else:
                            self.ping_result_label.setText("❌ Ping failed - Connection issue detected")
                            self.ping_result_label.setStyleSheet(f"color: #F44336; font-size: 12px; font-weight: bold; {self.font_style}")
                    except subprocess.TimeoutExpired:
                        self.ping_result_label.setText("❌ Ping timeout - Connection issue detected")
                        self.ping_result_label.setStyleSheet(f"color: #F44336; font-size: 12px; font-weight: bold; {self.font_style}")
                    except Exception as e:
                        self.ping_result_label.setText(f"❌ Ping error: {str(e)}")
                        self.ping_result_label.setStyleSheet(f"color: #F44336; font-size: 12px; font-weight: bold; {self.font_style}")
                    finally:
                        self.test_ping_button.setEnabled(True)
                
                threading.Thread(target=ping_test, daemon=True).start()

    def copy_wg_quick_up_command(self):
        clipboard = QApplication.clipboard()
        clipboard.setText(self.wg_quick_up_command_widget.text())
        self.update_status.update_status("wg-quick UP command copied to clipboard")

    def copy_wg_quick_down_command(self):
        clipboard = QApplication.clipboard()
        clipboard.setText(self.wg_quick_down_command_widget.text())
        self.update_status.update_status("wg-quick DOWN command copied to clipboard")

    def on_profile_selected(self, button):
        self.delete_button.setEnabled(True)
        self.selected_profile_id = self.profile_buttons.id(button)

    def delete_selected_profile(self):
        if hasattr(self, 'selected_profile_id'):
            self.popup = ConfirmationPopup(
                self,
                message=f"Are you sure you want to delete Profile {self.selected_profile_id}?",
                action_button_text="Delete",
                cancel_button_text="Cancel"
            )
            self.popup.setWindowModality(Qt.WindowModality.ApplicationModal)
            self.popup.finished.connect(self.handle_delete_confirmation)
            self.popup.show()

    def handle_delete_confirmation(self, confirmed):
        if confirmed:
            self.update_status.update_status(f'Deleting profile...')
            self.worker_thread = WorkerThread('DESTROY_PROFILE', profile_data={'id': self.selected_profile_id})
            self.worker_thread.text_output.connect(self.delete_status_update)
            self.worker_thread.start()
            

    def delete_status_update(self, message):
        self.update_status.update_status(message)
        self.content_layout.removeWidget(self.delete_page)
        self.delete_page = self.create_delete_page()
        self.content_layout.addWidget(self.delete_page)
        self.content_layout.setCurrentWidget(self.delete_page)

    

    def get_combobox_style(self) -> str:
        return f"""
            QComboBox {{
                color: black;
                background: #f0f0f0;
                padding: 5px 30px 5px 10px;
                border: 1px solid #ccc;
                border-radius: 4px;
                min-width: 120px;
                margin-bottom: 10px;
                {self.font_style}
            }}
            QComboBox:disabled {{
                color: #666;
                background: #e0e0e0;
            }}
            QComboBox::drop-down {{
                border: none;
                width: 30px;
            }}
            QComboBox::down-arrow {{
                image: url(assets/down_arrow.png);
                width: 12px;
                height: 12px;
            }}
            QComboBox QAbstractItemView {{
                color: black;
                background: white;
                selection-background-color: #007bff;
                selection-color: white;
                border: 1px solid #ccc;
                {self.font_style}
            }}
        """

    def get_checkbox_style(self) -> str:
        return f"""
            QCheckBox {{
                color: white;
                spacing: 10px;
                margin-top: 10px;
                margin-bottom: 10px;
                font-size: 14px;
                {self.font_style}
            }}
            QCheckBox::indicator {{
                width: 18px;
                height: 18px;
                border: 2px solid #666666;
                border-radius: 3px;
                background-color: #2a2a2a;
            }}
            QCheckBox::indicator:checked {{
                background-color: #4CAF50;
                border: 2px solid #4CAF50;
            }}
            QCheckBox::indicator:unchecked {{
                background-color: #2a2a2a;
                border: 2px solid #666666;
            }}
            QCheckBox::indicator:hover {{
                border: 2px solid #888888;
            }}
        """

    def populate_wireguard_profiles(self) -> None:
        self.wireguard_profile_selector.clear()
        profiles = ProfileController.get_all()
        for profile_id, profile in profiles.items():
            if profile.connection.code == 'wireguard':
                
                self.wireguard_profile_selector.addItem(f"Profile {profile_id}: {profile.name}", profile_id)



    def convert_duration(self, value: Union[str, int], to_hours: bool = True) -> Union[str, int]:
        if to_hours:
            number, unit = value.split(' ')
            number = int(number)
            if unit in ['day', 'days']:
                return number * 24
            elif unit in ['week', 'weeks']:
                return number * 7 * 24
            else:
                raise ValueError(f"Unsupported duration unit: {unit}")
        else:
            hours = int(value)
            if hours % (7 * 24) == 0:
                weeks = hours // (7 * 24)
                return f"{weeks} {'week' if weeks == 1 else 'weeks'}"
            elif hours % 24 == 0:
                days = hours // 24
                return f"{days} {'day' if days == 1 else 'days'}"
            else:
                raise ValueError(f"Hours value {hours} cannot be converted to days or weeks cleanly")



    def show_account_page(self):
        self.content_layout.setCurrentWidget(self.account_page)
        self.update_button_states(0)


    def show_subscription_page(self):
        self.content_layout.setCurrentWidget(self.subscription_page)
        self.update_button_states(1)

    def show_registrations_page(self):
        self.content_layout.setCurrentWidget(self.registrations_page)
        self.update_button_states(2)

    def show_verification_page(self):
        self.content_layout.setCurrentWidget(self.verification_page)
        self.update_button_states(3)

    def show_delete_page(self):
        self.content_layout.setCurrentWidget(self.delete_page)
        self.update_button_states(4)

    def show_logs_page(self):
        self.content_layout.setCurrentWidget(self.logs_page)
        self.update_button_states(5)

    def show_debug_page(self):
        self.content_layout.setCurrentWidget(self.debug_page)
        self.update_button_states(6)

    def update_button_states(self, active_index):
        for i, btn in enumerate(self.menu_buttons):
            btn.setChecked(i == active_index)

    def reverse(self):
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage)))

    def create_subscription_page(self):
        page = QWidget()
        layout = QVBoxLayout(page)
        layout.setSpacing(20)
        layout.setContentsMargins(20, 20, 20, 20)

        title = QLabel("Subscription Info")
        title.setStyleSheet(f"color: #808080; font-size: 12px; font-weight: bold; {self.font_style}")
        layout.addWidget(title)

        profile_group = QGroupBox("Profile Selection")
        profile_group.setStyleSheet(f"""
            QGroupBox {{
                color: white;
                font-weight: bold;
                border: 1px solid rgba(255, 255, 255, 0.1);
                border-radius: 8px;
                padding: 15px;
                margin-top: 15px;
                {self.font_style}
            }}
            QGroupBox::title {{
                subcontrol-origin: margin;
                left: 10px;
                padding: 0 5px;
            }}
        """)
        profile_layout = QVBoxLayout(profile_group)

        self.profile_selector = QComboBox()
        self.profile_selector.setStyleSheet(self.get_combobox_style())
        profiles = ProfileController.get_all()
        if profiles:
            for profile_id, profile in profiles.items():
                self.profile_selector.addItem(f"Profile {profile_id}: {profile.name}", profile_id)
        profile_layout.addWidget(self.profile_selector)
        layout.addWidget(profile_group)

        subscription_group = QGroupBox("Subscription Details")
        subscription_group.setStyleSheet(f"""
            QGroupBox {{
                color: white;
                font-weight: bold;
                border: 1px solid rgba(255, 255, 255, 0.1);
                border-radius: 8px;
                padding: 15px;
                margin-top: 15px;
                {self.font_style}
            }}
            QGroupBox::title {{
                subcontrol-origin: margin;
                left: 10px;
                padding: 0 5px;
            }}
        """)
        subscription_layout = QGridLayout(subscription_group)
        subscription_layout.setSpacing(10)

        self.subscription_info = {}
        info_items = [
            ("Billing Code", "billing_code"),
            ("Expires At", "expires_at")
        ]

        for i, (label, key) in enumerate(info_items):
            if key == "billing_code":
                billing_container = QWidget()
                billing_layout = QVBoxLayout(billing_container)
                billing_layout.setContentsMargins(0, 0, 0, 0)
                billing_layout.setSpacing(5)
                
                stat_widget = self.create_stat_widget(label, "N/A")
                billing_layout.addWidget(stat_widget)
                
                copy_button = QPushButton("Copy")
                copy_button.setFixedSize(60, 30)
                copy_button.setStyleSheet(f"""
                    QPushButton {{
                        background: #007AFF;
                        color: white;
                        border: none;
                        border-radius: 4px;
                        font-size: 11px;
                        font-weight: bold;
                        {self.font_style}
                    }}
                    QPushButton:hover {{
                        background: #0056CC;
                    }}
                """)
                copy_button.clicked.connect(lambda: self.copy_billing_code())
                billing_layout.addWidget(copy_button)
                
                row, col = divmod(i, 2)
                subscription_layout.addWidget(billing_container, row, col)
                
                old_label = stat_widget.findChild(QLabel, "value_label")
                if old_label:
                    old_label.setParent(None)
                    old_label.deleteLater()
                
                value_label = ClickableValueLabel("N/A", stat_widget)
                value_label.setObjectName("value_label")
                value_label.setStyleSheet(f"color: #00ffff; font-size: 12px; font-family: 'Retro Gaming', sans-serif;")
                value_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
                stat_widget.layout().insertWidget(0, value_label)
                
                self.subscription_info[key] = value_label
            else:
                stat_widget = self.create_stat_widget(label, "N/A")
                row, col = divmod(i, 2)
                subscription_layout.addWidget(stat_widget, row, col)
                
                old_label = stat_widget.findChild(QLabel, "value_label")
                if old_label:
                    old_label.setParent(None)
                    old_label.deleteLater()
                
                value_label = ClickableValueLabel("N/A", stat_widget)
                value_label.setObjectName("value_label")
                value_label.setStyleSheet(f"color: #00ffff; font-size: 12px; font-family: 'Retro Gaming', sans-serif;")
                value_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
                stat_widget.layout().insertWidget(0, value_label)
                
                self.subscription_info[key] = value_label

        layout.addWidget(subscription_group)
        
        clipboard_hint = QLabel("💡 Click on the billing code or use the Copy button to copy it to clipboard")
        clipboard_hint.setStyleSheet(f"color: #666666; font-size: 11px; font-style: italic; {self.font_style}")
        clipboard_hint.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(clipboard_hint)
        
        layout.addStretch()

        self.profile_selector.currentIndexChanged.connect(self.update_subscription_info)
        if self.profile_selector.count() > 0:
            self.update_subscription_info(0)

        return page

    def create_verification_page(self):
        page = QWidget()
        layout = QVBoxLayout(page)
        layout.setSpacing(20)
        layout.setContentsMargins(20, 20, 20, 20)

        title = QLabel("Verification Information")
        title.setStyleSheet(f"color: #808080; font-size: 12px; font-weight: bold; {self.font_style}")
        layout.addWidget(title)

        profile_label = QLabel("Profile Selection:")
        profile_label.setStyleSheet(f"color: white; font-size: 14px; {self.font_style}")
        layout.addWidget(profile_label)

        self.verification_profile_selector = QComboBox()
        self.verification_profile_selector.setStyleSheet(self.get_combobox_style())
        profiles = ProfileController.get_all()
        if profiles:
            for profile_id, profile in profiles.items():
                self.verification_profile_selector.addItem(f"Profile {profile_id}: {profile.name}", profile_id)
        layout.addWidget(self.verification_profile_selector)

        details_label = QLabel("Verification Details:")
        details_label.setStyleSheet(f"color: white; font-size: 14px; margin-top: 20px; {self.font_style}")
        layout.addWidget(details_label)

        verification_layout = QVBoxLayout()
        verification_layout.setSpacing(15)
        self.verification_info = {}
        self.verification_checkmarks = {}
        self.verification_full_values = {}  
        info_items = [
            ("Operator Name", "operator_name"),
            ("Nostr Key", "nostr_public_key"),
            ("HydraVeil Key", "hydraveil_public_key"),
            ("Nostr Verification", "nostr_attestation_event_reference"),
        ]

        for label, key in info_items:
            container = QWidget()
            container_layout = QHBoxLayout(container)
            container_layout.setContentsMargins(0, 0, 0, 0)
            container_layout.setSpacing(10)

            label_widget = QLabel(label + ":")
            label_widget.setStyleSheet(f"color: white; font-size: 12px; {self.font_style}")
            label_widget.setMinimumWidth(120)
            container_layout.addWidget(label_widget)

            value_widget = QLineEdit()
            value_widget.setReadOnly(True)
            value_widget.setText("N/A")
            value_widget.setStyleSheet(f"""
                QLineEdit {{
                    color: white;
                    background: transparent;
                    border: none;
                    border-bottom: 1px solid rgba(255, 255, 255, 0.3);
                    padding: 5px 0px;
                    font-size: 12px;
                    {self.font_style}
                }}
            """)
            container_layout.addWidget(value_widget, 1)

            checkmark_widget = QLabel("✓")
            checkmark_widget.setStyleSheet(f"color: #4CAF50; font-size: 20px; font-weight: bold; {self.font_style}")
            checkmark_widget.setFixedSize(20, 20)
            checkmark_widget.setAlignment(Qt.AlignmentFlag.AlignCenter)
            checkmark_widget.hide()  
            container_layout.addWidget(checkmark_widget)

            copy_button = QPushButton()
            copy_button.setIcon(QIcon(os.path.join(self.btn_path, "paste_button.png")))
            copy_button.setIconSize(QSize(24, 24))
            copy_button.setFixedSize(30, 30)
            copy_button.setStyleSheet(f"""
                QPushButton {{
                    background: transparent;
                    border: none;
                }}
                QPushButton:hover {{
                    background: rgba(255, 255, 255, 0.1);
                    border-radius: 4px;
                }}
            """)
            copy_button.clicked.connect(lambda checked=False, k=key: self.copy_verification_value(k))
            container_layout.addWidget(copy_button)

            verification_layout.addWidget(container)
            self.verification_info[key] = value_widget
            self.verification_checkmarks[key] = checkmark_widget

        layout.addLayout(verification_layout)
        layout.addStretch()


        endpoint_verification_label = QLabel("Endpoint Verification:", page)
        endpoint_verification_label.setGeometry(20, 420, 150, 20)
        endpoint_verification_label.setStyleSheet(f"color: white; font-size: 15px; {self.font_style}")
        endpoint_verification_label.show()

        self.endpoint_verification_checkbox = QCheckBox(page)
        self.endpoint_verification_checkbox.setGeometry(180, 415, 30, 30)
        self.endpoint_verification_checkbox.setChecked(ConfigurationController.get_endpoint_verification_enabled())
        self.endpoint_verification_checkbox.setStyleSheet(self.get_checkbox_style())
        self.endpoint_verification_checkbox.show()

        save_button = QPushButton(page)
        save_button.setGeometry(350, 410, 60, 31)
        save_button.setIcon(QIcon(os.path.join(self.btn_path, "save.png")))
        save_button.setIconSize(QSize(60, 31))
        save_button.clicked.connect(self.save_verification_settings)
        save_button.show()

        self.verification_profile_selector.currentIndexChanged.connect(self.update_verification_info)
        self.verification_profile_selector.activated.connect(self.update_verification_info)
        if self.verification_profile_selector.count() > 0:
            self.update_verification_info(0)

        return page

    def truncate_key(self, text, max_length=50):
        """Truncate text in the middle, showing start and end parts."""
        if not text or text == "N/A" or len(text) <= max_length:
            return text
        start_len = max_length // 2 - 2
        end_len = max_length // 2 - 2
        return text[:start_len] + "....." + text[-end_len:]
    
    def update_verification_info(self, index):
        if index < 0:
            return

        profile_id = self.verification_profile_selector.itemData(index)
        if profile_id is None:
            for key, widget in self.verification_info.items():
                widget.setText("N/A")
                self.verification_full_values[key] = "N/A"
                if key in self.verification_checkmarks:
                    self.verification_checkmarks[key].hide()
            return

        profile = ProfileController.get(profile_id)
        if not profile:
            for key, widget in self.verification_info.items():
                widget.setText("N/A")
                self.verification_full_values[key] = "N/A"
                if key in self.verification_checkmarks:
                    self.verification_checkmarks[key].hide()
            return

        operator = None
        if profile.location and profile.location.operator:
            operator = profile.location.operator

        if operator:
            operator_name = operator.name or "N/A"
            self.verification_full_values["operator_name"] = operator_name
            self.verification_info["operator_name"].setText(operator_name)
            
            nostr_key = operator.nostr_public_key or "N/A"
            self.verification_full_values["nostr_public_key"] = nostr_key
            self.verification_info["nostr_public_key"].setText(self.truncate_key(nostr_key) if nostr_key != "N/A" else nostr_key)
            
            hydraveil_key = operator.public_key or "N/A"
            self.verification_full_values["hydraveil_public_key"] = hydraveil_key
            self.verification_info["hydraveil_public_key"].setText(self.truncate_key(hydraveil_key) if hydraveil_key != "N/A" else hydraveil_key)
            
            nostr_verification = operator.nostr_attestation_event_reference or "N/A"
            self.verification_full_values["nostr_attestation_event_reference"] = nostr_verification
            self.verification_info["nostr_attestation_event_reference"].setText(self.truncate_key(nostr_verification) if nostr_verification != "N/A" else nostr_verification)
        else:
            self.verification_info["operator_name"].setText("N/A")
            self.verification_full_values["operator_name"] = "N/A"
            self.verification_info["nostr_public_key"].setText("N/A")
            self.verification_full_values["nostr_public_key"] = "N/A"
            self.verification_info["hydraveil_public_key"].setText("N/A")
            self.verification_full_values["hydraveil_public_key"] = "N/A"
            self.verification_info["nostr_attestation_event_reference"].setText("N/A")
            self.verification_full_values["nostr_attestation_event_reference"] = "N/A"
        
        for key, widget in self.verification_info.items():
            if key in self.verification_checkmarks:
                full_value = self.verification_full_values.get(key, "")
                if full_value and full_value != "N/A":
                    self.verification_checkmarks[key].show()
                else:
                    self.verification_checkmarks[key].hide()

    def save_verification_settings(self):
        try:
            ConfigurationController.set_endpoint_verification_enabled(self.endpoint_verification_checkbox.isChecked())
            self.update_status.update_status("Verification settings saved successfully")
        except Exception as e:
            logging.error(f"Error saving verification settings: {str(e)}")
            self.update_status.update_status("Error saving verification settings")

    def copy_verification_value(self, key):
        """Copy the full verification value (not truncated) to clipboard."""
        full_value = self.verification_full_values.get(key, "")
        if full_value and full_value != "N/A":
            clipboard = QApplication.clipboard()
            clipboard.setText(full_value)
            verification_display_names = {
                "operator_name": "Operator Name",
                "nostr_public_key": "Nostr Key",
                "hydraveil_public_key": "HydraVeil Key",
                "nostr_attestation_event_reference": "Nostr Verification"
            }
            display_name = verification_display_names.get(key, "Verification value")
            self.update_status.update_status(f"{display_name} copied to clipboard")

    def update_subscription_info(self, index):
        if index < 0:
            return

        profile_id = self.profile_selector.itemData(index)
        if profile_id is None:
            return

        profile = ProfileController.get(profile_id)
        
        if profile and hasattr(profile, 'subscription') and profile.subscription:
            try:
                self.subscription_info["billing_code"].setText(str(profile.subscription.billing_code))
                
                if hasattr(profile.subscription, 'expires_at') and profile.subscription.expires_at:
                    expires_at = profile.subscription.expires_at.strftime("%Y-%m-%d %H:%M:%S UTC")
                    self.subscription_info["expires_at"].setText(expires_at)
                else:
                    self.subscription_info["expires_at"].setText("Not available")
            except Exception as e:
                print(f"Error updating subscription info: {e}")
        else:
            for label in self.subscription_info.values():
                label.setText("N/A")

    def copy_billing_code(self):
        if "billing_code" in self.subscription_info:
            billing_code = self.subscription_info["billing_code"].text()
            if billing_code and billing_code != "N/A":
                clipboard = QApplication.clipboard()
                clipboard.setText(billing_code)
                self.update_status.update_status("Billing code copied to clipboard")
            else:
                self.update_status.update_status("No billing code available to copy")

    def showEvent(self, event):
        super().showEvent(event)
        
        current_index = self.content_layout.currentIndex()
        
        self.content_layout.removeWidget(self.account_page)
        self.account_page = self.create_account_page()
        self.content_layout.addWidget(self.account_page)


        self.content_layout.removeWidget(self.subscription_page)
        self.subscription_page = self.create_subscription_page()
        self.content_layout.addWidget(self.subscription_page)

        self.content_layout.removeWidget(self.registrations_page)
        self.registrations_page = self.create_registrations_page()
        self.content_layout.addWidget(self.registrations_page)

        self.content_layout.removeWidget(self.verification_page)
        self.verification_page = self.create_verification_page()
        self.content_layout.addWidget(self.verification_page)

        self.content_layout.removeWidget(self.logs_page)
        self.logs_page = self.create_logs_page()
        self.content_layout.addWidget(self.logs_page)

        self.content_layout.removeWidget(self.delete_page)
        self.delete_page = self.create_delete_page()
        self.content_layout.addWidget(self.delete_page)

        self.content_layout.removeWidget(self.debug_page)
        self.debug_page = self.create_debug_page()
        self.content_layout.addWidget(self.debug_page)

        self.content_layout.setCurrentIndex(current_index)
        
        if self.content_layout.currentWidget() == self.subscription_page:
            if self.profile_selector.count() > 0:
                self.update_subscription_info(0)
    def create_account_page(self):
        page = QWidget()
        layout = QVBoxLayout(page)
        layout.setSpacing(20)
        layout.setContentsMargins(20, 20, 20, 20)

        title = QLabel("Account Overview")
        title.setStyleSheet(f"color: #808080; font-size: 12px; font-weight: bold; {self.font_style}")
        layout.addWidget(title)

        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_area.setStyleSheet(f"""
            QScrollArea {{
                border: none;
                background: transparent;
            }}
            QScrollArea > QWidget > QWidget {{
                background: transparent;
            }}
        """)

        scroll_content = QWidget()
        scroll_layout = QVBoxLayout(scroll_content)
        scroll_layout.setSpacing(15)

        info_sections = [
            ("Profile Statistics", self.create_profile_stats()),
            ("System Resources", self.create_system_stats())
        ]

        for section_title, content_widget in info_sections:
            group = QGroupBox(section_title)
            group.setStyleSheet(f"""
                QGroupBox {{
                    color: white;
                    font-weight: bold;
                    border: 1px solid rgba(255, 255, 255, 0.1);
                    border-radius: 8px;
                    padding: 15px;
                    margin-top: 15px;
                    {self.font_style}
                }}
                QGroupBox::title {{
                    subcontrol-origin: margin;
                    left: 10px;
                    padding: 0 5px;
                }}
            """)
            group_layout = QVBoxLayout(group)
            group_layout.addWidget(content_widget)
            scroll_layout.addWidget(group)

        scroll_area.setWidget(scroll_content)
        layout.addWidget(scroll_area)
        return page

    def create_profile_stats(self):
        widget = QWidget()
        layout = QGridLayout(widget)
        layout.setSpacing(10)

        profiles = ProfileController.get_all()
        total_profiles = len(profiles)
        session_profiles = sum(1 for p in profiles.values() if isinstance(p, SessionProfile))
        system_profiles = sum(1 for p in profiles.values() if isinstance(p, SystemProfile))
        active_profiles = sum(
            1 for p in profiles.values() 
            if p.subscription and p.subscription.expires_at and p.subscription.expires_at > datetime.now(timezone.utc)
        )

        stats = [
            ("Total Profiles", total_profiles),
            ("Browser-only", session_profiles),
            ("System-wide", system_profiles),
            ("Active Profiles", active_profiles)
        ]

        for i, (label, value) in enumerate(stats):
            stat_widget = self.create_stat_widget(label, value)
            row, col = divmod(i, 2)
            layout.addWidget(stat_widget, row, col)

        return widget




    def create_system_stats(self):
        widget = QWidget()
        layout = QGridLayout(widget)
        layout.setSpacing(10)

        config_path = Constants.HV_CONFIG_HOME

        current_connection = self.update_status.get_current_connection();

        if current_connection is not None:
            current_connection = current_connection.capitalize()

        stats = [
            ("Config Path", config_path),
            ("Client Version", Constants.HV_CLIENT_VERSION_NUMBER),
            ("Connection", current_connection),
        ]

        for i, (label, value) in enumerate(stats):
            info_widget = QLabel(f"{label}: {value}")
            info_widget.setStyleSheet(f"font-size: 14px; color: white; padding: 5px; {self.font_style}")
            info_widget.setWordWrap(True)
            layout.addWidget(info_widget, i, 0)

        return widget

    def create_stat_widget(self, label, value):
        widget = QFrame()
        widget.setStyleSheet(f"""
            QFrame {{
                background: rgba(255, 255, 255, 0.05);
                border-radius: 8px;
                padding: 10px;
                {self.font_style}
            }}
        """)
        layout = QVBoxLayout(widget)

        value_label = QLabel(str(value))
        value_label.setObjectName("value_label")  
        value_label.setStyleSheet("font-family: 'Retro Gaming', sans-serif; color: #00ffff; font-size: 22px; font-weight: bold")
        value_label.setAlignment(Qt.AlignmentFlag.AlignCenter)

        desc_label = QLabel(label)
        desc_label.setStyleSheet(f"color: white; font-size: 12px; {self.font_style}")
        desc_label.setAlignment(Qt.AlignmentFlag.AlignCenter)

        layout.addWidget(value_label)
        layout.addWidget(desc_label)
        return widget

    def create_horizontal_stat(self, label, value, total):
        widget = QWidget()
        layout = QHBoxLayout(widget)
        layout.setContentsMargins(0, 5, 0, 5)

        text_label = QLabel(f"{label}")
        text_label.setStyleSheet(f"color: white; font-size: 12px; {self.font_style}")
        text_label.setFixedWidth(100)

        progress = QFrame()
        progress.setStyleSheet("""
            QFrame {
                background: rgba(0, 255, 255, 0.3);
                border-radius: 3px;
            }
        """)
        percentage = (value / total) * 100 if total > 0 else 0
        progress.setFixedSize(int(200 * (percentage / 100)), 20)

        value_label = QLabel(f"{value} ({percentage:.1f}%)")
        value_label.setStyleSheet(f"color: white; font-size: 12px; {self.font_style}")
        value_label.setAlignment(Qt.AlignmentFlag.AlignRight)

        progress_container = QFrame()
        progress_container.setStyleSheet("""
            QFrame {
                background: rgba(255, 255, 255, 0.1);
                border-radius: 3px;
            }
        """)
        progress_container.setFixedSize(200, 20)
        progress_layout = QHBoxLayout(progress_container)
        progress_layout.setContentsMargins(0, 0, 0, 0)
        progress_layout.addWidget(progress)
        progress.setFixedHeight(20)

        layout.addWidget(text_label)
        layout.addWidget(progress_container)
        layout.addWidget(value_label)
        layout.addStretch()

        return widget

    def setup_pages(self):
        self.account_page = self.create_account_page()
        self.subscription_page = self.create_subscription_page()
        self.registrations_page = self.create_registrations_page()
        self.verification_page = self.create_verification_page()
        self.logs_page = self.create_logs_page()
        self.delete_page = self.create_delete_page()
        self.debug_page = self.create_debug_page()

        self.content_layout.addWidget(self.account_page)
        self.content_layout.addWidget(self.subscription_page)
        self.content_layout.addWidget(self.registrations_page)
        self.content_layout.addWidget(self.verification_page)
        self.content_layout.addWidget(self.logs_page)
        self.content_layout.addWidget(self.delete_page)
        self.content_layout.addWidget(self.debug_page)

        self.content_layout.setCurrentIndex(0)
        self.show_account_page()

    def create_logs_page(self):
        page = QWidget()
        layout = QVBoxLayout(page)
        layout.setSpacing(20)
        layout.setContentsMargins(20, 20, 20, 20)

        title = QLabel("LOGGING SETTINGS")
        title.setStyleSheet(f"color: #808080; font-size: 12px; font-weight: bold; {self.font_style}")
        layout.addWidget(title)

        log_text = QLabel(f"Enabling this feature means error logs will be stored on your local\nmachine at: '{Constants.HV_CACHE_HOME}/gui'.")
        log_text.setStyleSheet(f"color: white; font-size: 14px; {self.font_style}")
        layout.addWidget(log_text)

        logs_group = QGroupBox("Log Configuration")
        logs_group.setStyleSheet(f"QGroupBox {{ color: white; padding: 15px; {self.font_style} }}")
        logs_layout = QVBoxLayout(logs_group)

        self.enable_gui_logging = QCheckBox("Enable GUI logging")
        self.enable_gui_logging.setStyleSheet(self.get_checkbox_style())
        logs_layout.addWidget(self.enable_gui_logging)
        layout.addWidget(logs_group)

        save_button = QPushButton()
        save_button.setFixedSize(75, 46)
        save_button.setIcon(QIcon(os.path.join(self.btn_path, f"save.png")))
        save_button.setIconSize(QSize(75, 46))
        save_button.clicked.connect(self.save_logs_settings)

        button_layout = QHBoxLayout()
        button_layout.addStretch()
        button_layout.addWidget(save_button)
        layout.addLayout(button_layout)

        layout.addStretch()
        self.load_logs_settings()
        return page

    def load_logs_settings(self) -> None:
        try:
            config = self.update_status._load_gui_config()
            if config and "logging" in config:
                self.enable_gui_logging.setChecked(config["logging"]["gui_logging_enabled"])
        except Exception as e:
            logging.error(f"Error loading logging settings: {str(e)}")
            self.enable_gui_logging.setChecked(True)

    def save_logs_settings(self) -> None:
        try:
            config = self.update_status._load_gui_config()
            if config is None:
                config = {
                    "logging": {
                        "gui_logging_enabled": True,
                        "log_level": "INFO"
                    }
                }

            config["logging"]["gui_logging_enabled"] = self.enable_gui_logging.isChecked()
            
            self.update_status._save_gui_config(config)

            if self.enable_gui_logging.isChecked():
                self.update_status._setup_gui_logging()
            else:
                self.update_status.stop_gui_logging()


            self.update_status.update_status("Logging settings saved successfully")
            
        except Exception as e:
            logging.error(f"Error saving logging settings: {str(e)}")
            self.update_status.update_status("Error saving logging settings")

    def create_registrations_page(self):
        page = QWidget()
        layout = QVBoxLayout(page)
        layout.setSpacing(20)
        layout.setContentsMargins(20, 20, 20, 20)

        title = QLabel("Create/Edit SETTINGS")
        title.setStyleSheet(f"color: #808080; font-size: 15px; font-weight: bold; {self.font_style}")
        layout.addWidget(title)

        registrations_group = QGroupBox("Create/Edit Configuration")
        registrations_group.setStyleSheet(f"QGroupBox {{ color: white; font-size: 15px; padding: 15px; {self.font_style} }}")
        registrations_layout = QVBoxLayout(registrations_group)

        self.enable_auto_sync = QCheckBox("Enable auto-sync on Edit")
        self.enable_auto_sync.setStyleSheet(self.get_checkbox_style())
        registrations_layout.addWidget(self.enable_auto_sync)

        self.enable_fast_registration = QCheckBox("Enable Fast-mode for Profile Creation")
        self.enable_fast_registration.setStyleSheet(self.get_checkbox_style())
        registrations_layout.addWidget(self.enable_fast_registration)

        layout.addWidget(registrations_group)

        save_button = QPushButton()
        save_button.setFixedSize(75, 46)
        save_button.setIcon(QIcon(os.path.join(self.btn_path, f"save.png")))
        save_button.setIconSize(QSize(75, 46))
        save_button.clicked.connect(self.save_registrations_settings)

        button_layout = QHBoxLayout()
        button_layout.addWidget(save_button)
        button_layout.addStretch()
        layout.addLayout(button_layout)

        layout.addStretch()
        self.load_registrations_settings()
        return page

    def load_registrations_settings(self) -> None:
        try:
            config = self.update_status._load_gui_config()
            if config and "registrations" in config:
                self.enable_auto_sync.setChecked(config["registrations"]["auto_sync_enabled"])
                self.enable_fast_registration.setChecked(config["registrations"]["fast_registration_enabled"])
            else:
                self.enable_auto_sync.setChecked(False)
                self.enable_fast_registration.setChecked(False)
        except Exception as e:
            logging.error(f"Error loading registration settings: {str(e)}")
            self.enable_auto_sync.setChecked(False)
            self.enable_fast_registration.setChecked(False)

    def save_registrations_settings(self) -> None:
        try:
            config = self.update_status._load_gui_config()
            if config is None:
                config = {
                    "logging": {
                        "gui_logging_enabled": True,
                        "log_level": "INFO"
                    },
                    "registrations": {
                        "auto_sync_enabled": False,
                        "fast_registration_enabled": False
                    }
                }

            if "registrations" not in config:
                config["registrations"] = {}

            config["registrations"]["auto_sync_enabled"] = self.enable_auto_sync.isChecked()
            config["registrations"]["fast_registration_enabled"] = self.enable_fast_registration.isChecked()
            
            self.update_status._save_gui_config(config)
            self.update_status.update_status("Registration settings saved")
            
        except Exception as e:
            logging.error(f"Error saving registration settings: {str(e)}")
            self.update_status.update_status("Error saving registration settings")

    def is_auto_sync_enabled(self) -> bool:
        try:
            config = self.update_status._load_gui_config()
            if config and "registrations" in config:
                return config["registrations"]["auto_sync_enabled"]
            return False
        except Exception as e:
            logging.error(f"Error checking auto-sync setting: {str(e)}")
            return False

    def is_fast_registration_enabled(self) -> bool:
        try:
            config = self.update_status._load_gui_config()
            if config and "registrations" in config:
                return config["registrations"]["fast_registration_enabled"]
            return False
        except Exception as e:
            logging.error(f"Error checking fast registration setting: {str(e)}")
            return False

    

    

class IdPage(Page):
    def __init__(self, page_stack, main_window=None, parent=None):
        super().__init__("Id", page_stack, main_window, parent)
        self.update_status = main_window
        self.btn_path = main_window.btn_path
        self.buttonGroup = QButtonGroup(self)
        self.display.setGeometry(QtCore.QRect(-10, 50, 550, 460))
        # self.display.setPixmap(QPixmap(os.path.join(self.btn_path, "wireguardx.png")).scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio))
        self.create_interface_elements()


        self.connect_button = QPushButton(self)
        self.connect_button.setObjectName("connect_button")
        self.connect_button.setGeometry(625, 450, 90, 50)
        self.connect_button.setIconSize(self.connect_button.size())
        tor_icon = QIcon(os.path.join(self.btn_path, "connect.png"))
        self.connect_button.setIcon(tor_icon)
        self.connect_button.clicked.connect(self.on_connect)
        self.connect_button.setDisabled(True)

        self.button_reverse.setVisible(True)


    def on_connect(self):
        text = self.text_edit.toPlainText()
        import re
        pattern = r'^[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$' 
        if re.match(pattern, text):
            self.update_status.update_status('Enabling profile in progress...')
            profile_data = {
                'id' : int(self.update_status.current_profile_id),
                'billing_code': str(text)
            }
            menu_page = self.find_menu_page()
            if menu_page:
                menu_page.enabling_profile(profile_data)
            
        else:
            self.update_text_output('Incorrect format for the billing code')



    def find_menu_page(self):
        for i in range(self.page_stack.count()):
            page = self.page_stack.widget(i)
            if isinstance(page, MenuPage):
                return page
        return None
    

    def create_interface_elements(self):
        self.object_selected = None
        self.display.setGeometry(QtCore.QRect(5, 50, 550, 460))
        self.title = QLabel("Entry Id", self)
        self.title.setGeometry(QtCore.QRect(560, 50, 220, 40))
        self.title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        

        self.button_reverse.clicked.connect(self.reverse)
        self.button_go.clicked.connect(self.go_selected)

        objects_info = [
            (QPushButton, os.path.join(self.btn_path, "new_id.png"), self.show_next, DurationSelectionPage, (575, 100, 185, 75)),
            (QLabel, os.path.join(self.btn_path, "button230x220.png"), None, None, (550, 220, 250, 220)),
            (QTextEdit, None, self.validate_password, DurationSelectionPage, (550, 230, 230, 190))
]



        for obj_type, icon_name, function, page_class, geometry in objects_info:
            obj = obj_type(self)
            obj.setGeometry(*geometry)
            if isinstance(obj, QPushButton):
                obj.setIconSize(QtCore.QSize(190, 120))
                obj.setIcon(QtGui.QIcon(icon_name))
                obj.clicked.connect(lambda _, func=function, page=page_class: self.show_object_selected(func, page))

            elif isinstance(obj, QLabel):
                obj.setPixmap(QPixmap(icon_name).scaled(obj.size(), Qt.AspectRatioMode.KeepAspectRatio))

            elif isinstance(obj, QTextEdit):
                obj.setPlaceholderText("Or use an existing billing Id, enter it here")
                obj.textChanged.connect(self.toggle_button_state)
                self.text_edit = obj

    def toggle_button_state(self):
        text = self.text_edit.toPlainText()
        if text.strip():  
            self.connect_button.setEnabled(True)
        else:  
            self.connect_button.setEnabled(False)



    def show_next(self):

        self.text_edit.clear()
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(DurationSelectionPage)))


    def validate_password(self):
        self.button_go.setVisible(False)
        text = self.text_edit.toPlainText().strip().lower()
        
        # Comparar el texto con la palabra "zenaku" ignorando mayúsculas y minúsculas
        if text == "zenaku":
            self.button_go.setVisible(True)

    def show_object_selected(self, function, page_class):
        function()
        self.object_selected = page_class

    def go_selected(self):
        if self.object_selected:
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(self.object_selected)))
            self.display.clear()
            for boton in self.buttons:
                boton.setChecked(False)
            
            self.button_go.setVisible(False)

    def reverse(self):
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage)))


class ConfettiParticle:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.color = QColor(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
        self.size = random.randint(5, 15)
        self.speed = random.uniform(1, 3)

    def update(self):
        self.y += self.speed

class ConfettiThread(QThread):
    update_signal = pyqtSignal(list)

    def __init__(self, width, height):
        super().__init__()
        self.width = width
        self.height = height
        self.running = True
        self.mutex = QMutex()
        self.confetti = [ConfettiParticle(random.randint(0, width), random.randint(-height, 0)) for _ in range(100)]

    def run(self):
        while self.running:
            with QMutexLocker(self.mutex):
                for particle in self.confetti:
                    particle.update()
                    if particle.y > self.height:
                        particle.y = random.randint(-100, 0)
                        particle.x = random.randint(0, self.width)
            
            self.update_signal.emit(self.confetti.copy())
            self.msleep(16)  

    def stop(self):
        self.running = False

    def update_dimensions(self, width, height):
        with QMutexLocker(self.mutex):
            self.width = width
            self.height = height

class ClickableLabel(QLabel):
    clicked = pyqtSignal()

    def __init__(self, text, parent=None, **kwargs):
        super().__init__(text, parent, **kwargs)
        self.setCursor(Qt.CursorShape.PointingHandCursor)
        self.hover_width = self.width()  
        self.is_hovered = False

    def mousePressEvent(self, event):
        self.clicked.emit()
        super().mousePressEvent(event)

    def enterEvent(self, event):
        self.is_hovered = True
        self.update()
        super().enterEvent(event)

    def leaveEvent(self, event):
        self.is_hovered = False
        self.update()
        super().leaveEvent(event)

    def set_hover_width(self, width):
        self.hover_width = width
        self.update()

    def paintEvent(self, event):
        super().paintEvent(event)
        if self.is_hovered:
            painter = QPainter(self)
            painter.setRenderHint(QPainter.RenderHint.Antialiasing)
            hover_color = QColor(255, 255, 255, 25)  
            
            center_x = self.width() // 2
            start_x = center_x - (self.hover_width // 2)
            painter.fillRect(start_x, 0, self.hover_width, self.height(), hover_color)
            painter.end()
class PaymentConfirmed(Page):
    def __init__(self, page_stack, main_window=None, parent=None):
        super().__init__("Id", page_stack, main_window, parent)
        
        self.update_status = main_window
        self.buttonGroup = QButtonGroup(self)
        self.display.setGeometry(QRect(-10, 50, 550, 460))
        # self.display.setPixmap(QPixmap(os.path.join(self.btn_path, f"wireguardx.png")).scaled(self.display.size(), Qt.AspectRatioMode.KeepAspectRatio))

        self.button_reverse.setVisible(False)

        self.confetti = []
        
        self.icon_label = QLabel(self)
        icon = QIcon(os.path.join(self.btn_path, "check_icon.png"))
        pixmap = icon.pixmap(QSize(64, 64))
        self.icon_label.setPixmap(pixmap)
        self.icon_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        
        self.label = QLabel("Payment Completed!", alignment=Qt.AlignmentFlag.AlignCenter, parent=self)
        self.label.setStyleSheet("font-size: 24px; color: #2ecc71; font-weight: bold;")
        
        self.billing_label = QLabel("Your billing code:", alignment=Qt.AlignmentFlag.AlignCenter, parent=self)
        self.billing_label.setStyleSheet("font-size: 18px; color: white;")
        
        self.billing_code = ClickableLabel("", alignment=Qt.AlignmentFlag.AlignCenter, parent=self)
        self.billing_code.setStyleSheet("""
            font-size: 24px;
            color: white;
            font-weight: bold;
            padding: 5px;
            border-radius: 5px;
        """)
        self.billing_code.clicked.connect(self.copy_billing_code)
        self.billing_code.set_hover_width(450)
        
        self.top_line = QFrame(self)
        self.top_line.setFrameShape(QFrame.Shape.HLine)
        self.top_line.setStyleSheet("color: #bdc3c7;")
        
        self.bottom_line = QFrame(self)
        self.bottom_line.setFrameShape(QFrame.Shape.HLine)
        self.bottom_line.setStyleSheet("color: #bdc3c7;")
        
        self.next_button = QPushButton("Next", self)
        self.next_button.setStyleSheet("""
            QPushButton {
                background-color: #3498db;
                color: white;
                border: none;
                padding: 10px;
                font-size: 18px;
                border-radius: 5px;
            }
            QPushButton:hover {
                background-color: #2980b9;
            }
        """)
        self.next_button.clicked.connect(self.on_next_button)
        
        self.confetti_thread = ConfettiThread(self.width(), self.height())
        self.confetti_thread.update_signal.connect(self.update_confetti)
        self.confetti_thread.start()


    def copy_billing_code(self):
        clipboard = QApplication.clipboard()
        clipboard.setText(self.billing_code.text())

        original_style = self.billing_code.styleSheet()

        self.billing_code.setText("Copied!")
        self.billing_code.setStyleSheet(original_style + "background-color: #27ae60;")

        QTimer.singleShot(1000, lambda: self.reset_billing_code_style(original_style))

    def reset_billing_code_style(self, original_style):
        self.billing_code.setStyleSheet(original_style)
        self.billing_code.setText(self.current_billing_code)


    def set_billing_code(self, code):
        self.current_billing_code = code
        self.billing_code.setText(code)

    def update_confetti(self, confetti):
        self.confetti = confetti
        self.update()

    def paintEvent(self, event):
        super().paintEvent(event)  
        
        painter = QPainter(self)
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)
        
        for particle in self.confetti:
            painter.setBrush(particle.color)
            painter.setPen(Qt.PenStyle.NoPen)
            painter.drawEllipse(QPointF(particle.x, particle.y), particle.size, particle.size)
        
        painter.end()

    def resizeEvent(self, event):
        super().resizeEvent(event)
        width = event.size().width()
        height = event.size().height()
        
        self.icon_label.setGeometry(QRect(width // 2 - 32, height // 8, 64, 64))
        self.label.setGeometry(QRect(0, height // 4, width, 50))
        self.billing_label.setGeometry(QRect(0, height // 2 - 50, width, 30))
        self.top_line.setGeometry(QRect(width // 4, height // 2 + 20 , width // 2, 1))
        self.billing_code.setGeometry(QRect(0, height // 2 + 28, width, 40))
        self.bottom_line.setGeometry(QRect(width // 4, height // 2 + 75, width // 2, 1))
        self.next_button.setGeometry(QRect(width // 4, height * 3 // 4, width // 2, 50))
        
        self.confetti_thread.update_dimensions(width, height)

    def closeEvent(self, event):
        self.confetti_thread.stop()
        self.confetti_thread.wait()
        super().closeEvent(event)

    def on_next_button(self):
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage)))

    def find_menu_page(self):
        for i in range(self.page_stack.count()):
            page = self.page_stack.widget(i)
            if isinstance(page, MenuPage):
                return page
        return None
    

    def reverse(self):
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(WireGuardPage)))

class ConfirmationPopup(QWidget):
    finished = pyqtSignal(bool)

    def __init__(self, parent=None, message="", action_button_text="", cancel_button_text="Cancel"):
        super().__init__(parent)
        self.parent_window = parent
        self.message = message
        self.action_button_text = action_button_text
        self.cancel_button_text = cancel_button_text
        self.initUI()

    def initUI(self):
        self.setMinimumSize(400, 200)
        self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
        self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)

        main_layout = QVBoxLayout()
        self.setLayout(main_layout)

        bg_widget = QWidget(self)
        bg_widget.setStyleSheet("""
            background-color: white;
            border-radius: 10px;
        """)
        main_layout.addWidget(bg_widget)

        content_layout = QVBoxLayout(bg_widget)

        close_button = QPushButton("✕", self)
        close_button.setStyleSheet("""
            QPushButton {
                background-color: transparent;
                color: #888888;
                font-size: 16px;
                font-weight: bold;
                border: none;
            }
            QPushButton:hover {
                color: #ff4d4d;
            }
        """)
        close_button.setFixedSize(30, 30)
        close_button.clicked.connect(self.close)
        content_layout.addWidget(close_button, alignment=Qt.AlignmentFlag.AlignRight)

        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_area.setFrameShape(QFrame.Shape.NoFrame)
        content_layout.addWidget(scroll_area)

        scroll_content = QWidget()
        scroll_layout = QVBoxLayout(scroll_content)

        message_label = QLabel(self.message)
        message_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        message_label.setFont(QFont("Arial", 14))
        message_label.setStyleSheet("color: #333333; margin: 10px 0;")
        message_label.setWordWrap(True)
        scroll_layout.addWidget(message_label)

        scroll_area.setWidget(scroll_content)

        button_layout = QHBoxLayout()
        content_layout.addLayout(button_layout)

        cancel_button = QPushButton(self.cancel_button_text)
        cancel_button.setFixedSize(150, 50)
        cancel_button.setFont(QFont("Arial", 12))
        cancel_button.setStyleSheet("""
            QPushButton {
                background-color: #e0e0e0;
                border: none;
                color: #333333;
                border-radius: 5px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #d0d0d0;
            }
        """)
        cancel_button.clicked.connect(self.close)
        button_layout.addWidget(cancel_button)

        action_button = QPushButton(self.action_button_text)
        action_button.setFixedSize(150, 50)
        action_button.setFont(QFont("Arial", 12))
        action_button.setStyleSheet("""
            QPushButton {
                background-color: #ff4d4d;
                border: none;
                color: white;
                border-radius: 5px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #ff3333;
            }
        """)
        action_button.clicked.connect(self.perform_action)
        button_layout.addWidget(action_button)

class EndpointVerificationPopup(QWidget):
    finished = pyqtSignal(bool, str)

    def __init__(self, parent=None, message=""):
        super().__init__(parent)
        self.parent_window = parent
        self.message = message
        self.initUI()

    def initUI(self):
        self.setMinimumSize(500, 250)
        self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
        self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)

        main_layout = QVBoxLayout()
        self.setLayout(main_layout)

        bg_widget = QWidget(self)
        bg_widget.setStyleSheet("""
            background-color: white;
            border-radius: 10px;
        """)
        main_layout.addWidget(bg_widget)

        content_layout = QVBoxLayout(bg_widget)

        close_button = QPushButton("✕", self)
        close_button.setStyleSheet("""
            QPushButton {
                background-color: transparent;
                color: #888888;
                font-size: 16px;
                font-weight: bold;
                border: none;
            }
            QPushButton:hover {
                color: #ff4d4d;
            }
        """)
        close_button.setFixedSize(30, 30)
        close_button.clicked.connect(lambda: self.close_with_action("abort"))
        content_layout.addWidget(close_button, alignment=Qt.AlignmentFlag.AlignRight)

        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_area.setFrameShape(QFrame.Shape.NoFrame)
        content_layout.addWidget(scroll_area)

        scroll_content = QWidget()
        scroll_layout = QVBoxLayout(scroll_content)

        message_label = QLabel(self.message)
        message_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        message_label.setFont(QFont("Arial", 14))
        message_label.setStyleSheet("color: #333333; margin: 10px 0;")
        message_label.setWordWrap(True)
        scroll_layout.addWidget(message_label)

        scroll_area.setWidget(scroll_content)

        button_layout = QHBoxLayout()
        content_layout.addLayout(button_layout)

        sync_button = QPushButton("Sync")
        sync_button.setFixedSize(120, 50)
        sync_button.setFont(QFont("Arial", 12))
        sync_button.setStyleSheet("""
            QPushButton {
                background-color: #4CAF50;
                border: none;
                color: white;
                border-radius: 5px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #45a049;
            }
        """)
        sync_button.clicked.connect(lambda: self.close_with_action("sync"))
        button_layout.addWidget(sync_button)

        abort_button = QPushButton("Abort")
        abort_button.setFixedSize(120, 50)
        abort_button.setFont(QFont("Arial", 12))
        abort_button.setStyleSheet("""
            QPushButton {
                background-color: #e0e0e0;
                border: none;
                color: #333333;
                border-radius: 5px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #d0d0d0;
            }
        """)
        abort_button.clicked.connect(lambda: self.close_with_action("abort"))
        button_layout.addWidget(abort_button)

        continue_button = QPushButton("Continue Anyway")
        continue_button.setFixedSize(150, 50)
        continue_button.setFont(QFont("Arial", 12))
        continue_button.setStyleSheet("""
            QPushButton {
                background-color: #ff9800;
                border: none;
                color: white;
                border-radius: 5px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #fb8c00;
            }
        """)
        continue_button.clicked.connect(lambda: self.close_with_action("continue"))
        button_layout.addWidget(continue_button)

    def close_with_action(self, action):
        self.finished.emit(True, action)
        self.close()

    def closeEvent(self, event):
        self.finished.emit(False, "abort")
        event.accept()
    
    def mousePressEvent(self, event):
        self.oldPos = event.globalPosition().toPoint()

    def mouseMoveEvent(self, event):
        delta = event.globalPosition().toPoint() - self.oldPos
        self.move(self.x() + delta.x(), self.y() + delta.y())
        self.oldPos = event.globalPosition().toPoint()

class ClickableValueLabel(QLabel):
    def __init__(self, text: str, parent=None):
        super().__init__(text, parent)
        self.setObjectName("value_label")
        self.setStyleSheet("color: #00ffff; font-size: 13px; font-weight: bold;")
        self.setCursor(Qt.CursorShape.PointingHandCursor)
        self.timer = QTimer(self)
        self.timer.setSingleShot(True)
        self.timer.timeout.connect(self.reset_style)
        self.default_style = "color: #00ffff; font-size: 13px; font-weight: bold;"
        self.success_style = "color: #00ff00; font-size: 13px; font-weight: bold;"

    def mousePressEvent(self, event):
        if event.button() == Qt.MouseButton.LeftButton:
            clipboard = QApplication.clipboard()
            clipboard.setText(self.text())
            self.setStyleSheet(self.success_style)
            self.timer.start(100)

    def reset_style(self):
        self.setStyleSheet(self.default_style)


class SyncScreen(Page):
    def __init__(self, page_stack, main_window=None, parent=None):
        super().__init__("SyncScreen", page_stack, main_window, parent)
        self.main_window = main_window
        self.btn_path = main_window.btn_path
        self.update_status = main_window
        self.connection_manager = main_window.connection_manager
        self.is_tor_mode = main_window.is_tor_mode
        

        
        self.heading_label = QLabel("You're about to fetch data from\nSimplified Privacy.", self)
        self.heading_label.setGeometry(15, 80, 750, 120)
        font_style = "font-size: 34px; font-weight: bold; color: white;"
        if self.custom_window.open_sans_family:
            font_style += f" font-family: '{self.custom_window.open_sans_family}';"
        self.heading_label.setStyleSheet(font_style)
        
        self.data_description = QLabel("This data includes what plans, countries,\nbrowsers, and version upgrades are\navailable. As well as coordinating billing.", self)
        self.data_description.setGeometry(22, 190, 750, 120)
        font_style = "font-size: 24px; font-weight: bold; color: #ffff00;"
        if self.custom_window.open_sans_family:
            font_style += f" font-family: '{self.custom_window.open_sans_family}';"
        self.data_description.setStyleSheet(font_style)
        
        self.instructions = QLabel("Use the toggle in the bottom right to\ndecide if you want to use Tor or not.\nThen hit \"Next\"", self)
        self.instructions.setGeometry(22, 345, 750, 120)
        font_style = "font-size: 28px; font-weight: bold; color: white;"
        if self.custom_window.open_sans_family:
            font_style += f" font-family: '{self.custom_window.open_sans_family}';"
        self.instructions.setStyleSheet(font_style)
        
        self.arrow_label = QLabel(self)
        self.arrow_label.setGeometry(520, 400, 180, 130)
        arrow_pixmap = QPixmap(os.path.join(self.btn_path, "arrow-down.png"))
        
        self.arrow_label.setPixmap(arrow_pixmap)
        self.arrow_label.raise_()

        self.button_go.setVisible(True)
        self.button_back.setVisible(True)
        self.button_go.clicked.connect(self.perform_sync)
        self.button_back.clicked.connect(self.go_back)

    def go_back(self):
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage)))
        
    def perform_sync(self):
        self.button_go.setEnabled(False)
        self.button_back.setEnabled(False)
        self.update_status.update_status('Sync in progress...')
        if self.main_window.get_current_connection() == 'tor':
            self.worker_thread = WorkerThread('SYNC_TOR')
        else:
            self.worker_thread = WorkerThread('SYNC')
            
        self.worker_thread.sync_output.connect(self.update_output)
        self.worker_thread.start()
    
    def update_output(self, available_locations, available_browsers, status, is_tor, locations, all_browsers):
        if isinstance(all_browsers, bool) and not all_browsers:
            install_page = self.page_stack.findChild(InstallSystemPackage)
            install_page.configure(package_name='tor', distro='debian', is_sync=True)
            self.page_stack.setCurrentIndex(self.page_stack.indexOf(install_page))
            self.button_go.setEnabled(True)
            self.button_back.setEnabled(True)
            return
        
        if status is False:
            self.button_go.setEnabled(True)
            self.button_back.setEnabled(True)
            self.update_status.update_status('An error occurred during sync')
            return

        self.update_status.update_status('Sync complete')
        
        
        update_available = ClientController.can_be_updated()

        if update_available:
            menu_page = self.page_stack.findChild(MenuPage)
            menu_page.on_update_check_finished()

            
        self.update_after_sync(available_locations, available_browsers, locations, all_browsers)
            
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(ProtocolPage)))

    def update_after_sync(self, available_locations, available_browsers, locations, all_browsers=None):

        self.connection_manager.set_synced(True)

        available_locations_list = []
        available_browsers_list = []

        self.connection_manager.store_locations(locations)
        self.connection_manager.store_browsers(available_browsers)
        
        browser_positions = self.generate_grid_positions(len(available_browsers))
        location_positions = self.generate_grid_positions(len(available_locations))

        for i, location in enumerate(available_locations):
            available_locations_list.append((QPushButton, location, location_positions[i]))

        for i, browser in enumerate(available_browsers):
            available_browsers_list.append((QPushButton, browser, browser_positions[i]))
        
        location_page = self.find_location_page()
        hidetor_page = self.find_hidetor_page()
        protocol_page = self.find_protocol_page()
        browser_page = self.find_browser_page()

        if browser_page:
            browser_page.create_interface_elements(available_browsers_list)

        if location_page:
            location_page.create_interface_elements(available_locations_list)
        if hidetor_page:
            hidetor_page.create_interface_elements(available_locations_list)
        if protocol_page:
            protocol_page.enable_protocol_buttons()

        menu_page = self.find_menu_page()
        if menu_page:
            menu_page.refresh_profiles_data()
        
    def generate_grid_positions(self, num_items):
        positions = []
        start_x = 395
        start_y = 90   
        button_width = 185
        button_height = 75
        h_spacing = 10
        v_spacing = 105  
        
        for i in range(num_items):
            col = i % 2  
            row = i // 2  
            
            x = start_x + (col * (button_width + h_spacing))
            y = start_y + (row * v_spacing)
            
            positions.append((x, y, button_width, button_height))
        
        return positions
        
    def find_browser_page(self):
        for i in range(self.page_stack.count()):
            page = self.page_stack.widget(i)
            if isinstance(page, BrowserPage):
                return page
        return None
    
    def find_location_page(self):
        for i in range(self.page_stack.count()):
            page = self.page_stack.widget(i)
            if isinstance(page, LocationPage):
                return page
        return None
    
    def find_hidetor_page(self):
        for i in range(self.page_stack.count()):
            page = self.page_stack.widget(i)
            if isinstance(page, HidetorPage):
                return page
        return None
        
    def find_protocol_page(self):
        for i in range(self.page_stack.count()):
            page = self.page_stack.widget(i)
            if isinstance(page, ProtocolPage):
                return page
        return None

    def find_menu_page(self):
        for i in range(self.page_stack.count()):
            page = self.page_stack.widget(i)
            if isinstance(page, MenuPage):
                return page
        return None

    

    

class WelcomePage(Page):
    def __init__(self, page_stack, main_window=None, parent=None):
        super().__init__("Welcome", page_stack, main_window, parent)
        self.btn_path = main_window.btn_path
        self.update_status = main_window
        self.ui_elements = []
        self.button_next.clicked.connect(self.go_to_install)
        self.button_next.setVisible(True)
        self._setup_welcome_ui()
        self._setup_stats_display()

    def _setup_welcome_ui(self):
        welcome_title = QLabel('Welcome to HydraVeil', self)
        welcome_title.setGeometry(20, 45, 760, 60)
        welcome_title.setStyleSheet("""
            font-size: 32px;
            font-weight: bold;
            color: cyan;
        """)
        welcome_title.setAlignment(Qt.AlignmentFlag.AlignCenter)
        
        welcome_msg = QLabel(
            "Before we begin your journey, we need to set up a few essential components. "
            "Click 'Next' to take you to the installation page.", self)
        welcome_msg.setGeometry(40, 100, 720, 80)
        welcome_msg.setWordWrap(True)
        welcome_msg.setStyleSheet("""
            font-size: 16px;
            color: cyan;
        """)
        welcome_msg.setAlignment(Qt.AlignmentFlag.AlignCenter)

    def _setup_stats_display(self):
        stats_container = QWidget(self)
        stats_container.setGeometry(70, 200, 730, 240)
        
        stats_title = QLabel(stats_container)
        stats_title.setText("Features & Services")
        stats_title.setGeometry(190, 10, 300, 30)  
        stats_title.setStyleSheet("""
            font-size: 22px;
            font-weight: bold;
            color: cyan;
        """)
        
        grid_widget = QWidget(stats_container)
        grid_widget.setGeometry(0, 70, 700, 190)  
        grid_layout = QGridLayout(grid_widget)
        grid_layout.setSpacing(30)
        
        stats = [
            ("Browsers", "browsers_mini.png", "10 Supported Browsers", True),
            ("WireGuard", "wireguard_mini.png", "6 Global Locations", True),
            ("Proxy", "just proxy_mini.png", "5 Proxy Locations", True),
            ("Tor", "toricon_mini.png", "Tor Network Access", True)
        ]
        
        for i, (title, icon_name, count, available) in enumerate(stats):
            row = i // 2
            col = i % 2
            
            stat_widget = QWidget()
            stat_layout = QHBoxLayout(stat_widget)
            stat_layout.setContentsMargins(20, 10, 2, 10)
            stat_layout.setSpacing(15)
            
            icon_label = QLabel()
            icon_path = os.path.join(self.btn_path, icon_name)
            icon_label.setPixmap(QPixmap(icon_path).scaled(30, 30, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation))
            icon_label.setFixedSize(30, 30)
            stat_layout.addWidget(icon_label)
            
            text_widget = QWidget()
            text_layout = QVBoxLayout(text_widget)
            text_layout.setSpacing(5)
            text_layout.setContentsMargins(0, 0, 30, 0)
            
            title_widget = QWidget()
            title_layout = QHBoxLayout(title_widget)
            title_layout.setContentsMargins(0, 0, 0, 0)
            title_layout.setSpacing(10)
            
            title_label = QLabel(title)
            title_label.setStyleSheet("font-size: 16px; font-weight: bold; color: #2c3e50;")
            title_layout.addWidget(title_label)
            
            status_indicator = QLabel("●")
            status_indicator.setStyleSheet("color: #2ecc71; font-size: 16px;")
            title_layout.addWidget(status_indicator)
            
            title_layout.addStretch()
            text_layout.addWidget(title_widget)
            
            count_label = QLabel(count)
            count_label.setStyleSheet("font-size: 16px; color: #34495e;")
            text_layout.addWidget(count_label)
            
            stat_layout.addWidget(text_widget, stretch=1)
            
            stat_widget.setStyleSheet("""
                QWidget {
                    background-color: transparent;
                    border-radius: 10px;
                }
            """)
            
            grid_layout.addWidget(stat_widget, row, col)


    def go_to_install(self):
        install_page = self.page_stack.findChild(InstallSystemPackage)
        install_page.configure(package_name='all', distro='debian')
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(install_page))


class DurationSelectionPage(Page):
    def __init__(self, page_stack, main_window=None, parent=None):
        super().__init__("Select Duration", page_stack, main_window, parent)
        self.update_status = main_window
        self.create_interface_elements()
        self.button_reverse.setVisible(True)

    def create_interface_elements(self):
        self.title = QLabel("Select Duration", self)
        self.title.setGeometry(QtCore.QRect(530, 30, 210, 40))
        self.title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.button_reverse.clicked.connect(self.reverse)

        self.combo_box = QComboBox(self)
        self.combo_box.setGeometry(200, 200, 400, 60)
        self.combo_box.addItems(["1 month ($1)", "3 months ($3)", "6 months ($5)", "12 months ($10)"])
        self.combo_box.setEditable(False)
        self.combo_box.setMaxVisibleItems(4)
        self.combo_box.setDuplicatesEnabled(True)
        self.combo_box.setPlaceholderText("Select options")
        self.combo_box.setStyleSheet("""
            QComboBox {
                font-size: 16px;
                padding: 10px;
                border: 2px solid #ccc;
                border-radius: 8px;
            }
            QComboBox::drop-down {
                width: 30px;
            }
            QComboBox::down-arrow {
                width: 12px;
                height: 12px;
            }
        """)

        self.next_button = QPushButton("Next", self)
        self.next_button.setGeometry(350, 300, 100, 40)
        self.next_button.setStyleSheet("""
            QPushButton {
                font-size: 18px;
                padding: 10px;
                border: 2px solid #ccc;
                border-radius: 10px;
                background-color: cyan;
                color: black;
                font-weight: bold;
            }
        """)
        self.next_button.clicked.connect(self.show_next)

    def show_next(self):
        currency_page = self.page_stack.findChild(CurrencySelectionPage)
        if currency_page:
            currency_page.selected_duration = self.combo_box.currentText()
            self.page_stack.setCurrentWidget(currency_page)

    def reverse(self):
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(IdPage)))
class CurrencySelectionPage(Page):
    def __init__(self, page_stack, main_window=None, parent=None):
        super().__init__("Select Currency", page_stack, main_window, parent)
        self.update_status = main_window
        self.selected_duration = None
        self.create_interface_elements()
        self.button_reverse.setVisible(True)
        self.button_next.setVisible(False)

    def create_interface_elements(self):
        self.title = QLabel("Payment Method", self)
        self.title.setGeometry(QtCore.QRect(510, 30, 250, 40))
        self.title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.button_reverse.clicked.connect(self.reverse)

        button_info = [
            ("monero", (545, 75)),
            ("bitcoin", (545, 290)),
            ("lightnering", (545, 180)),
            ("litecoin", (545, 395))
        ]

        self.buttonGroup = QButtonGroup(self)
        self.buttons = []

        for j, (icon_name, position) in enumerate(button_info):
            button = QPushButton(self)
            button.setGeometry(position[0], position[1], 185, 75)
            button.setIconSize(QSize(190, 120))
            button.setCheckable(True)
            self.buttons.append(button)
            self.buttonGroup.addButton(button, j)
            button.setIcon(QIcon(os.path.join(self.btn_path, f"{icon_name}.png")))
            button.clicked.connect(self.on_currency_selected)

    def on_currency_selected(self):
        payment_details_page = self.page_stack.findChild(PaymentDetailsPage)
        if payment_details_page:
            payment_details_page.selected_duration = self.selected_duration
            payment_details_page.selected_currency = self.get_selected_currency()
            payment_details_page.check_invoice()
            self.page_stack.setCurrentWidget(payment_details_page)
            self.update_status.update_status('Loading payment details...')

        

    def get_selected_currency(self):
        selected_button = self.buttonGroup.checkedButton()
        if selected_button:
            index = self.buttonGroup.id(selected_button)
            currencies = ["monero", "bitcoin", "lightning", "litecoin"]
            return currencies[index]
        return None

    def reverse(self):
        duration_page = self.page_stack.findChild(DurationSelectionPage)
        if duration_page:
            self.page_stack.setCurrentWidget(duration_page)

class PaymentDetailsPage(Page):
    def __init__(self, page_stack, main_window=None, parent=None):
        super().__init__("Payment Details", page_stack, main_window, parent)
        self.update_status = main_window
        self.text_fields = []
        self.invoice_data = {}
        self.selected_duration = None
        self.selected_currency = None
        
        self.create_interface_elements()
        self.button_reverse.setVisible(True)

    def create_interface_elements(self):
        self.title = QLabel("Payment Details", self)
        self.title.setGeometry(QtCore.QRect(530, 30, 210, 40))
        self.title.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.button_reverse.clicked.connect(self.reverse)

        self.qr_code_button = QPushButton(self)
        self.qr_code_button.setGeometry(360, 435, 50, 50)
        qr_icon = QIcon(os.path.join(self.btn_path, "qr-code.png"))
        self.qr_code_button.setIcon(qr_icon)
        self.qr_code_button.setIconSize(self.qr_code_button.size())
        self.qr_code_button.clicked.connect(self.show_qr_code)
        self.qr_code_button.setToolTip("Show QR Code")
        self.qr_code_button.setDisabled(True)

        labels_info = [
            ("Your new billing ID", None, (20, 40), (240, 50)),
            ("", "cuadro400x50", (20, 90), (400, 50)),
            ("Duration", None, (20, 155), (150, 50)),
            ("", "cuadro150x50", (200, 155), (150, 50)),
            ("Amount", None, (10, 220), (150, 50)),
            ("", "cuadro150x50", (200, 220), (150, 50)),
            ("Hit this white icon to copy paste the address:", None, (15, 305), (500, 30)),
            ("", "cuadro400x50", (20, 350), (400, 50)),
            ("Hit this icon to Scan the QR code:", None, (15, 450), (360, 30)),
        ]

        for text, image_name, position, size in labels_info:
            label = QLabel(self)
            label.setGeometry(position[0], position[1], size[0], size[1])

            if "Hit" in text:
                label.setStyleSheet("font-size: 16px;")
                label.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeft | QtCore.Qt.AlignmentFlag.AlignVCenter)
            else:
                label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)

            if image_name:
                pixmap = QPixmap(os.path.join(self.btn_path, f"{image_name}.png"))
                label.setPixmap(pixmap)
                label.setScaledContents(True)
            else:
                label.setText(text)


        
        line_edit_info = [
            (20, 90, 400, 50),
            (200, 155, 150, 50),
            (200, 220, 150, 50),
            (20, 350, 400, 50),
        ]

        for x, y, width, height in line_edit_info:
            line_edit = QLineEdit(self)
            line_edit.setGeometry(x, y, width, height)
            line_edit.setReadOnly(True)
            self.text_fields.append(line_edit)
            line_edit.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)

        copy_button_info = [
            (430, 90, 0),
            (360, 220, 2),
            (480, 290, 3),
        ]

        for x, y, field_index in copy_button_info:
            button = QPushButton(self)
            button.setGeometry(x, y, 50, 50)
            icon = QIcon(os.path.join(self.btn_path, "paste_button.png"))
            button.setIcon(icon)
            button.setIconSize(button.size())
            button.clicked.connect(lambda checked, index=field_index: self.copy_text(index))

        currency_button_info = [
            ("monero", (545, 75)),
            ("bitcoin", (545, 290)),
            ("lightnering", (545, 180)),
            ("litecoin", (545, 395))
        ]

        self.currency_display_buttons = []
        for icon_name, position in currency_button_info:
            button = QPushButton(self)
            button.setGeometry(position[0], position[1], 185, 75)
            button.setIconSize(QSize(190, 120))
            button.setCheckable(True)
            button.setEnabled(False)
            self.currency_display_buttons.append(button)
            button.setIcon(QIcon(os.path.join(self.btn_path, f"{icon_name}.png")))

        

    def fetch_invoice_duration(self):
        duration_month_num = int(self.selected_duration.split()[0])
        if duration_month_num == 12:
            total_hours = 365 * 24
        else:
            total_hours = duration_month_num * (30 * 24)
        return total_hours

    def display_selected_options(self):
        if self.selected_duration:
            self.text_fields[1].setText(self.selected_duration)
            self.text_fields[1].setStyleSheet('font-size: 13px;')
        
        if self.selected_currency:
            currency_index_map = {
                "monero": 0,
                "bitcoin": 1,
                "lightning": 2,
                "litecoin": 3
            }
            currency_index = currency_index_map.get(self.selected_currency, -1)
            if currency_index >= 0:
                for i, button in enumerate(self.currency_display_buttons):
                    button.setChecked(i == currency_index)
                    button.setEnabled(i == currency_index)



    def on_request_invoice(self):
        total_hours = self.fetch_invoice_duration()
        if self.selected_currency is None:
            self.update_status.update_status('No currency selected')
            return
        
        profile_data = {
            'id': int(self.update_status.current_profile_id),
            'duration': total_hours,
            'currency': 'xmr' if self.selected_currency == 'monero' else 'btc' if self.selected_currency == 'bitcoin' else 'btc-ln' if self.selected_currency == 'lightning' else 'ltc' if self.selected_currency == 'litecoin' else None
        }
        
        self.update_status.update_status('Generating Invoice...')
        self.worker_thread = WorkerThread('GET_SUBSCRIPTION', profile_data=profile_data)
        self.worker_thread.text_output.connect(self.invoice_update_text_output)
        self.worker_thread.invoice_output.connect(self.on_invoice_generation_finished)
        self.worker_thread.invoice_finished.connect(self.on_invoice_finished)
        self.worker_thread.start()

    def invoice_update_text_output(self, text):
        self.update_status.update_status(text)

        if 'No compatible' in text:
            for line in self.text_fields:
                line.setText('')

    def store_invoice_data(self, billing_details: dict, duration: int):
        self.invoice_data = {
            'billing_details': billing_details,
            'duration': duration
        }

    def check_invoice(self):
        self.display_selected_options()
        total_hours = self.fetch_invoice_duration()
        if self.invoice_data and self.invoice_data['duration'] == total_hours:
            self.update_status.update_status('Checking invoice status...')
            self.check_invoice_status(self.invoice_data['billing_details'].billing_code)
        else:
            self.on_request_invoice()
        

    def check_invoice_status(self, billing_code: str):
        self.worker_thread = WorkerThread('CHECK_INVOICE_STATUS', profile_data={'billing_code': billing_code})
        self.worker_thread.invoice_finished.connect(self.on_invoice_status_finished)
        self.worker_thread.start()

    def on_invoice_status_finished(self, result):
        if result:
            self.parse_invoice_data(self.invoice_data['billing_details'])
        else:
            self.update_status.update_status('Invoice has expired. Generating new invoice...')
            self.on_request_invoice()

    def on_invoice_generation_finished(self, billing_details: object, text: str):
        total_hours = self.fetch_invoice_duration()
        self.store_invoice_data(billing_details, duration=total_hours)
        self.parse_invoice_data(billing_details)

    def parse_invoice_data(self, invoice_data: object):
        billing_details = {
            'billing_code': invoice_data.billing_code
        }
        
        if self.selected_currency.lower() == 'lightning':
            currency = 'Bitcoin Lightning'
        else:
            currency = self.selected_currency
            
        preferred_method = next((pm for pm in invoice_data.payment_methods if pm.name.lower() == currency.lower()), None)

        if preferred_method:
            billing_details['due_amount'] = preferred_method.due
            billing_details['address'] = preferred_method.address
        else:
            self.update_status.update_status('No payment method found for the selected currency.')
            return

        billing_values = list(billing_details.values())
        text_field_indices = [0, 2, 3]
        
        for i, dict_value in enumerate(billing_values):
            if i < 3:
                field_index = text_field_indices[i]
                if i == 2:
                    text = str(dict_value)
                    self.full_address = text
                    metrics = self.text_fields[field_index].fontMetrics()
                    width = self.text_fields[field_index].width()
                    elided_text = metrics.elidedText(text, QtCore.Qt.TextElideMode.ElideMiddle, width)
                    self.text_fields[field_index].setText(elided_text)
                elif i == 1:
                    text = str(dict_value)
                    self.text_fields[field_index].setProperty("fullText", text)
                    self.text_fields[field_index].setText(text)
                    font_size = 14
                    if len(text) > 9:
                        font_size = 15
                    if len(text) > 13:
                        font_size = 10
                    if len(text) > 16:
                        font_size = 10
                    self.text_fields[field_index].setStyleSheet(f"font-size: {font_size}px; font-weight: bold;")
                else:
                    self.text_fields[field_index].setProperty("fullText", str(dict_value))
                    self.text_fields[field_index].setText(str(dict_value))

        self.qr_code_button.setDisabled(False)
        self.update_status.update_status('Invoice generated. Awaiting payment...')
        

    def on_invoice_finished(self, result):
        if result:
            self.invoice_data.clear()
            self.show_payment_confirmed(self.text_fields[0].text())
            return
        self.update_status.update_status('An error occurred when generating invoice')

    def show_payment_confirmed(self, billing_code):
        payment_page = self.find_payment_confirmed_page()
        
        if payment_page:
            for line in self.text_fields:
                line.setText('')
            payment_page.set_billing_code(billing_code)
            self.page_stack.setCurrentWidget(payment_page)
        else:
            print("PaymentConfirmed page not found")

    def find_payment_confirmed_page(self):
        for i in range(self.page_stack.count()):
            page = self.page_stack.widget(i)
            if isinstance(page, PaymentConfirmed):
                return page
        return None

    def copy_text(self, field: int):
        try:
            original_status = self.update_status.status_label.text()
            original_status = original_status.replace("Status: ", "")
            
            if int(field) == 3:
                text = self.full_address
            else:
                text = self.text_fields[int(field)].text()
            QApplication.clipboard().setText(text)
            
            if field == 0:
                self.update_status.update_status('Billing code copied to clipboard!')
            elif field == 3:
                self.update_status.update_status('Address copied to clipboard!')
            else:
                self.update_status.update_status('Pay amount copied to clipboard!')
            
            QTimer.singleShot(2000, lambda: self.update_status.update_status(original_status))
        except AttributeError:
            self.update_status.update_status('No content available for copying')
        except Exception as e:
            self.update_status.update_status(f'An error occurred when copying the text')

    def reverse(self):
        currency_page = self.page_stack.findChild(CurrencySelectionPage)
        if currency_page:
            self.page_stack.setCurrentWidget(currency_page)

    def show_qr_code(self):
        full_amount = self.text_fields[2].text()
        if hasattr(self, 'full_address') and self.full_address:
            currency_type = getattr(self, 'selected_currency', None)
            qr_dialog = QRCodeDialog(self.full_address, full_amount, currency_type, self)
            qr_dialog.exec()
        else:
            self.update_status.update_status('No address available for QR code')

    def fetch_invoice_duration(self):
        duration_month_num = int(self.selected_duration.split()[0])
        if duration_month_num == 12:
            total_hours = 365 * 24
        else:
            total_hours = duration_month_num * (30 * 24)
        return total_hours
class FastRegistrationPage(Page):
    def __init__(self, page_stack, main_window):
        super().__init__("FastRegistration", page_stack, main_window)
        self.page_stack = page_stack
        self.update_status = main_window
        self.connection_manager = main_window.connection_manager
        self.labels = []
        self.buttons = []
        self.title.setGeometry(550, 40, 250, 40)
        self.title.setText("Fast Creation")
        
        self.button_apply.setVisible(True)
        self.button_apply.clicked.connect(self.create_profile)
        
        self.button_back.setVisible(True)
        try:
            self.button_back.clicked.disconnect()
        except TypeError:
            pass
        self.button_back.clicked.connect(self.go_back)

        self.name_handle = QLabel(self)
        self.name_handle.setGeometry(110, 70, 400, 30)
        self.name_handle.setStyleSheet('color: #cacbcb;')
        self.name_handle.setText("Profile Name:")

        self.name_hint = QLabel(self)
        self.name_hint.setGeometry(265, 100, 190, 20)
        self.name_hint.setStyleSheet('color: #888888; font-size: 10px; font-style: italic;')
        self.name_hint.setText("Click here to edit profile name")
        self.name_hint.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)

        self.name = QLineEdit(self)
        self.name.setPlaceholderText("Enter name")
        self.name.setGeometry(265, 70, 190, 30)
        self.name.setStyleSheet("color: cyan; border: 1px solid #666666; border-radius: 3px; background-color: rgba(0, 0, 0, 0.3);")
        self.name.setCursor(QtCore.Qt.CursorShape.IBeamCursor)  
        self.name.focusInEvent = lambda event: self.name_hint.hide()
        self.name.focusOutEvent = lambda event: self.name_hint.show() if not self.name.text() else self.name_hint.hide()
        
        self.name.textChanged.connect(lambda text: self.name_hint.hide() if text else self.name_hint.show())

        self.profile_data = {}
        self.selected_values = {
            'protocol': 'wireguard',
            'connection': 'browser-only',
            'location': '',
            'browser': '',
            'resolution': '1024x760'
        }
        
        self.initialize_default_selections()

    def initialize_default_selections(self):
        if not self.selected_values['location']:
            locations = self.connection_manager.get_location_list()
            if locations:
                random_index = random.randint(0, len(locations) - 1)
                self.selected_values['location'] = locations[random_index]
        
        if not self.selected_values['browser']:
            browsers = self.connection_manager.get_browser_list()
            if browsers:
                random_index = random.randint(0, len(browsers) - 1)
                self.selected_values['browser'] = browsers[random_index]

    def get_next_available_profile_id(self) -> int:
        profiles = ProfileController.get_all()
        if not profiles:
            return 1
            
        existing_ids = sorted(profiles.keys())
        
        for i in range(1, max(existing_ids) + 2):
            if i not in existing_ids:
                return i
                
        return 1

    def showEvent(self, event):
        super().showEvent(event)
        self.initialize_default_selections()
        self.create_interface_elements()

    def create_interface_elements(self):
        for label in self.labels:
            label.deleteLater()
        self.labels = []
        for button in self.buttons:
            button.deleteLater()
        self.buttons = []
        
        if not self.name.text():
            self.name_hint.show()
        else:
            self.name_hint.hide()

        self.create_protocol_section()
        self.create_connection_section()
        self.create_location_section()
        self.create_browser_section()
        self.create_resolution_section()
        self.update_ui_state_for_connection()

    def create_protocol_section(self):
        label = QLabel("Protocol", self)
        label.setGeometry(300, 150, 185, 75)
        
        protocol_image = QPixmap(os.path.join(self.btn_path, f"{self.selected_values['protocol']}_button.png"))
        label.setPixmap(protocol_image)
        label.setScaledContents(True)
        label.show()
        self.labels.append(label)

        prev_button = QPushButton(self)
        prev_button.setGeometry(265, 150, 30, 75)
        prev_button.clicked.connect(lambda: self.show_previous_value('protocol'))
        prev_button.show()
        icon_path = os.path.join(self.btn_path, "UP_button.png")
        icon = QPixmap(icon_path)
        transform = QTransform().rotate(180)
        rotated_icon = icon.transformed(transform)
        prev_button.setIcon(QIcon(rotated_icon))
        prev_button.setIconSize(prev_button.size())
        self.buttons.append(prev_button)

        next_button = QPushButton(self)
        next_button.setGeometry(490, 150, 30, 75)
        next_button.clicked.connect(lambda: self.show_next_value('protocol'))
        next_button.show()
        next_button.setIcon(QIcon(os.path.join(self.btn_path, "UP_button.png")))
        next_button.setIconSize(next_button.size())
        self.buttons.append(next_button)

    def create_connection_section(self):
        label = QLabel("Connection", self)
        label.setGeometry(150, 250, 185, 75)
        
        if self.selected_values['connection']:
            connection_image = QPixmap(os.path.join(self.btn_path, f"{self.selected_values['connection']}_button.png"))
            if connection_image.isNull():
                fallback_path = os.path.join(self.btn_path, "browser-only_button.png")
                connection_image = QPixmap(fallback_path)
        else:
            connection_image = QPixmap(os.path.join(self.btn_path, "browser-only_button.png"))
        
        label.setPixmap(connection_image)
        label.setScaledContents(True)
        label.show()
        self.labels.append(label)

        prev_button = QPushButton(self)
        prev_button.setGeometry(115, 250, 30, 75)
        prev_button.clicked.connect(lambda: self.show_previous_value('connection'))
        prev_button.show()
        icon_path = os.path.join(self.btn_path, "UP_button.png")
        icon = QPixmap(icon_path)
        transform = QTransform().rotate(180)
        rotated_icon = icon.transformed(transform)
        prev_button.setIcon(QIcon(rotated_icon))
        prev_button.setIconSize(prev_button.size())
        self.buttons.append(prev_button)

        next_button = QPushButton(self)
        next_button.setGeometry(340, 250, 30, 75)
        next_button.clicked.connect(lambda: self.show_next_value('connection'))
        next_button.show()
        next_button.setIcon(QIcon(os.path.join(self.btn_path, "UP_button.png")))
        next_button.setIconSize(next_button.size())
        self.buttons.append(next_button)

    def create_location_section(self):
        info_label = QLabel("Click the location for more info", self)
        info_label.setGeometry(520, 80, 230, 20)
        info_label.setStyleSheet("color: #888888; font-size: 11px; font-style: italic;")
        info_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight)
        info_label.show()
        self.labels.append(info_label)
        
        label = QPushButton(self)
        label.setGeometry(435, 250, 185, 75)
        label.setFlat(True)
        label.setStyleSheet("background: transparent; border: none;")
        
        if self.selected_values['location']:
            image_path = os.path.join(self.btn_path, f"button_{self.selected_values['location']}.png")
            location_image = QPixmap(image_path)
            locations = self.connection_manager.get_location_info(self.selected_values['location'])
            provider = locations.operator.name if locations and hasattr(locations, 'operator') else None
            fallback_path = os.path.join(self.btn_path, "default_location_button.png")
            
            if location_image.isNull():
                if locations and hasattr(locations, 'country_name'):
                    location_image = LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', fallback_path, provider)
                else:
                    location_image = LocationPage.create_location_button_image(self.selected_values['location'], fallback_path, provider)
            else:
                if locations and hasattr(locations, 'country_name'):
                    location_image = LocationPage.create_location_button_image(f'{locations.country_code}_{locations.code}', fallback_path, provider, image_path)
                else:
                    location_image = LocationPage.create_location_button_image(self.selected_values['location'], fallback_path, provider, image_path)
        else:
            location_image = QPixmap(os.path.join(self.btn_path, "default_location_button.png"))
        
        label.setIcon(QIcon(location_image))
        label.setIconSize(QSize(185, 75))
        if self.selected_values['location']:
            label.location_icon_name = self.selected_values['location']
            label.setCursor(QtCore.Qt.CursorShape.PointingHandCursor)
            label.clicked.connect(lambda checked, loc=self.selected_values['location']: self.show_location_verification(loc))
        label.show()
        self.labels.append(label)

        prev_button = QPushButton(self)
        prev_button.setGeometry(400, 250, 30, 75)
        prev_button.clicked.connect(lambda: self.show_previous_value('location'))
        prev_button.show()
        icon_path = os.path.join(self.btn_path, "UP_button.png")
        icon = QPixmap(icon_path)
        transform = QTransform().rotate(180)
        rotated_icon = icon.transformed(transform)
        prev_button.setIcon(QIcon(rotated_icon))
        prev_button.setIconSize(prev_button.size())
        self.buttons.append(prev_button)

        next_button = QPushButton(self)
        next_button.setGeometry(625, 250, 30, 75)
        next_button.clicked.connect(lambda: self.show_next_value('location'))
        next_button.show()
        next_button.setIcon(QIcon(os.path.join(self.btn_path, "UP_button.png")))
        next_button.setIconSize(next_button.size())
        self.buttons.append(next_button)

    def create_browser_section(self):
        label = QLabel("Browser", self)
        label.setGeometry(150, 350, 185, 75)
        
        if self.selected_values['browser']:
            browser_image = BrowserPage.create_browser_button_image(self.selected_values['browser'], self.btn_path)
            if browser_image.isNull():
                fallback_path = os.path.join(self.btn_path, "default_browser_button.png")
                browser_image = BrowserPage.create_browser_button_image(self.selected_values['browser'], fallback_path, True)
        else:
            browser_image = QPixmap()
        
        label.setPixmap(browser_image)
        label.setScaledContents(True)
        label.show()
        self.labels.append(label)

        prev_button = QPushButton(self)
        prev_button.setGeometry(115, 350, 30, 75)
        prev_button.clicked.connect(lambda: self.show_previous_value('browser'))
        prev_button.show()
        icon_path = os.path.join(self.btn_path, "UP_button.png")
        icon = QPixmap(icon_path)
        transform = QTransform().rotate(180)
        rotated_icon = icon.transformed(transform)
        prev_button.setIcon(QIcon(rotated_icon))
        prev_button.setIconSize(prev_button.size())
        self.buttons.append(prev_button)

        next_button = QPushButton(self)
        next_button.setGeometry(340, 350, 30, 75)
        next_button.clicked.connect(lambda: self.show_next_value('browser'))
        next_button.show()
        next_button.setIcon(QIcon(os.path.join(self.btn_path, "UP_button.png")))
        next_button.setIconSize(next_button.size())
        self.buttons.append(next_button)

    def create_resolution_section(self):
        label = QLabel("Resolution", self)
        label.setGeometry(435, 350, 185, 75)
        screen_page = self.page_stack.findChild(ScreenPage)
        if self.selected_values['resolution']:
            
            resolution_image = screen_page.create_resolution_button_image(self.selected_values['resolution'])
        else:
            resolution_image = screen_page.create_resolution_button_image("1024x760")
        
        label.setPixmap(resolution_image)
        label.setScaledContents(True)
        label.show()
        self.labels.append(label)

        prev_button = QPushButton(self)
        prev_button.setGeometry(400, 350, 30, 75)
        prev_button.clicked.connect(lambda: self.show_previous_value('resolution'))
        prev_button.show()
        icon_path = os.path.join(self.btn_path, "UP_button.png")
        icon = QPixmap(icon_path)
        transform = QTransform().rotate(180)
        rotated_icon = icon.transformed(transform)
        prev_button.setIcon(QIcon(rotated_icon))
        prev_button.setIconSize(prev_button.size())
        self.buttons.append(prev_button)

        next_button = QPushButton(self)
        next_button.setGeometry(625, 350, 30, 75)
        next_button.clicked.connect(lambda: self.show_next_value('resolution'))
        next_button.show()
        next_button.setIcon(QIcon(os.path.join(self.btn_path, "UP_button.png")))
        next_button.setIconSize(next_button.size())
        self.buttons.append(next_button)

    def update_ui_state_for_connection(self):
        is_system_wide = self.selected_values['connection'] == 'system-wide'
        
        for button in self.buttons:
            if hasattr(button, 'geometry'):
                button_geometry = button.geometry()
                if button_geometry.y() == 350:
                    if button_geometry.x() in [115, 340, 400, 625]:
                        button.setEnabled(not is_system_wide)


    def show_previous_value(self, key):
        if key == 'protocol':
            protocols = ['wireguard', 'hidetor']
            current_index = protocols.index(self.selected_values[key])
            previous_index = (current_index - 1) % len(protocols)
            self.selected_values[key] = protocols[previous_index]
            if self.selected_values[key] == 'wireguard':
                self.selected_values['connection'] = 'browser-only'
            else:
                self.selected_values['connection'] = 'tor'
        elif key == 'connection':
            if self.selected_values['protocol'] == 'wireguard':
                connections = ['browser-only', 'system-wide']
            else:
                connections = ['tor', 'just proxy']
            current_index = connections.index(self.selected_values[key])
            previous_index = (current_index - 1) % len(connections)
            self.selected_values[key] = connections[previous_index]
            self.update_ui_state_for_connection()
        elif key == 'location':
            locations = self.connection_manager.get_location_list()
            if locations and self.selected_values[key] in locations:
                current_index = locations.index(self.selected_values[key])
                previous_index = (current_index - 1) % len(locations)
                self.selected_values[key] = locations[previous_index]
            elif locations:
                self.selected_values[key] = locations[0]
        elif key == 'browser':
            browsers = self.connection_manager.get_browser_list()
            if browsers and self.selected_values[key] in browsers:
                current_index = browsers.index(self.selected_values[key])
                previous_index = (current_index - 1) % len(browsers)
                self.selected_values[key] = browsers[previous_index]
            elif browsers:
                self.selected_values[key] = browsers[0]
        elif key == 'resolution':
            resolutions = ['800x600', '1024x760', '1152x1080', '1280x1024', '1920x1080', '2560x1440', '2560x1600', '1920x1440', '1792x1344', '2048x1152']
            current_index = resolutions.index(self.selected_values[key])
            previous_index = (current_index - 1) % len(resolutions)
            self.selected_values[key] = resolutions[previous_index]
        
        self.create_interface_elements()

    def show_next_value(self, key):
        if key == 'protocol':
            protocols = ['wireguard', 'hidetor']
            current_index = protocols.index(self.selected_values[key])
            next_index = (current_index + 1) % len(protocols)
            self.selected_values[key] = protocols[next_index]
            if self.selected_values[key] == 'wireguard':
                self.selected_values['connection'] = 'browser-only'
            else:
                self.selected_values['connection'] = 'tor'
        elif key == 'connection':
            if self.selected_values['protocol'] == 'wireguard':
                connections = ['browser-only', 'system-wide']
            else:
                connections = ['tor', 'just proxy']
            current_index = connections.index(self.selected_values[key])
            next_index = (current_index + 1) % len(connections)
            self.selected_values[key] = connections[next_index]
            self.update_ui_state_for_connection()
        elif key == 'location':
            locations = self.connection_manager.get_location_list()
            if locations and self.selected_values[key] in locations:
                current_index = locations.index(self.selected_values[key])
                next_index = (current_index + 1) % len(locations)
                self.selected_values[key] = locations[next_index]
            elif locations:
                self.selected_values[key] = locations[0]
        elif key == 'browser':
            browsers = self.connection_manager.get_browser_list()
            if browsers and self.selected_values[key] in browsers:
                current_index = browsers.index(self.selected_values[key])
                next_index = (current_index + 1) % len(browsers)
                self.selected_values[key] = browsers[next_index]
            elif browsers:
                self.selected_values[key] = browsers[0]
        elif key == 'resolution':
            resolutions = ['800x600', '1024x760', '1152x1080', '1280x1024', '1920x1080', '2560x1440', '2560x1600', '1920x1440', '1792x1344', '2048x1152']
            current_index = resolutions.index(self.selected_values[key])
            next_index = (current_index + 1) % len(resolutions)
            self.selected_values[key] = resolutions[next_index]
        
        self.create_interface_elements()

    def go_back(self):
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage)))

    def show_location_verification(self, location_icon_name):
        verification_page = LocationVerificationPage(self.page_stack, self.update_status, location_icon_name, self)
        self.page_stack.addWidget(verification_page)
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(verification_page))

    def create_profile(self):
        profile_name = self.name.text()
        if not profile_name:
            self.update_status.update_status('Please enter a profile name')
            return

        if not self.selected_values['location']:
            self.update_status.update_status('Please select a location')
            return

        if self.selected_values['connection'] != 'system-wide' and not self.selected_values['browser']:
            self.update_status.update_status('Please select a browser')
            return

        profile_data = {
            'name': profile_name,
            'protocol': self.selected_values['protocol'],
            'connection': self.selected_values['connection'],
            'location': self.selected_values['location'],
            'browser': self.selected_values['browser'],
            'resolution': self.selected_values['resolution']
        }

        self.profile_data = profile_data
        self.update_status.write_data(profile_data)
        
        resume_page = self.find_resume_page()
        if resume_page:
            if self.selected_values['protocol'] == 'wireguard':
                self.create_wireguard_profile(profile_data)
            else:
                self.create_tor_profile(profile_data)

        self.go_back()

    def create_wireguard_profile(self, profile_data):
        location_info = self.connection_manager.get_location_info(profile_data['location'])
        if not location_info:
            self.update_status.update_status('Invalid location selected')
            return

        profile_id = self.get_next_available_profile_id()
        profile_data_for_resume = {
            'id': profile_id,
            'name': profile_data['name'],
            'country_code': location_info.country_code,
            'code': location_info.code,
            'application': profile_data['browser'],
            'connection_type': 'wireguard',
            'resolution': profile_data['resolution'],
        }

        resume_page = self.find_resume_page()
        if resume_page:
            if profile_data['connection'] == 'system-wide':
                resume_page.handle_core_action_create_profile('CREATE_SYSTEM_PROFILE', profile_data_for_resume, 'system')
            else:
                resume_page.handle_core_action_create_profile('CREATE_SESSION_PROFILE', profile_data_for_resume, 'session')

    def create_tor_profile(self, profile_data):
        location_info = self.connection_manager.get_location_info(profile_data['location'])
        if not location_info:
            self.update_status.update_status('Invalid location selected')
            return

        connection_type = 'tor' if profile_data['connection'] == 'tor' else 'system'

        profile_id = self.get_next_available_profile_id()
        profile_data_for_resume = {
            'id': profile_id,
            'name': profile_data['name'],
            'country_code': location_info.country_code,
            'code': location_info.code,
            'application': profile_data['browser'],
            'connection_type': connection_type,
            'resolution': profile_data['resolution'],
        }

        resume_page = self.find_resume_page()
        if resume_page:
            resume_page.handle_core_action_create_profile('CREATE_SESSION_PROFILE', profile_data_for_resume, 'session')

        

    def find_resume_page(self):
        for i in range(self.page_stack.count()):
            page = self.page_stack.widget(i)
            if isinstance(page, ResumePage):
                return page
        return None

class FastModePromptPage(Page):
    def __init__(self, page_stack, main_window):
        super().__init__("FastModePrompt", page_stack, main_window)
        self.page_stack = page_stack
        self.update_status = main_window
        self.title.setGeometry(500, 40, 350, 40)
        self.title.setText("Quick Setup Option")
        self.button_back.setVisible(False)
        self.button_apply.setVisible(False)

        container = QWidget(self)
        container.setGeometry(QtCore.QRect(80, 100, 640, 360))
        v = QVBoxLayout(container)
        v.setContentsMargins(0, 0, 0, 0)
        v.setSpacing(20)

        large_text = QLabel("Would you like to switch to convenient \"fast mode\" for profile creation going forward? (recommended)")
        large_text.setWordWrap(True)
        large_text.setStyleSheet("color: white; font-size: 18px;")
        large_text.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        v.addWidget(large_text)

        buttons_row = QWidget()
        h = QHBoxLayout(buttons_row)
        h.setContentsMargins(0, 0, 0, 0)
        h.setSpacing(20)

        yes_btn = QPushButton("Yes Fast Mode")
        yes_btn.setCursor(QtCore.Qt.CursorShape.PointingHandCursor)
        yes_btn.setFixedSize(240, 56)
        yes_btn.setStyleSheet("background-color: #27ae60; color: white; font-weight: bold; font-size: 16px; border: none; border-radius: 6px;")
        yes_btn.clicked.connect(self.choose_yes)

        no_btn = QPushButton("No Keep This")
        no_btn.setCursor(QtCore.Qt.CursorShape.PointingHandCursor)
        no_btn.setFixedSize(160, 42)
        no_btn.setStyleSheet("background-color: #c0392b; color: white; font-size: 14px; border: none; border-radius: 6px;")
        no_btn.clicked.connect(self.choose_no)

        h.addStretch()
        h.addWidget(yes_btn)
        h.addWidget(no_btn)
        h.addStretch()
        v.addWidget(buttons_row)

        small_text = QLabel("You can toggle this anytime in the \"Options\" Menu, under \"Create/Edit\"")
        small_text.setWordWrap(True)
        small_text.setStyleSheet("color: #999999; font-size: 12px;")
        small_text.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        v.addWidget(small_text)

    def finalize(self):
        self.update_status.mark_fast_mode_prompt_shown()
        self.page_stack.setCurrentIndex(self.page_stack.indexOf(self.page_stack.findChild(MenuPage)))

    def choose_yes(self):
        self.update_status.set_fast_mode_enabled(True)
        self.finalize()

    def choose_no(self):
        self.update_status.set_fast_mode_enabled(False)
        self.finalize()

    def initialize_default_selections(self):
        if not self.selected_values['location']:
            locations = self.connection_manager.get_location_list()
            if locations:
                random_index = random.randint(0, len(locations) - 1)
                self.selected_values['location'] = locations[random_index]
        
        if not self.selected_values['browser']:
            browsers = self.connection_manager.get_browser_list()
            if browsers:
                random_index = random.randint(0, len(browsers) - 1)
                self.selected_values['browser'] = browsers[random_index]

    def get_next_available_profile_id(self) -> int:
        profiles = ProfileController.get_all()
        if not profiles:
            return 1
            
        existing_ids = sorted(profiles.keys())
        
        for i in range(1, max(existing_ids) + 2):
            if i not in existing_ids:
                return i
                
        return 1
class QRCodeDialog(QDialog):
    def __init__(self, address_text, full_amount, currency_type=None, parent=None):
        super().__init__(parent)
        self.currency_type = currency_type
        self.setWindowTitle("Payment Address QR Code")
        self.setFixedSize(400, 450)
        self.setModal(True)
        
        layout = QVBoxLayout(self)
        
        title_label = QLabel("Scan QR Code to Copy Address", self)
        title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        title_label.setStyleSheet("font-size: 16px; font-weight: bold; color: #00ffff; margin: 10px;")
        layout.addWidget(title_label)
        
        qr_label = QLabel(self)
        qr_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        qr_label.setStyleSheet("margin: 10px; border: 2px solid #00ffff; border-radius: 10px;")
        
        qr_pixmap = self.generate_qr_code(address_text, full_amount)
        qr_label.setPixmap(qr_pixmap)
        layout.addWidget(qr_label)

        amount_label = QLabel("Amount:", self)
        amount_label.setStyleSheet("font-size: 12px; color: #ffffff; margin-top: 10px;")
        layout.addWidget(amount_label)
        
        amount_text_label = QLabel(full_amount, self)
        amount_text_label.setStyleSheet("font-size: 10px; color: #cccccc; margin: 5px; padding: 5px; border: 1px solid #666; border-radius: 5px;")
        layout.addWidget(amount_text_label)
        
        address_label = QLabel("Address:", self)
        address_label.setStyleSheet("font-size: 12px; color: #ffffff; margin-top: 10px;")
        layout.addWidget(address_label)
        
        address_text_label = QLabel(address_text, self)
        address_text_label.setWordWrap(True)
        address_text_label.setStyleSheet("font-size: 10px; color: #cccccc; margin: 5px; padding: 5px; border: 1px solid #666; border-radius: 5px;")
        layout.addWidget(address_text_label)
        
        close_button = QPushButton("Close", self)
        close_button.setStyleSheet("font-size: 14px; padding: 8px; margin: 10px;")
        close_button.clicked.connect(self.close)
        layout.addWidget(close_button)
        
        self.setStyleSheet("""
            QDialog {
                background-color: #2c3e50;
                border: 2px solid #00ffff;
                border-radius: 10px;
            }
        """)
    
    def generate_qr_code(self, text, full_amount):
        qr = qrcode.QRCode(
            version=1,
            error_correction=qrcode.constants.ERROR_CORRECT_L,
            box_size=8,
            border=4,
        )
        
        if self.currency_type:
            currency_lower = self.currency_type.lower()
            if currency_lower == 'bitcoin':
                qr_data = f"bitcoin:{text}?amount={full_amount}"
            elif currency_lower == 'monero':
                qr_data = f"monero:{text}?amount={full_amount}"
            elif currency_lower == 'lightning':
                qr_data = f"bitcoin:{text}?amount={full_amount}&lightning=ln"
            elif currency_lower == 'litecoin':
                qr_data = f"litecoin:{text}?amount={full_amount}"
            else:
                qr_data = f"{text}?amount={full_amount}"
        else:
            qr_data = text
            
        qr.add_data(qr_data)
        qr.make(fit=True)
        
        qr_image = qr.make_image(fill_color="black", back_color="white")
        
        buffer = BytesIO()
        qr_image.save(buffer, format='PNG')
        buffer.seek(0)
        
        pixmap = QPixmap()
        pixmap.loadFromData(buffer.getvalue())
        
        return pixmap.scaled(150, 150, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)



if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = CustomWindow()
    window.show()
    sys.exit(app.exec())