#!/usr/bin/env python3
"""
Lite Theme Manager - GTK4 + libadwaita
A modern theme manager for XFCE desktop - managing UI themes, icons, and cursors.
"""

import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Adw, Gio, GLib
import os
import subprocess
import shutil
import tempfile
import webbrowser
from pathlib import Path


class LiteThemeManager(Adw.Application):
    def __init__(self):
        super().__init__(
            application_id="com.lite.thememanager",
            flags=Gio.ApplicationFlags.FLAGS_NONE
        )
        self.window = None
        
        # Directories
        self.home = Path.home()
        self.themes_dir = self.home / ".themes"
        self.icons_dir = self.home / ".icons"
        self.system_themes_dir = Path("/usr/share/themes")
        self.system_icons_dir = Path("/usr/share/icons")
        
        # Ensure directories exist
        self.themes_dir.mkdir(parents=True, exist_ok=True)
        self.icons_dir.mkdir(parents=True, exist_ok=True)
    
    def xfconf_get(self, channel, prop):
        """Get a value from xfconf"""
        try:
            result = subprocess.run(
                ['xfconf-query', '-c', channel, '-p', prop],
                capture_output=True, text=True
            )
            if result.returncode == 0:
                return result.stdout.strip()
        except Exception:
            pass
        return ""
    
    def xfconf_set(self, channel, prop, value):
        """Set a value in xfconf"""
        try:
            subprocess.run(
                ['xfconf-query', '-c', channel, '-p', prop, '-s', value],
                check=True
            )
            return True
        except Exception as e:
            print(f"xfconf-query error: {e}")
            return False

    def do_activate(self):
        if not self.window:
            self.window = MainWindow(application=self)
        self.window.present()


class MainWindow(Adw.ApplicationWindow):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.app = self.get_application()
        
        self.set_title("Lite Theme Manager")
        self.set_default_size(400, 500)
        
        self.setup_ui()
    
    def setup_ui(self):
        # Main box
        main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.set_content(main_box)
        
        # Header bar
        header = Adw.HeaderBar()
        main_box.append(header)
        
        # Content with clamp for proper sizing
        clamp = Adw.Clamp()
        clamp.set_maximum_size(600)
        clamp.set_margin_top(24)
        clamp.set_margin_bottom(24)
        clamp.set_margin_start(12)
        clamp.set_margin_end(12)
        main_box.append(clamp)
        
        # Content box
        content_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=24)
        clamp.set_child(content_box)
        
        # Welcome banner
        welcome_group = Adw.PreferencesGroup()
        welcome_group.set_title("Welcome to Lite Theme Manager")
        welcome_group.set_description("Customize your desktop appearance")
        content_box.append(welcome_group)
        
        # Browse online row
        browse_row = Adw.ActionRow()
        browse_row.set_title("Browse Themes Online")
        browse_row.set_subtitle("Find new themes on Pling.com")
        browse_row.add_prefix(Gtk.Image.new_from_icon_name("web-browser-symbolic"))
        browse_row.set_activatable(True)
        browse_row.connect("activated", self.on_browse_themes)
        browse_row.add_suffix(Gtk.Image.new_from_icon_name("go-next-symbolic"))
        welcome_group.add(browse_row)
        
        # Theme Management group
        manage_group = Adw.PreferencesGroup()
        manage_group.set_title("Theme Management")
        content_box.append(manage_group)
        
        # Install theme row
        install_row = Adw.ActionRow()
        install_row.set_title("Install New Theme")
        install_row.set_subtitle("Install from .tar.gz, .tar.xz, .zip, or .rar")
        install_row.add_prefix(Gtk.Image.new_from_icon_name("list-add-symbolic"))
        install_row.set_activatable(True)
        install_row.connect("activated", self.on_install_theme)
        install_row.add_suffix(Gtk.Image.new_from_icon_name("go-next-symbolic"))
        manage_group.add(install_row)
        
        # Remove theme row
        remove_row = Adw.ActionRow()
        remove_row.set_title("Remove Theme")
        remove_row.set_subtitle("Uninstall user-installed themes")
        remove_row.add_prefix(Gtk.Image.new_from_icon_name("list-remove-symbolic"))
        remove_row.set_activatable(True)
        remove_row.connect("activated", self.on_remove_theme)
        remove_row.add_suffix(Gtk.Image.new_from_icon_name("go-next-symbolic"))
        manage_group.add(remove_row)
        
        # Theme Settings group
        settings_group = Adw.PreferencesGroup()
        settings_group.set_title("Theme Settings")
        content_box.append(settings_group)
        
        # Change UI theme row
        ui_row = Adw.ActionRow()
        ui_row.set_title("Change UI Theme")
        ui_row.set_subtitle("Change the GTK application theme")
        ui_row.add_prefix(Gtk.Image.new_from_icon_name("preferences-desktop-theme-symbolic"))
        ui_row.set_activatable(True)
        ui_row.connect("activated", self.on_change_ui_theme)
        ui_row.add_suffix(Gtk.Image.new_from_icon_name("go-next-symbolic"))
        settings_group.add(ui_row)
        
        # Change cursor theme row
        cursor_row = Adw.ActionRow()
        cursor_row.set_title("Change Mouse Cursor Theme")
        cursor_row.set_subtitle("Change the cursor appearance")
        cursor_row.add_prefix(Gtk.Image.new_from_icon_name("input-mouse-symbolic"))
        cursor_row.set_activatable(True)
        cursor_row.connect("activated", self.on_change_cursor_theme)
        cursor_row.add_suffix(Gtk.Image.new_from_icon_name("go-next-symbolic"))
        settings_group.add(cursor_row)
        
        # Change icons theme row
        icons_row = Adw.ActionRow()
        icons_row.set_title("Change Icons Theme")
        icons_row.set_subtitle("Change the icon set")
        icons_row.add_prefix(Gtk.Image.new_from_icon_name("folder-symbolic"))
        icons_row.set_activatable(True)
        icons_row.connect("activated", self.on_change_icons_theme)
        icons_row.add_suffix(Gtk.Image.new_from_icon_name("go-next-symbolic"))
        settings_group.add(icons_row)

    def on_browse_themes(self, row):
        webbrowser.open("https://www.pling.com/s/XFCE/browse")

    def on_install_theme(self, row):
        dialog = InstallThemeDialog(self)
        dialog.present(self)

    def on_remove_theme(self, row):
        dialog = RemoveThemeDialog(self)
        dialog.present(self)

    def on_change_ui_theme(self, row):
        themes = self.get_ui_themes()
        current = self.app.xfconf_get('xsettings', '/Net/ThemeName')
        dialog = ThemeSelectionDialog(
            self, "Select UI Theme", themes, current,
            lambda theme: self.apply_ui_theme(theme)
        )
        dialog.present(self)

    def on_change_cursor_theme(self, row):
        themes = self.get_cursor_themes()
        current = self.app.xfconf_get('xsettings', '/Gtk/CursorThemeName')
        dialog = ThemeSelectionDialog(
            self, "Select Cursor Theme", themes, current,
            lambda theme: self.apply_cursor_theme(theme)
        )
        dialog.present(self)

    def on_change_icons_theme(self, row):
        themes = self.get_icon_themes()
        current = self.app.xfconf_get('xsettings', '/Net/IconThemeName')
        dialog = ThemeSelectionDialog(
            self, "Select Icons Theme", themes, current,
            lambda theme: self.apply_icon_theme(theme)
        )
        dialog.present(self)

    def get_ui_themes(self):
        themes = set()
        for themes_dir in [self.app.themes_dir, self.app.system_themes_dir]:
            if themes_dir.exists():
                for item in themes_dir.iterdir():
                    # Include all theme directories (matching original script)
                    if item.is_dir():
                        themes.add(item.name)
        return sorted(themes)

    def get_cursor_themes(self):
        themes = set()
        for icons_dir in [self.app.icons_dir, self.app.system_icons_dir]:
            if icons_dir.exists():
                for item in icons_dir.iterdir():
                    if item.is_dir() and (item / "cursors").exists():
                        themes.add(item.name)
        return sorted(themes)

    def get_icon_themes(self):
        themes = set()
        for icons_dir in [self.app.icons_dir, self.app.system_icons_dir]:
            if icons_dir.exists():
                for item in icons_dir.iterdir():
                    # Include directories that don't have a cursors subfolder
                    # (matching original script behavior)
                    if item.is_dir() and not (item / "cursors").exists():
                        themes.add(item.name)
        return sorted(themes)

    def apply_ui_theme(self, theme):
        # Set GTK theme
        self.app.xfconf_set('xsettings', '/Net/ThemeName', theme)
        # Set window manager theme
        self.app.xfconf_set('xfwm4', '/general/theme', theme)
        self.show_toast(f"UI theme changed to {theme}")

    def apply_cursor_theme(self, theme):
        self.app.xfconf_set('xsettings', '/Gtk/CursorThemeName', theme)
        self.show_toast(f"Cursor theme changed to {theme}")

    def apply_icon_theme(self, theme):
        self.app.xfconf_set('xsettings', '/Net/IconThemeName', theme)
        self.show_toast(f"Icon theme changed to {theme}")

    def show_toast(self, message):
        toast = Adw.Toast.new(message)
        toast.set_timeout(3)
        # Find or create toast overlay
        if not hasattr(self, 'toast_overlay'):
            self.toast_overlay = Adw.ToastOverlay()
            content = self.get_content()
            self.set_content(self.toast_overlay)
            self.toast_overlay.set_child(content)
        self.toast_overlay.add_toast(toast)


class ThemeSelectionDialog(Adw.Dialog):
    def __init__(self, parent, title, themes, current_theme, callback):
        super().__init__()
        self.parent_window = parent
        self.callback = callback
        self.selected_theme = current_theme
        
        self.set_title(title)
        self.set_content_width(400)
        self.set_content_height(650)
        
        # Main box
        main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.set_child(main_box)
        
        # Header bar
        header = Adw.HeaderBar()
        header.set_show_end_title_buttons(False)
        header.set_show_start_title_buttons(False)
        
        cancel_btn = Gtk.Button(label="Cancel")
        cancel_btn.connect("clicked", lambda b: self.close())
        header.pack_start(cancel_btn)
        
        apply_btn = Gtk.Button(label="Apply")
        apply_btn.add_css_class("suggested-action")
        apply_btn.connect("clicked", self.on_apply)
        header.pack_end(apply_btn)
        
        main_box.append(header)
        
        # Scrolled window for theme list
        scrolled = Gtk.ScrolledWindow()
        scrolled.set_vexpand(True)
        scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        main_box.append(scrolled)
        
        # List box for themes
        clamp = Adw.Clamp()
        clamp.set_margin_top(12)
        clamp.set_margin_bottom(12)
        clamp.set_margin_start(12)
        clamp.set_margin_end(12)
        scrolled.set_child(clamp)
        
        self.listbox = Gtk.ListBox()
        self.listbox.set_selection_mode(Gtk.SelectionMode.NONE)
        self.listbox.add_css_class("boxed-list")
        clamp.set_child(self.listbox)
        
        # Add themes with radio button behavior
        self.check_buttons = {}
        first_check = None
        
        if not themes:
            row = Adw.ActionRow()
            row.set_title("No themes found")
            row.set_sensitive(False)
            self.listbox.append(row)
        else:
            for theme in themes:
                row = Adw.ActionRow()
                row.set_title(theme)
                row.theme_name = theme
                
                check = Gtk.CheckButton()
                if first_check is None:
                    first_check = check
                else:
                    check.set_group(first_check)
                
                check.set_active(theme == current_theme)
                check.connect("toggled", self.on_check_toggled, theme)
                self.check_buttons[theme] = check
                
                row.add_prefix(check)
                row.set_activatable_widget(check)
                
                self.listbox.append(row)

    def on_check_toggled(self, check_button, theme):
        if check_button.get_active():
            self.selected_theme = theme

    def on_apply(self, button):
        if self.selected_theme:
            self.callback(self.selected_theme)
        self.close()


class InstallThemeDialog(Adw.Dialog):
    def __init__(self, parent):
        super().__init__()
        self.parent_window = parent
        self.selected_file = None
        self.selected_type = None
        
        self.set_title("Install Theme")
        self.set_content_width(400)
        self.set_content_height(350)
        
        # Main box
        main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.set_child(main_box)
        
        # Header bar
        header = Adw.HeaderBar()
        header.set_show_end_title_buttons(False)
        header.set_show_start_title_buttons(False)
        
        cancel_btn = Gtk.Button(label="Cancel")
        cancel_btn.connect("clicked", lambda b: self.close())
        header.pack_start(cancel_btn)
        
        self.install_btn = Gtk.Button(label="Install")
        self.install_btn.add_css_class("suggested-action")
        self.install_btn.set_sensitive(False)
        self.install_btn.connect("clicked", self.on_install)
        header.pack_end(self.install_btn)
        
        main_box.append(header)
        
        # Content
        clamp = Adw.Clamp()
        clamp.set_margin_top(24)
        clamp.set_margin_bottom(24)
        clamp.set_margin_start(12)
        clamp.set_margin_end(12)
        main_box.append(clamp)
        
        content = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=24)
        clamp.set_child(content)
        
        # Info banner
        banner = Adw.Banner()
        banner.set_title("Download themes from the web in .tar.gz, .tar.xz, .zip, or .rar format")
        banner.set_revealed(True)
        content.append(banner)
        
        # File selection group
        file_group = Adw.PreferencesGroup()
        file_group.set_title("Theme File")
        content.append(file_group)
        
        self.file_row = Adw.ActionRow()
        self.file_row.set_title("Select File")
        self.file_row.set_subtitle("No file selected")
        self.file_row.add_prefix(Gtk.Image.new_from_icon_name("folder-open-symbolic"))
        self.file_row.set_activatable(True)
        self.file_row.connect("activated", self.on_select_file)
        self.file_row.add_suffix(Gtk.Image.new_from_icon_name("go-next-symbolic"))
        file_group.add(self.file_row)
        
        # Type selection group
        type_group = Adw.PreferencesGroup()
        type_group.set_title("Theme Type")
        content.append(type_group)
        
        # Radio buttons for type selection
        self.ui_check = Gtk.CheckButton(label="UI Theme")
        self.icon_check = Gtk.CheckButton(label="Icon Theme")
        self.cursor_check = Gtk.CheckButton(label="Cursor Theme")
        
        self.icon_check.set_group(self.ui_check)
        self.cursor_check.set_group(self.ui_check)
        
        self.ui_check.connect("toggled", self.on_type_changed, "UI theme")
        self.icon_check.connect("toggled", self.on_type_changed, "Icons theme")
        self.cursor_check.connect("toggled", self.on_type_changed, "Cursor theme")
        
        ui_row = Adw.ActionRow()
        ui_row.set_title("UI Theme")
        ui_row.set_subtitle("GTK themes for window decoration")
        ui_row.add_prefix(self.ui_check)
        ui_row.set_activatable_widget(self.ui_check)
        type_group.add(ui_row)
        
        icon_row = Adw.ActionRow()
        icon_row.set_title("Icon Theme")
        icon_row.set_subtitle("Icon sets for applications")
        icon_row.add_prefix(self.icon_check)
        icon_row.set_activatable_widget(self.icon_check)
        type_group.add(icon_row)
        
        cursor_row = Adw.ActionRow()
        cursor_row.set_title("Cursor Theme")
        cursor_row.set_subtitle("Mouse cursor styles")
        cursor_row.add_prefix(self.cursor_check)
        cursor_row.set_activatable_widget(self.cursor_check)
        type_group.add(cursor_row)

    def on_select_file(self, row):
        dialog = Gtk.FileDialog()
        dialog.set_title("Select Theme File")
        
        # File filter
        filter_store = Gio.ListStore.new(Gtk.FileFilter)
        
        archive_filter = Gtk.FileFilter()
        archive_filter.set_name("Archive files")
        archive_filter.add_pattern("*.tar.gz")
        archive_filter.add_pattern("*.tar.xz")
        archive_filter.add_pattern("*.zip")
        archive_filter.add_pattern("*.rar")
        filter_store.append(archive_filter)
        
        dialog.set_filters(filter_store)
        dialog.set_default_filter(archive_filter)
        
        dialog.open(self.parent_window, None, self.on_file_selected)

    def on_file_selected(self, dialog, result):
        try:
            file = dialog.open_finish(result)
            if file:
                self.selected_file = file.get_path()
                self.file_row.set_subtitle(Path(self.selected_file).name)
                self.update_install_button()
        except GLib.Error:
            pass

    def on_type_changed(self, button, theme_type):
        if button.get_active():
            self.selected_type = theme_type
            self.update_install_button()

    def update_install_button(self):
        self.install_btn.set_sensitive(
            self.selected_file is not None and self.selected_type is not None
        )

    def on_install(self, button):
        if not self.selected_file or not self.selected_type:
            return
        
        try:
            temp_dir = tempfile.mkdtemp()
            file_path = self.selected_file
            
            # Extract archive
            if file_path.endswith('.tar.gz'):
                subprocess.run(['tar', '-xzf', file_path, '-C', temp_dir], check=True)
            elif file_path.endswith('.tar.xz'):
                subprocess.run(['tar', '-xJf', file_path, '-C', temp_dir], check=True)
            elif file_path.endswith('.zip'):
                subprocess.run(['unzip', '-q', file_path, '-d', temp_dir], check=True)
            elif file_path.endswith('.rar'):
                subprocess.run(['unrar', 'x', '-y', file_path, temp_dir], check=True)
            else:
                self.show_error("Unsupported file format")
                shutil.rmtree(temp_dir)
                return
            
            # Find and move theme
            installed = False
            app = self.parent_window.app
            
            for root, dirs, files in os.walk(temp_dir):
                root_path = Path(root)
                
                if self.selected_type == "UI theme":
                    # Look for GTK theme indicators
                    if (root_path / "gtk-3.0").exists() or (root_path / "gtk-4.0").exists() or (root_path / "xfwm4").exists():
                        dest = app.themes_dir / root_path.name
                        if dest.exists():
                            shutil.rmtree(dest)
                        shutil.move(str(root_path), str(app.themes_dir))
                        installed = True
                        break
                        
                elif self.selected_type == "Icons theme":
                    if (root_path / "index.theme").exists() and not (root_path / "cursors").exists():
                        dest = app.icons_dir / root_path.name
                        if dest.exists():
                            shutil.rmtree(dest)
                        shutil.move(str(root_path), str(app.icons_dir))
                        installed = True
                        break
                        
                elif self.selected_type == "Cursor theme":
                    if (root_path / "cursors").exists():
                        dest = app.icons_dir / root_path.name
                        if dest.exists():
                            shutil.rmtree(dest)
                        shutil.move(str(root_path), str(app.icons_dir))
                        installed = True
                        break
            
            shutil.rmtree(temp_dir, ignore_errors=True)
            
            if installed:
                self.parent_window.show_toast("Theme installed successfully!")
                self.close()
            else:
                self.show_error("Could not find valid theme in archive")
                
        except subprocess.CalledProcessError as e:
            self.show_error(f"Extraction failed: {e}")
        except Exception as e:
            self.show_error(f"Installation failed: {e}")

    def show_error(self, message):
        dialog = Adw.AlertDialog()
        dialog.set_heading("Error")
        dialog.set_body(message)
        dialog.add_response("ok", "OK")
        dialog.present(self.parent_window)


class RemoveThemeDialog(Adw.Dialog):
    def __init__(self, parent):
        super().__init__()
        self.parent_window = parent
        self.selected_theme = None
        self.target_dir = None
        
        self.set_title("Remove Theme")
        self.set_content_width(400)
        self.set_content_height(450)
        
        # Main box
        main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.set_child(main_box)
        
        # Header bar
        header = Adw.HeaderBar()
        header.set_show_end_title_buttons(False)
        header.set_show_start_title_buttons(False)
        
        cancel_btn = Gtk.Button(label="Cancel")
        cancel_btn.connect("clicked", lambda b: self.close())
        header.pack_start(cancel_btn)
        
        self.remove_btn = Gtk.Button(label="Remove")
        self.remove_btn.add_css_class("destructive-action")
        self.remove_btn.set_sensitive(False)
        self.remove_btn.connect("clicked", self.on_remove)
        header.pack_end(self.remove_btn)
        
        main_box.append(header)
        
        # Content
        clamp = Adw.Clamp()
        clamp.set_margin_top(12)
        clamp.set_margin_bottom(12)
        clamp.set_margin_start(12)
        clamp.set_margin_end(12)
        main_box.append(clamp)
        
        content = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)
        clamp.set_child(content)
        
        # Type selection
        type_group = Adw.PreferencesGroup()
        type_group.set_title("Select Theme Type")
        content.append(type_group)
        
        self.type_combo = Adw.ComboRow()
        self.type_combo.set_title("Theme Type")
        type_model = Gtk.StringList.new(["UI Theme", "Icon Theme", "Cursor Theme"])
        self.type_combo.set_model(type_model)
        self.type_combo.connect("notify::selected", self.on_type_selected)
        type_group.add(self.type_combo)
        
        # Theme list
        self.themes_group = Adw.PreferencesGroup()
        self.themes_group.set_title("User Themes")
        self.themes_group.set_description("Only user-installed themes can be removed")
        content.append(self.themes_group)
        
        scrolled = Gtk.ScrolledWindow()
        scrolled.set_vexpand(True)
        scrolled.set_min_content_height(200)
        content.append(scrolled)
        
        self.listbox = Gtk.ListBox()
        self.listbox.set_selection_mode(Gtk.SelectionMode.SINGLE)
        self.listbox.add_css_class("boxed-list")
        self.listbox.connect("row-selected", self.on_theme_selected)
        scrolled.set_child(self.listbox)
        
        # Initial population
        self.populate_themes()

    def on_type_selected(self, combo, param):
        self.populate_themes()

    def populate_themes(self):
        # Clear existing
        while True:
            row = self.listbox.get_row_at_index(0)
            if row:
                self.listbox.remove(row)
            else:
                break
        
        self.selected_theme = None
        self.remove_btn.set_sensitive(False)
        
        app = self.parent_window.app
        selected_type = self.type_combo.get_selected()
        
        themes = []
        if selected_type == 0:  # UI Theme
            self.target_dir = app.themes_dir
            if app.themes_dir.exists():
                themes = [d.name for d in app.themes_dir.iterdir() if d.is_dir()]
        elif selected_type == 1:  # Icon Theme
            self.target_dir = app.icons_dir
            if app.icons_dir.exists():
                themes = [d.name for d in app.icons_dir.iterdir() 
                         if d.is_dir() and not (d / "cursors").exists()]
        elif selected_type == 2:  # Cursor Theme
            self.target_dir = app.icons_dir
            if app.icons_dir.exists():
                themes = [d.name for d in app.icons_dir.iterdir() 
                         if d.is_dir() and (d / "cursors").exists()]
        
        themes.sort()
        
        if not themes:
            row = Adw.ActionRow()
            row.set_title("No user themes found")
            row.set_sensitive(False)
            self.listbox.append(row)
        else:
            for theme in themes:
                row = Adw.ActionRow()
                row.set_title(theme)
                row.theme_name = theme
                row.add_prefix(Gtk.Image.new_from_icon_name("user-trash-symbolic"))
                self.listbox.append(row)

    def on_theme_selected(self, listbox, row):
        if row and hasattr(row, 'theme_name'):
            self.selected_theme = row.theme_name
            self.remove_btn.set_sensitive(True)
        else:
            self.selected_theme = None
            self.remove_btn.set_sensitive(False)

    def on_remove(self, button):
        if not self.selected_theme or not self.target_dir:
            return
        
        # Confirmation dialog
        dialog = Adw.AlertDialog()
        dialog.set_heading("Remove Theme?")
        dialog.set_body(f"Are you sure you want to remove '{self.selected_theme}'? This cannot be undone.")
        dialog.add_response("cancel", "Cancel")
        dialog.add_response("remove", "Remove")
        dialog.set_response_appearance("remove", Adw.ResponseAppearance.DESTRUCTIVE)
        dialog.set_default_response("cancel")
        dialog.set_close_response("cancel")
        dialog.connect("response", self.on_confirm_remove)
        dialog.present(self.parent_window)

    def on_confirm_remove(self, dialog, response):
        if response == "remove":
            try:
                theme_path = self.target_dir / self.selected_theme
                shutil.rmtree(theme_path)
                self.parent_window.show_toast(f"Theme '{self.selected_theme}' removed")
                self.populate_themes()
            except Exception as e:
                error_dialog = Adw.AlertDialog()
                error_dialog.set_heading("Error")
                error_dialog.set_body(f"Failed to remove theme: {e}")
                error_dialog.add_response("ok", "OK")
                error_dialog.present(self.parent_window)


def main():
    app = LiteThemeManager()
    app.run(None)


if __name__ == "__main__":
    main()
