#!/usr/bin/python3
import os
import shlex
import subprocess
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib

class InstallKompasGUI:
    def __init__(self):
        self.window = Gtk.Window(title="Установка КОМПАС-3D v24")
        self.window.set_icon_name("install")
        self.window.set_border_width(10)
        self.window.set_default_size(600, 500)
        self.window.connect("destroy", Gtk.main_quit)

        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
        self.window.add(vbox)

        # Адрес репозитория
        repo_label = Gtk.Label(label="Адрес репозитория:", halign=Gtk.Align.START)
        vbox.pack_start(repo_label, False, False, 0)

        self.repo_entry = Gtk.Entry()
        self.repo_entry.set_text("https://repo.ascon.ru/stable/rpm/redos/8.0/")
        vbox.pack_start(self.repo_entry, False, False, 0)

        # Что устанавливать
        install_label = Gtk.Label(label="Что устанавливать:", halign=Gtk.Align.START)
        vbox.pack_start(install_label, False, False, 10)

        self.install_combo = Gtk.ComboBoxText()
        self.install_combo.append("all", "КОМПАС-3D и Просмотрщик")
        self.install_combo.append("kompas", "Только КОМПАС-3D")
        self.install_combo.append("viewer", "Только Просмотрщик")
        self.install_combo.set_active(0)
        vbox.pack_start(self.install_combo, False, False, 0)

        # Кнопки
        btn_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)

        self.install_btn = Gtk.Button(label="Установить")
        self.install_btn.connect("clicked", self.on_install_clicked)
        btn_box.pack_start(self.install_btn, False, False, 0)

        self.update_btn = Gtk.Button(label="Обновить")
        self.update_btn.connect("clicked", self.on_update_clicked)
        btn_box.pack_start(self.update_btn, False, False, 0)

        self.remove_btn = Gtk.Button(label="Удалить")
        self.remove_btn.connect("clicked", self.on_remove_clicked)
        btn_box.pack_start(self.remove_btn, False, False, 0)

        vbox.pack_start(btn_box, False, False, 20)

        # Прогресс
        self.progress = Gtk.ProgressBar(show_text=True)
        self.progress.set_text("Готово к установке")
        vbox.pack_start(self.progress, False, False, 0)

        # Лог
        log_label = Gtk.Label(label="Лог:", halign=Gtk.Align.START)
        vbox.pack_start(log_label, False, False, 10)

        self.log_view = Gtk.TextView()
        self.log_view.set_editable(False)
        self.log_view.set_monospace(True)
        css_provider = Gtk.CssProvider()
        css_provider.load_from_data(b"textview { font-family: monospace; font-size: 10pt; }")
        self.log_view.get_style_context().add_provider(css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
        self.log_buffer = self.log_view.get_buffer()

        self.scrolled = Gtk.ScrolledWindow()
        self.scrolled.set_vexpand(True)
        self.scrolled.add(self.log_view)
        vbox.pack_start(self.scrolled, True, True, 0)

        self.window.show_all()
        # Убрать автоматическое выделение текста в поле адреса
        GLib.idle_add(self.repo_entry.set_position, -1)

        self.detect_installed()

    def detect_installed(self):
        self.kompas_installed = subprocess.run(
            ["rpm", "-q", "ascon-kompas3d-v24"],
            stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
        ).returncode == 0
        self.viewer_installed = subprocess.run(
            ["rpm", "-q", "ascon-kompas3d-viewer-v24"],
            stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
        ).returncode == 0
        installed = self.kompas_installed or self.viewer_installed
        self.update_btn.set_visible(installed)
        self.remove_btn.set_visible(installed)

        # Обновляем список вариантов установки с учётом уже установленного
        self.install_combo.remove_all()
        if not self.kompas_installed and not self.viewer_installed:
            self.install_combo.append("all", "КОМПАС-3D и Просмотрщик")
            self.install_combo.append("kompas", "Только КОМПАС-3D")
            self.install_combo.append("viewer", "Только Просмотрщик")
            self.install_combo.set_active(0)
        elif self.kompas_installed and not self.viewer_installed:
            self.install_combo.append("viewer", "Просмотрщик")
            self.install_combo.set_active(0)
        elif not self.kompas_installed and self.viewer_installed:
            self.install_combo.append("kompas", "КОМПАС-3D")
            self.install_combo.set_active(0)
        # Если оба установлены — список пуст, устанавливать нечего
        has_install_options = self.install_combo.get_model().iter_n_children(None) > 0
        self.install_btn.set_visible(has_install_options)

    def set_buttons_sensitive(self, sensitive):
        self.install_btn.set_sensitive(sensitive)
        self.update_btn.set_sensitive(sensitive)
        self.remove_btn.set_sensitive(sensitive)

    def log(self, text):
        end_iter = self.log_buffer.get_end_iter()
        self.log_buffer.insert(end_iter, text + "\n")
        adj = self.scrolled.get_vadjustment()
        adj.set_value(adj.get_upper())

    def on_install_clicked(self, button):
        repo_url = self.repo_entry.get_text()
        install_type = self.install_combo.get_active_id()

        self.set_buttons_sensitive(False)
        self.progress.set_fraction(0)
        self.progress.set_text("Установка...")
        self.log_buffer.set_text("")
        self.log(f"Адрес репозитория: {repo_url}")
        self.log(f"Устанавливается: {install_type}")
        self.log("")

        cmd = f"KOMPAS_REPO_URL={shlex.quote(repo_url)} KOMPAS_INSTALL={shlex.quote(install_type)} install-kompas-v24"

        def run():
            try:
                proc = subprocess.Popen(
                    ["pkexec", "sh", "-c", cmd],
                    stdout=subprocess.PIPE,
                    stderr=subprocess.STDOUT,
                    text=True
                )
                for line in proc.stdout:
                    GLib.idle_add(self.log, line.rstrip())
                proc.wait()
                GLib.idle_add(self.action_finished, "Установка", proc.returncode)
            except Exception as e:
                GLib.idle_add(self.action_finished, "Установка", 1, str(e))

        import threading
        threading.Thread(target=run, daemon=True).start()

    def on_update_clicked(self, button):
        repo_url = self.repo_entry.get_text()

        self.set_buttons_sensitive(False)
        self.progress.set_fraction(0)
        self.progress.set_text("Обновление...")
        self.log_buffer.set_text("")
        self.log(f"Адрес репозитория: {repo_url}")
        self.log("Обновление установленных пакетов...")
        self.log("")

        cmd = f"KOMPAS_REPO_URL={shlex.quote(repo_url)} update-kompas-v24"

        def run():
            try:
                proc = subprocess.Popen(
                    ["pkexec", "sh", "-c", cmd],
                    stdout=subprocess.PIPE,
                    stderr=subprocess.STDOUT,
                    text=True
                )
                for line in proc.stdout:
                    GLib.idle_add(self.log, line.rstrip())
                proc.wait()
                GLib.idle_add(self.action_finished, "Обновление", proc.returncode)
            except Exception as e:
                GLib.idle_add(self.action_finished, "Обновление", 1, str(e))

        import threading
        threading.Thread(target=run, daemon=True).start()

    def on_remove_clicked(self, button):
        self.set_buttons_sensitive(False)
        self.progress.set_fraction(0)
        self.progress.set_text("Удаление...")
        self.log_buffer.set_text("")
        self.log("Удаление пакетов...")
        self.log("")

        def run():
            try:
                proc = subprocess.Popen(
                    ["pkexec", "dnf", "remove", "-y", "ascon*kompas*v24*"],
                    stdout=subprocess.PIPE,
                    stderr=subprocess.STDOUT,
                    text=True
                )
                for line in proc.stdout:
                    GLib.idle_add(self.log, line.rstrip())
                proc.wait()
                GLib.idle_add(self.action_finished, "Удаление", proc.returncode)
            except Exception as e:
                GLib.idle_add(self.action_finished, "Удаление", 1, str(e))

        import threading
        threading.Thread(target=run, daemon=True).start()

    def action_finished(self, action, returncode, error=None):
        self.set_buttons_sensitive(True)
        self.progress.set_fraction(1.0)
        if returncode == 0:
            self.progress.set_text(f"{action} завершено успешно")
            self.log(f"\n{action} завершено успешно.")
        else:
            self.progress.set_text(f"Ошибка: {action}")
            if error:
                self.log(f"\nОшибка: {error}")
            dialog = Gtk.MessageDialog(
                transient_for=self.window,
                flags=0,
                message_type=Gtk.MessageType.ERROR,
                buttons=Gtk.ButtonsType.OK,
                text=f"Ошибка: {action}"
            )
            dialog.format_secondary_text(error if error else "Смотрите лог для подробностей")
            dialog.run()
            dialog.destroy()
        self.detect_installed()

if __name__ == "__main__":
    app = InstallKompasGUI()
    Gtk.main()
