import gi
import os

gi.require_version("Gtk", "4.0")
import subprocess
from typing import List

from gi.repository import Gtk

# Diese Liste wird zur Laufzeit importiert, _() sollte durch main.py verfügbar sein.
MIRRORS = [
    f"{_('Standard')} - https://repo-default.voidlinux.org/",
    f"{_('Weltweit (Tier 1)')} - https://repo-fastly.voidlinux.org/",
    f"{_('Frankfurt (Tier 1)')} - https://repo-de.voidlinux.org/",
    f"{_('Helsinki (Tier 1)')} - https://repo-fi.voidlinux.org/",
    f"{_('Chicago (Tier 1)')} - https://mirrors.servercentral.com/voidlinux/",
]

# Technische Paketnamen - NICHT übersetzen
SERVICES_SET = [
    "chrony",
    "dbus",
    "NetworkManager",
    "polkit",
    "acpid",
    "cronie",
    "avahi-daemon",
    "bluetooth",
    "tlp",
    "smb",
]

# BASIS-PAKETE (Immer installiert)
BASE_SET = [
    # Original Minimal Base
    "espeakup", "void-live-audio", "brltty", "dialog", 
    "void-docs-browse", "xtools-minimal", "xmirror", "tmux",
    "grub-i386-efi", "grub-x86_64-efi", "chrony", "zramen",
    
    # Tools & Shell
    "bash-completion", "base-devel", "binutils", "dkms", "git", "wget", "curl", 
    "fzf", "topgrade", "vsv", "rsync", "tar", "unzip", "xz", 
    "rpm", "rpmextract", "avahi", "nss-mdns", "acpid", "cronie", "mtools", "xtools",
    
    # Filesystem & Partitioning
    "cryptsetup", "lvm2", "mdadm", "gptfdisk", "parted", "dosfstools", "exfatprogs", 
    "btrfs-progs", "grub-btrfs", "zfs", "zfs-auto-snapshot", "udisks2", "gvfs", 
    "gvfs-afc", "gvfs-afp", "gvfs-cdda", "gvfs-gphoto2", "gvfs-mtp", "gvfs-smb",
    
    # Hardware & Firmware
    "linux-headers", "linux-firmware", "linux-firmware-amd", "linux-firmware-intel", 
    "linux-firmware-nvidia", "linux-firmware-network", "broadcom-wl-dkms",
    "os-prober", "efibootmgr", "rtkit", "tlp", "tlpui",
    
    # Grafik Basics
    "mesa-dri", "mesa-nouveau-dri", "vdpauinfo", "libadwaita",
    "xorg-minimal", "xorg-video-drivers", "xorg-input-drivers", "xf86-video-nouveau",
    "xrandr", "setxkbmap", "xauth", "numlockx",
    
    # Audio (Basis) & Print
    "bluez", "bluez-cups",
    "cups", "gutenprint", "foomatic-db", "ipp-usb", "python3-cups",
    
    # UI & Fonts
    "dconf", "elogind", "dbus", "dbus-elogind", "dbus-elogind-x11",
    "papirus-icon-theme", "dejavu-fonts-ttf", "freefont-ttf", "liberation-fonts-ttf",
    "noto-fonts-emoji", "font-awesome6", "terminus-font",
    
    # Portals
    "xdg-user-dirs", "xdg-user-dirs-gtk", "xdg-utils",
    "xdg-desktop-portal", "xdg-desktop-portal-gtk", "xdg-desktop-portal-kde",
    "xdg-desktop-portal-gnome", "xdg-desktop-portal-xapp",
    
    # Apps & Repos
    "engrampa", "xarchiver", "tilix", "octoxbps", "ocs-url", "gtk+3",
    "void-repo-multilib", "void-repo-multilib-nonfree", "void-repo-nonfree",
    "python3", "python3-dbus", "python3-gobject", "python3-pyudev", "ca-certificates",
    
    # Hinzugefügt,
    "samba" 
]

XORG_SET = ["font-misc-misc", "orca"]

# --- DESKTOP ENVIRONMENTS ---

CINNAMON_SET = [
    "cinnamon", "cinnamon-control-center", "cinnamon-desktop", "cinnamon-screensaver",
    "cinnamon-session", "cinnamon-settings-daemon", "file-roller", "gnome-keyring",
    "gnome-screenshot", "gnome-terminal", "lightdm", "lightdm-gtk-greeter",
    "lightdm-gtk-greeter-settings", "mugshot", "nemo-audio-tab", "nemo-compare",
    "nemo-emblems", "nemo-extensions", "nemo-image-converter", "nemo-python",
    "simple-scan", "colord"
]

XFCE_SET = [
    "xfce4", "xfce4-appfinder", "xfce4-panel", "xfce4-notifyd", "xfce4-power-manager",
    "xfce4-screensaver", "xfce4-screenshooter", "xfce4-dev-tools", "xfce4-panel-profiles",
    "xfce4-plugins", "xfce4-battery-plugin", "xfce4-clipman-plugin", "xfce4-cpufreq-plugin",
    "xfce4-cpugraph-plugin", "xfce4-datetime-plugin", "xfce4-docklike-plugin",
    "xfce4-fsguard-plugin", "xfce4-sensors-plugin", "xfce4-wavelan-plugin",
    "xfce4-weather-plugin", "xfce4-whiskermenu-plugin",
    "Thunar", "thunar-archive-plugin", "thunar-media-tags-plugin", "thunar-volman", "tumbler",
    "lightdm", "lightdm-gtk-greeter", "lightdm-gtk-greeter-settings",
    "menulibre", "mugshot", "gnome-disk-utility", "gnome-icon-theme"
]

GNOME_SET = [
    "gdm", "gnome-core", "gnome-keyring", "sushi", "gnome-terminal",
    "gnome-disk-utility", "gnome-tweaks",
    "nautilus-gnome-terminal-extension", "extension-manager", "file-roller",
    "nautilus-papers-extension", "nautilus-python", "seahorse-nautilus"
]

KDE_SET = [
    "sddm", "kde5", "dolphin", "konsole", "ark", "kate", "gwenview", "okular", "spectacle",
    "dolphin-plugins", "kaccounts-integration", "kaccounts-providers", "kde-gtk-config",
    "kde5-baseapps", "kdegraphics-thumbnailers", "kdesu", "kfind", "kio-extras",
    "kscreen", "ksysguard", "plasma-browser-integration", "plasma-desktop",
    "plasma-nm", "plasma-pa", "sddm-kcm"
]

# --- AKTUALISIERTES LXQT SET ---
LXQT_SET = [
    # Basis & Window Manager
    "lxqt",                 # Das Meta-Paket
    "openbox", "obconf-qt", # Der Window Manager (Openbox ist Standard für LXQt)
    
    # Core Komponenten (explizit gewünscht)
    "pcmanfm-qt",           # Dateimanager
    "lxqt-admin",           # Admin-Tools (Datum/Zeit etc.)
    "lxqt-archiver",        # Archiv-Verwaltung (basiert auf libfm-qt)
    "lxqt-config",          # Kontrollzentrum
    "lxqt-menu-data",       # Menü-Strukturen
    "lxqt-notificationd",   # Benachrichtigungen
    "lxqt-panel",           # Taskleiste
    "lxqt-powermanagement", # Energieverwaltung
    "lxqt-runner",          # Schnellstarter (Alt+F2)
    "lxqt-sudo",            # Grafischer Sudo-Dialog
    "lxqt-themes",          # Designs
    
    # Qt Integration
    "lxqt-qtplugin",        # Integration von Qt-Einstellungen
    "lxqt-qt5plugin",       # Speziell für Qt5 Apps (falls noch vorhanden)
    
    # System Integration
    "xdg-desktop-portal-lxqt", # Wichtig für Flatpak & Dateidialoge
    "gnome-keyring",        # Passwort-Speicher
    
    # Apps & Icons
    "lximage-qt",           # Bildbetrachter
    "qterminal",            # Terminal
    "oxygen-icons", "breeze-icons",
    
    # Display Manager
    "sddm"                  # Empfohlener Login-Manager für Qt-Desktops
]

# --- AKTUALISIERTES LXDE SET ---
LXDE_SET = [
    "lxde",                 # Das Meta-Paket
    "lxde-common",          # Sitzungskonfigurationen
    "lxde-icon-theme",      # Standard-Icons
    "lxmenu-data",          # Menü-Strukturen
    
    # Core Komponenten
    "lxpanel",              # Die Taskleiste
    "lxrandr",              # Bildschirmauflösung
    "lxtask",               # Task-Manager
    "lxterminal",           # Terminal
    "pcmanfm",              # Dateimanager
    "libfm-extra",          # Bibliothek für Dateimanager-Funktionen
    
    # Login Manager & Tools
    "lxdm",                 # Display Manager
    "lxappearance",         # Themen-Einstellungen
    "leafpad",              # Einfacher Texteditor
    "gpicview",             # Bildbetrachter
    "openbox"               # Der Window Manager
]

# --- WINDOW MANAGERS ---

# --- I3 TILING WINDOW MANAGER (X11) ---
I3_SET = [
    "i3-gaps",              # Der WM mit Lücken zwischen den Fenstern
    "i3blocks",             # Flexiblere Statusleiste
    "i3status",             # Standard Statusleiste (Backup)
    "i3lock-color",         # Sperrbildschirm mit mehr Farboptionen
    "i3lockr",              # Wrapper/Glitch-Effekt für den Lockscreen
    "i3cat",                # Tool um Ausgaben für die Bar zu kombinieren
    "i3wsr",                # Workspace Renamer (automatische Benennung nach Icons)
    
    "rofi",                 # Launcher (Menü)
    "dmenu",                # Fallback Launcher
    "dunst",                # Benachrichtigungen
    
    "azote",                # Wallpaper Manager
    "autotiling",           # Skript für automatisches Tiling (Spiral/Master-Stack)
    "picom",                # Compositor (für Transparenz/Schatten)
    
    # GUI Tools & System
    "arandr",               # Bildschirmeinstellungen
    "lxappearance",         # Themes einstellen
    "network-manager-applet", # WLAN Tray Icon
    "polkit-gnome",         # Rechte-Verwaltung
    
    # Apps
    "alacritty",            # Terminal
    "thunar",               # Dateimanager
    
    # Login Manager
    "lightdm", "lightdm-gtk-greeter", "lightdm-gtk-greeter-settings"
]

# --- SWAY TILING WINDOW MANAGER (WAYLAND) ---
SWAY_SET = [
    "swayfx",               # Ersetzt 'sway' (bietet mehr optische Effekte wie Schatten/Runde Ecken)
    "swaybg",               # Hintergrundbilder
    "swayidle",             # Idle-Management
    "swaylock",             # Sperrbildschirm
    "swayimg",              # Bildbetrachter für Sway
    
    # Statusbar & Menü & Benachrichtigungen
    "waybar",               # Die Leiste (Statusbar)
    "rofi",                 # Anwendungsstarter (statt wofi, wie gewünscht)
    "dunst",                # Benachrichtigungs-Daemon (statt mako, wie gewünscht)
    
    # Tools & Konfiguration
    "kanshi",               # Automatisches Display-Profil-Management (Hotplugging)
    "azote",                # Wallpaper Manager & Monitor-Einstellung
    "autotiling",           # Skript für automatisches Tiling (Spiral/Master-Stack)
    "wdisplays",            # GUI für Monitoreinstellungen
    
    # Screenshot & Clipboard
    "grim", "slurp",        # Screenshot Basis-Tools
    "grimshot",             # Screenshot Skript (falls im Repo verfügbar)
    "wl-clipboard",         # Clipboard Manager
    
    # Kompatibilität
    "xorg-server-xwayland", # X11-Apps unter Wayland
    "qt5-wayland", "qt6-wayland", # Qt-Support
    
    # Basis-Apps
    "alacritty",            # Terminal
    "thunar",               # Dateimanager
    
    # System-Integration
    "network-manager-applet",
    "polkit-gnome",
    "lightdm", "lightdm-gtk-greeter"
]

# --- OPENBOX SET ---
OPENBOX_SET = [
    # Core & Konfiguration
    "openbox",              # Der Window Manager
    "obconf",               # GUI zum Konfigurieren von Openbox
    "lxappearance-obconf",  # Plugin, um Openbox-Themes in lxappearance zu wählen
    
    # Interface Elemente
    "tint2",                # Die klassische Taskleiste für Openbox
    "jgmenu",               # Modernes, dynamisches Menü (Startmenü)
    "dmenu",                # Minimalistischer Launcher
    "rofi",                 # Komfortabler Launcher
    "dunst",                # Benachrichtigungen
    
    # System Tray Apps (Wichtig für Usability!)
    "volumeicon",           # Lautstärke-Icon im Tray
    "cbatticon",            # Batterie-Icon im Tray
    "network-manager-applet", # WLAN-Icon
    
    # Optik & Verhalten
    "nitrogen",             # Wallpaper setzen
    "picom",                # Compositor (Schatten, Transparenz, V-Sync)
    "lxappearance",         # GTK-Themen und Icons einstellen
    "arandr",               # Bildschirm-Auflösung (GUI)
    
    # Tools
    "scrot",                # Screenshot Tool (einfach per Taste)
    "gmrun",                # Befehls-Ausführen Dialog
    "polkit-gnome",         # Authentifizierungs-Dialog (für Sudo-GUIs)
    
    # Basis Apps
    "thunar",               # Dateimanager (passt perfekt zu Openbox)
    "alacritty",            # Terminal
    
    # Login Manager
    "lightdm", "lightdm-gtk-greeter", "lightdm-gtk-greeter-settings"
]

# --- AWESOME SET ---
AWESOME_SET = [
    "awesome",              # Der WM
    "vicious",              # Widgets für Awesome (Battery, CPU, Mem etc.)
    "picom",                # Compositor
    "nitrogen",             # Wallpaper
    "rofi", "dmenu",        # Launcher
    
    # System Tray Helfer (da Awesome standardmäßig leer ist)
    "volumeicon",           # Audio Icon
    "cbatticon",            # Batterie Icon
    "network-manager-applet", # WLAN Icon
    
    # GUI Tools
    "arandr",               # Bildschirm
    "lxappearance",         # Themes
    "polkit-gnome",         # Auth
    "scrot",                # Screenshots
    
    # Apps
    "alacritty",            # Terminal
    "thunar",               # Files
    
    # Login
    "lightdm", "lightdm-gtk-greeter", "lightdm-gtk-greeter-settings"
]

# --- OPTIONALE BUNDLES ---

BUNDLE_NVIDIA = ["nvidia", "nvidia-dkms", "nvidia-firmware"]
BUNDLE_PRINTER = ["cups-pdf", "cups-filters"] 
BUNDLE_FLATPAK = ["flatpak"] 

BUNDLE_PIPEWIRE = [
    "pipewire", "wireplumber", "pavucontrol", "pulsemixer",
    "libspa-bluetooth", "alsa-utils", "paprefs",
    "alsa-pipewire", "alsa-ucm-conf", "gstreamer1-pipewire", "libpipewire"
]

BUNDLE_NONFREE_CODECS = [
    "ffmpeg", "ffmpegthumbnailer", "gst-libav", 
    "gst-plugins-base1", "gst-plugins-good1", "gst-plugins-bad1", "gst-plugins-ugly1",
    "x264", "x265"
]

BUNDLE_FIREFOX_DE = ["firefox", "firefox-i18n-de"]
BUNDLE_CHROMIUM = ["chromium"]
BUNDLE_VIVALDI = ["vivaldi"]
BUNDLE_EVOLUTION = ["evolution"]
BUNDLE_THUNDERBIRD_DE = ["thunderbird", "thunderbird-i18n-de"]

BUNDLE_LIBREOFFICE_DE = ["libreoffice", "libreoffice-i18n-de"]
PKG_GNOME_CALENDAR = "gnome-calendar"
PKG_PAPERS = "papers"
PKG_EVINCE = "evince"

PKG_VLC = "vlc"
PKG_RHYTHMBOX = "rhythmbox"
PKG_KDENLIVE = "kdenlive"
PKG_OBS = "obs"

PKG_TIMESHIFT = "timeshift"
PKG_GPARTED = "gparted"
PKG_GNOME_DISK = "gnome-disk-utility"
PKG_HTOP = "htop"
PKG_FASTFETCH = "fastfetch"


class SoftwareConfigView(Gtk.Box):
    # Page to select preferred applications and customizations
    def __init__(self):
        super().__init__(orientation=Gtk.Orientation.VERTICAL, spacing=12)
        for s in (
            self.set_margin_top,
            self.set_margin_bottom,
            self.set_margin_start,
            self.set_margin_end,
        ):
            s(6)

        title = Gtk.Label.new(_("Software & Konfiguration"))
        title.add_css_class("title-2")
        title.set_halign(Gtk.Align.START)
        self.append(title)
        sc = Gtk.ScrolledWindow()
        sc.set_vexpand(True)
        sc.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        self.append(sc)
        root = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)
        sc.set_child(root)

        # --- Repo Mirror ---
        f_repo = Gtk.Frame(label=_("Repository Server"))
        f_repo.add_css_class("card")
        root.append(f_repo)
        box_repo = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8, margin_top=10, margin_bottom=10, margin_start=10, margin_end=10)
        f_repo.set_child(box_repo)
        box_repo.append(Gtk.Label.new(_("Mirror:")))
        self.cmb_mirror = Gtk.ComboBoxText()
        for m in MIRRORS:
            self.cmb_mirror.append_text(m)
        try:
            idx = 0
            for i, m in enumerate(MIRRORS):
                if "repo-de.voidlinux.org" in m:
                    idx = i
                    break
            self.cmb_mirror.set_active(idx)
        except ValueError:
            self.cmb_mirror.set_active(0)
        box_repo.append(self.cmb_mirror)

        # --- ISO Packages ---
        f_iso = Gtk.Frame(label=_("Live-System Pakete"))
        f_iso.add_css_class("card")
        root.append(f_iso)
        box_iso = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6, margin_top=10, margin_bottom=10, margin_start=10, margin_end=10)
        f_iso.set_child(box_iso)
        self.cb_iso_packages = Gtk.CheckButton.new_with_label(_("Alle Pakete vom Live-System übernehmen"))
        self.cb_iso_packages.set_active(True)
        self.cb_iso_packages.set_tooltip_text(_("Installiert alle Pakete, die im Live-System derzeit vorhanden sind."))
        box_iso.append(self.cb_iso_packages)

        # --- Desktop Environment / WM Selection (5 Kacheln) ---
        f_de = Gtk.Frame(label=_("Desktop Umgebung / Window Manager"))
        f_de.add_css_class("card")
        root.append(f_de)
        
        # Grid mit 5 Spalten
        grid_de = Gtk.Grid(column_spacing=12, row_spacing=10, margin_top=10, margin_bottom=10, margin_start=10, margin_end=10)
        grid_de.set_column_homogeneous(True)
        f_de.set_child(grid_de)

        self.cb_cinnamon = Gtk.CheckButton.new_with_label("Cinnamon")
        grid_de.attach(self.cb_cinnamon, 0, 0, 1, 1)
        self.cb_gnome = Gtk.CheckButton.new_with_label("GNOME")
        grid_de.attach(self.cb_gnome, 1, 0, 1, 1)
        self.cb_kde = Gtk.CheckButton.new_with_label("KDE Plasma")
        grid_de.attach(self.cb_kde, 2, 0, 1, 1)
        self.cb_xfce = Gtk.CheckButton.new_with_label("XFCE")
        grid_de.attach(self.cb_xfce, 3, 0, 1, 1)
        self.cb_lxqt = Gtk.CheckButton.new_with_label("LXQt")
        grid_de.attach(self.cb_lxqt, 4, 0, 1, 1)

        self.cb_lxde = Gtk.CheckButton.new_with_label("LXDE")
        grid_de.attach(self.cb_lxde, 0, 1, 1, 1)
        self.cb_i3 = Gtk.CheckButton.new_with_label("i3 (Tiling)")
        grid_de.attach(self.cb_i3, 1, 1, 1, 1)
        self.cb_sway = Gtk.CheckButton.new_with_label("Sway (Wayland)")
        grid_de.attach(self.cb_sway, 2, 1, 1, 1)
        self.cb_openbox = Gtk.CheckButton.new_with_label("Openbox")
        grid_de.attach(self.cb_openbox, 3, 1, 1, 1)
        self.cb_awesome = Gtk.CheckButton.new_with_label("Awesome WM")
        grid_de.attach(self.cb_awesome, 4, 1, 1, 1)

        # --- Additional Packages ---
        f_extra = Gtk.Frame(label=_("Zusätzliche Pakete"))
        f_extra.add_css_class("card")
        root.append(f_extra)
        
        grid_main = Gtk.Grid(column_spacing=12, row_spacing=12, margin_top=10, margin_bottom=10, margin_start=10, margin_end=10)
        grid_main.set_column_homogeneous(True)
        grid_main.set_row_homogeneous(True)
        f_extra.set_child(grid_main)

        # Col 0: Hardware & Services
        frame_system = Gtk.Frame(label=_("Treiber & Dienste"))
        frame_system.add_css_class("card")
        grid_main.attach(frame_system, 0, 0, 1, 1)
        box_system = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8, margin_top=5, margin_bottom=5, margin_start=5, margin_end=5)
        frame_system.set_child(box_system)
        
        self.cb_nvidia = Gtk.CheckButton.new_with_label(_("NVIDIA Treiber"))
        box_system.append(self.cb_nvidia)
        
        self.cb_printer = Gtk.CheckButton.new_with_label(_("Drucker"))
        box_system.append(self.cb_printer)
        
        # Pipewire wieder auswählbar
        self.cb_pipewire = Gtk.CheckButton.new_with_label("PipeWire Audio")
        self.cb_pipewire.set_active(False) 
        box_system.append(self.cb_pipewire)
        
        # Codecs wieder auswählbar
        self.cb_codecs = Gtk.CheckButton.new_with_label(_("Nonfree Codecs"))
        self.cb_codecs.set_active(False)
        box_system.append(self.cb_codecs)
        
        self.cb_flatpak = Gtk.CheckButton.new_with_label("Flatpak")
        box_system.append(self.cb_flatpak)

        # Col 1: Internet
        frame_internet = Gtk.Frame(label=_("Internet"))
        frame_internet.add_css_class("card")
        grid_main.attach(frame_internet, 1, 0, 1, 1)
        box_internet = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8, margin_top=5, margin_bottom=5, margin_start=5, margin_end=5)
        frame_internet.set_child(box_internet)
        self.cb_firefox = Gtk.CheckButton.new_with_label(_("Firefox (de)"))
        box_internet.append(self.cb_firefox)
        self.cb_chromium = Gtk.CheckButton.new_with_label("Chromium")
        box_internet.append(self.cb_chromium)
        self.cb_vivaldi = Gtk.CheckButton.new_with_label("Vivaldi")
        box_internet.append(self.cb_vivaldi)
        self.cb_evolution = Gtk.CheckButton.new_with_label("Evolution")
        box_internet.append(self.cb_evolution)
        self.cb_thunderbird = Gtk.CheckButton.new_with_label(_("Thunderbird (de)"))
        box_internet.append(self.cb_thunderbird)

        # Col 2: Office
        frame_office = Gtk.Frame(label=_("Office"))
        frame_office.add_css_class("card")
        grid_main.attach(frame_office, 2, 0, 1, 1)
        box_office = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8, margin_top=5, margin_bottom=5, margin_start=5, margin_end=5)
        frame_office.set_child(box_office)
        self.cb_libre = Gtk.CheckButton.new_with_label(_("LibreOffice (de)"))
        box_office.append(self.cb_libre)
        self.cb_calendar = Gtk.CheckButton.new_with_label("GNOME Calendar")
        box_office.append(self.cb_calendar)
        self.cb_papers = Gtk.CheckButton.new_with_label("Papers")
        box_office.append(self.cb_papers)
        self.cb_evince = Gtk.CheckButton.new_with_label("Evince (PDF)")
        box_office.append(self.cb_evince)

        # Col 3: Multimedia
        frame_media = Gtk.Frame(label=_("Multimedia"))
        frame_media.add_css_class("card")
        grid_main.attach(frame_media, 3, 0, 1, 1)
        box_media = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8, margin_top=5, margin_bottom=5, margin_start=5, margin_end=5)
        frame_media.set_child(box_media)
        self.cb_vlc = Gtk.CheckButton.new_with_label("VLC")
        box_media.append(self.cb_vlc)
        self.cb_rhythmbox = Gtk.CheckButton.new_with_label("Rhythmbox")
        box_media.append(self.cb_rhythmbox)
        self.cb_kdenlive = Gtk.CheckButton.new_with_label("Kdenlive")
        box_media.append(self.cb_kdenlive)
        self.cb_obs = Gtk.CheckButton.new_with_label("OBS Studio")
        box_media.append(self.cb_obs)

        # Col 4: Tools
        frame_sys_tools = Gtk.Frame(label=_("System-Tools"))
        frame_sys_tools.add_css_class("card")
        grid_main.attach(frame_sys_tools, 4, 0, 1, 1)
        box_sys_tools = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8, margin_top=5, margin_bottom=5, margin_start=5, margin_end=5)
        frame_sys_tools.set_child(box_sys_tools)
        
        self.cb_timeshift = Gtk.CheckButton.new_with_label("Timeshift")
        box_sys_tools.append(self.cb_timeshift)
        
        self.cb_gparted = Gtk.CheckButton.new_with_label("GParted")
        self.cb_gparted.set_active(False)
        box_sys_tools.append(self.cb_gparted)
        
        self.cb_gnome_disks = Gtk.CheckButton.new_with_label("GNOME Disks")
        box_sys_tools.append(self.cb_gnome_disks)
        
        self.cb_htop = Gtk.CheckButton.new_with_label("Htop")
        box_sys_tools.append(self.cb_htop)
        
        self.cb_fastfetch = Gtk.CheckButton.new_with_label("Fastfetch")
        self.cb_fastfetch.set_active(False)
        box_sys_tools.append(self.cb_fastfetch)

        # --- Copy Options ---
        f_copy = Gtk.Frame(label=_("Anpassungen kopieren"))
        f_copy.add_css_class("card")
        root.append(f_copy)
        box_copy = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12, margin_top=10, margin_bottom=10, margin_start=10, margin_end=10)
        f_copy.set_child(box_copy)

        self.rb_copy_none = Gtk.CheckButton.new_with_label(_("Nichts kopieren"))
        self.rb_copy_iso = Gtk.CheckButton.new_with_label(_("ISO-Anpassungen kopieren"))
        self.rb_copy_include = Gtk.CheckButton.new_with_label(_("Inhalt aus /opt/INCLUDE kopieren"))

        self.rb_copy_iso.set_group(self.rb_copy_none)
        self.rb_copy_include.set_group(self.rb_copy_none)
        self.rb_copy_iso.set_active(True)

        self.rb_copy_none.connect("toggled", self._on_copy_option_changed)
        self.rb_copy_iso.connect("toggled", self._on_copy_option_changed)
        self.rb_copy_include.connect("toggled", self._on_copy_option_changed)

        box_copy.append(self.rb_copy_none)
        box_copy.append(self.rb_copy_iso)
        box_copy.append(self.rb_copy_include)

        iso_info = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8)
        iso_info.set_margin_start(20)
        iso_label = Gtk.Label.new(_("Tipp: Lege im Include-Ordner die gleiche Verzeichnisstruktur wie im Ziel an, alles wird 1:1 kopiert."))
        iso_label.set_wrap(True)
        iso_info.append(iso_label)
        box_copy.append(iso_info)

        # NEU: Hinweis statt Filechooser mit festem Pfad
        include_info_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8)
        include_info_box.set_margin_start(20)
        include_hint = Gtk.Label.new(_("Hinweis: Es muss ein Ordner '/opt/INCLUDE' existieren. Dessen Inhalt wird kopiert."))
        include_hint.set_wrap(True)
        include_hint.add_css_class("dim-label")
        include_info_box.append(include_hint)
        box_copy.append(include_info_box)

    def get_selected_mirror(self) -> str:
        txt = self.cmb_mirror.get_active_text() or ""
        return txt if txt else MIRRORS[0]

    def get_mirror_url(self) -> str:
        selected = self.get_selected_mirror()
        if "https://" in selected:
            return "https://" + selected.split("https://", 1)[1].strip().rstrip("/")
        return "https://repo-default.voidlinux.org"

    def get_selected_packages(self) -> List[str]:
        pkgs: List[str] = []
        
        # Desktop Environments
        if self.cb_cinnamon.get_active():
            pkgs.extend(CINNAMON_SET)
            pkgs.extend(SERVICES_SET)
            pkgs.extend(BASE_SET)
            pkgs.extend(XORG_SET)
        if self.cb_xfce.get_active():
            pkgs.extend(XFCE_SET)
            pkgs.extend(SERVICES_SET)
            pkgs.extend(BASE_SET)
            pkgs.extend(XORG_SET)
        if self.cb_gnome.get_active():
            pkgs.extend(GNOME_SET)
            pkgs.extend(SERVICES_SET)
            pkgs.extend(BASE_SET)
            pkgs.extend(XORG_SET)
        if self.cb_kde.get_active():
            pkgs.extend(KDE_SET)
            pkgs.extend(SERVICES_SET)
            pkgs.extend(BASE_SET)
            pkgs.extend(XORG_SET)
        if self.cb_lxqt.get_active():
            pkgs.extend(LXQT_SET)
            pkgs.extend(SERVICES_SET)
            pkgs.extend(BASE_SET)
            pkgs.extend(XORG_SET)
        if self.cb_lxde.get_active():
            pkgs.extend(LXDE_SET)
            pkgs.extend(SERVICES_SET)
            pkgs.extend(BASE_SET)
            pkgs.extend(XORG_SET)
        
        # Window Managers
        if self.cb_i3.get_active():
            pkgs.extend(I3_SET)
            pkgs.extend(SERVICES_SET)
            pkgs.extend(BASE_SET)
            pkgs.extend(XORG_SET)
        if self.cb_sway.get_active():
            pkgs.extend(SWAY_SET)
            pkgs.extend(SERVICES_SET)
            pkgs.extend(BASE_SET)
            pkgs.extend(XORG_SET) 
        if self.cb_openbox.get_active():
            pkgs.extend(OPENBOX_SET)
            pkgs.extend(SERVICES_SET)
            pkgs.extend(BASE_SET)
            pkgs.extend(XORG_SET)
        if self.cb_awesome.get_active():
            pkgs.extend(AWESOME_SET)
            pkgs.extend(SERVICES_SET)
            pkgs.extend(BASE_SET)
            pkgs.extend(XORG_SET)
            
        # Hardware / Drivers
        if self.cb_nvidia.get_active():
            pkgs.extend(BUNDLE_NVIDIA)
        if self.cb_printer.get_active():
            pkgs.extend(BUNDLE_PRINTER)
        
        # Checkbox Logik für optionale Pakete
        if self.cb_pipewire.get_active():
            pkgs.extend(BUNDLE_PIPEWIRE)
        if self.cb_codecs.get_active():
            pkgs.extend(BUNDLE_NONFREE_CODECS)
        
        if self.cb_flatpak.get_active():
            pkgs.extend(BUNDLE_FLATPAK)

        # Internet
        if self.cb_firefox.get_active():
            pkgs.extend(BUNDLE_FIREFOX_DE)
        if self.cb_chromium.get_active():
            pkgs.extend(BUNDLE_CHROMIUM)
        if self.cb_vivaldi.get_active():
            pkgs.extend(BUNDLE_VIVALDI)
        if self.cb_evolution.get_active():
            pkgs.extend(BUNDLE_EVOLUTION)
        if self.cb_thunderbird.get_active():
            pkgs.extend(BUNDLE_THUNDERBIRD_DE)
            
        # Office
        if self.cb_libre.get_active():
            pkgs.extend(BUNDLE_LIBREOFFICE_DE)
        if self.cb_calendar.get_active():
            pkgs.append(PKG_GNOME_CALENDAR)
        if self.cb_papers.get_active():
            pkgs.append(PKG_PAPERS)
        if self.cb_evince.get_active():
            pkgs.append(PKG_EVINCE)
            
        # Multimedia
        if self.cb_vlc.get_active():
            pkgs.append(PKG_VLC)
        if self.cb_rhythmbox.get_active():
            pkgs.append(PKG_RHYTHMBOX)
        if self.cb_kdenlive.get_active():
            pkgs.append(PKG_KDENLIVE)
        if self.cb_obs.get_active():
            pkgs.append(PKG_OBS)
            
        # System Tools
        if self.cb_timeshift.get_active():
            pkgs.append(PKG_TIMESHIFT)
        if self.cb_gparted.get_active():
            pkgs.append(PKG_GPARTED)
        if self.cb_gnome_disks.get_active():
            pkgs.append(PKG_GNOME_DISK)
        if self.cb_htop.get_active():
            pkgs.append(PKG_HTOP)
        if self.cb_fastfetch.get_active():
            pkgs.append(PKG_FASTFETCH)

        if self.cb_iso_packages.get_active():
            iso_packages = self._get_live_system_packages()
            pkgs.extend(iso_packages)

        # BASE_SET immer installieren
        pkgs.extend(BASE_SET)

        seen = set()
        out = []
        for p in pkgs:
            if p not in seen:
                out.append(p)
                seen.add(p)
        return out

    def get_include_root(self) -> str:
        # Pfad fixieren: /opt/INCLUDE
        return "/opt/INCLUDE"

    def _on_copy_option_changed(self, button):
        pass # Buttons ändern nichts mehr am UI

    def _on_choose_folder_clicked(self, button):
        pass

    def _on_folder_selected(self, dialog, result):
        pass

    def get_copy_option(self) -> str:
        if self.rb_copy_none.get_active():
            return "none"
        elif self.rb_copy_iso.get_active():
            return "iso"
        elif self.rb_copy_include.get_active():
            return "include"

    def _get_live_system_packages(self) -> List[str]:
        try:
            result = subprocess.run(
                ["xbps-query", "-m"], capture_output=True, text=True, check=True
            )
            packages = []
            for line in result.stdout.split("\n"):
                line = line.strip()
                if line and line.startswith("ii"):
                    parts = line.split()
                    if len(parts) >= 2:
                        pkg_full = parts[1]
                        pkg_name = pkg_full.rsplit("-", 2)[0]
                        packages.append(pkg_name)
            return packages
        except Exception:
            return []