#!/usr/bin/env python3

# This file is part of TileOS project

# SPDX-FileCopyrightText: 2025 Aleksey Samoilov <samoilov.lex@gmail.com>
# SPDX-License-Identifier: GPL-3.0-or-later

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

import os
import signal
import sys
import subprocess
from shutil import copy2
from pathlib import Path
from PyQt6.QtWidgets import (QApplication, QMainWindow, QDialog, QDialogButtonBox)
from PyQt6.QtGui import QPixmap, QIcon
from PyQt6.QtCore import Qt, QDir
from tileos_welcome.ui_mainwindow import Ui_MainWindow
from tileos_welcome.ui_warning import Ui_WarningMessage
from tileos_welcome.ui_shell_select import Ui_shellSelect

def get_config_home():
    config_home = os.getenv('XDG_CONFIG_HOME') if os.getenv('XDG_CONFIG_HOME') else os.path.join(
        os.getenv("HOME"), ".config/")
    return config_home

dir_name = os.path.dirname(__file__)
config_home = get_config_home()
user = os.getlogin()
desktop_file = os.path.join(dir_name, "data/tileos-welcome.desktop")
autostart_dir = os.path.join(config_home, "autostart/")
icons_path = os.path.join(os.path.dirname(__file__), "data", "icons")
autostart_desktop_file = os.path.join(config_home, autostart_dir, "tileos-welcome.desktop")

# Icons for buttons
QDir.addSearchPath("icons", icons_path)

# Get current desktop
desktop = os.getenv("XDG_CURRENT_DESKTOP")

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # Background
        page_label = os.path.join(dir_name, "data/label.png")
        page_pixmap = QPixmap(page_label).scaled(600, 300, Qt.AspectRatioMode.KeepAspectRatio)
        self.ui.logo.setPixmap(page_pixmap)
        self.ui.logo2.setPixmap(page_pixmap)

        # Autostart (copying tileos-welcome.desktop to ~/.config/autostart)
        if os.path.isfile(autostart_desktop_file):
            self.ui.checkAutostart.setChecked(True)
        self.ui.checkAutostart.toggled.connect(self.on_check_autostart)

        # Detect running compositor and adapt Wiki button text to it
        if desktop == "sway":
            self.ui.btnWiki.setText("Sway Wiki")
            self.ui.btnWiki.setIcon(QIcon("icons:sway.png"))
        elif desktop == "river":
            self.ui.btnWiki.setText("River Wiki")
            self.ui.btnWiki.setIcon(QIcon("icons:river.png"))
        elif desktop == "qtile":
            self.ui.btnWiki.setText("Qtile Wiki")
            self.ui.btnWiki.setIcon(QIcon("icons:qtile.png"))
        elif desktop == "mir:miracle-wm":
            self.ui.btnWiki.setText("MiracleWM Wiki")
            self.ui.btnWiki.setIcon(QIcon("icons:miraclewm.png"))
        elif desktop == "niri":
            self.ui.btnWiki.setText("Niri Wiki")

        # Page 1
        self.ui.btnInstall.clicked.connect(self.on_clicked_install)
        self.ui.btnInstall.setIcon(QIcon("icons:install-system.svg"))
        self.ui.btnGprd.clicked.connect(self.on_clicked_partition)
        self.ui.btnGprd.setIcon(QIcon("icons:gparted.svg"))
        self.ui.btnWebsite.clicked.connect(self.on_clicked_website)
        self.ui.btnWebsite.setIcon(QIcon("icons:web.svg"))
        self.ui.btnDoc.clicked.connect(self.on_clicked_doc)
        self.ui.btnDoc.setIcon(QIcon("icons:doc.svg"))
        self.ui.btnIssue.clicked.connect(self.on_clicked_tracker)
        self.ui.btnIssue.setIcon(QIcon("icons:issue.svg"))
        self.ui.btnContrib.clicked.connect(self.on_clicked_contribute)
        self.ui.btnContrib.setIcon(QIcon("icons:contrib.svg"))
        self.ui.btnTelegram.clicked.connect(self.on_clicked_telegram)
        self.ui.btnTelegram.setIcon(QIcon("icons:telegram.svg"))
        self.ui.btnNext.clicked.connect(self.on_page_switch)
        self.ui.btnNext.setIcon(QIcon.fromTheme("go-next"))
        self.ui.btnQuit.clicked.connect(self.exitApp)
        self.ui.btnQuit.setIcon(QIcon("icons:exit.svg"))

        # Page 2
        self.ui.btnGTK.clicked.connect(self.on_clicked_gtk_theme)
        self.ui.btnGTK.setIcon(QIcon("icons:gtk-theme.svg"))
        self.ui.btnKvantum.clicked.connect(self.on_clicked_qt_theme)
        self.ui.btnKvantum.setIcon(QIcon("icons:theme.svg"))
        self.ui.btnDisplay.clicked.connect(self.on_clicked_display_settings)
        self.ui.btnDisplay.setIcon(QIcon("icons:display.svg"))
        self.ui.btnShell.clicked.connect(self.on_clicked_shell_select)
        self.ui.btnShell.setIcon(QIcon("icons:shell.svg"))

        # Sway Input Configurator available only for Sway
        if desktop == "sway":
            self.ui.btnInput.clicked.connect(self.on_clicked_input_settings)
            self.ui.btnInput.setIcon(QIcon("icons:input.svg"))
        else:
            self.ui.btnInput.setHidden(True)

        self.ui.btnSoftware.clicked.connect(self.on_clicked_software)
        self.ui.btnSoftware.setIcon(QIcon("icons:software.svg"))
        self.ui.btnPrev.clicked.connect(self.on_page_switch)
        self.ui.btnPrev.setIcon(QIcon.fromTheme("go-previous"))
        self.ui.btnKernelManager.clicked.connect(self.on_clicked_kernel_manager)
        self.ui.btnKernelManager.setIcon(QIcon("icons:kernel.svg"))
        self.ui.btnExit.clicked.connect(self.exitApp)
        self.ui.btnExit.setIcon(QIcon("icons:exit.svg"))

    def on_check_autostart(self):
        if self.ui.checkAutostart.isChecked():
            if os.path.exists(autostart_dir):
                if os.path.isfile(autostart_desktop_file) is False:
                    copy2(os.path.join(desktop_file),
                        os.path.join(config_home, "autostart/"))
            else:
                os.mkdir(autostart_dir)
                if os.path.isfile(autostart_desktop_file) is False:
                    copy2(os.path.join(dir_name, "resources/tileos-welcome.desktop"),
                          os.path.join(config_home, "autostart/"))
        else:
            os.unlink(autostart_desktop_file)

    def on_clicked_install(self):
        self.msg = WarningMessage()
        self.msg.setWindowTitle("Warning!")
        self.msg.setModal(True)
        if Path(f'{"/usr/bin/calamares"}').is_file() and user == "tileos":
            subprocess.Popen("/usr/bin/install-tileos")
            self.close()
        else:
            self.msg.show()

    def on_clicked_partition(self):
        subprocess.Popen("xhost +si:localuser:root && pkexec /usr/sbin/gparted && xhost -si:localuser:root &", shell=True)

    def on_clicked_website(self):
        subprocess.Popen(["xdg-open", "https://tile-os.com"])

    def on_clicked_tracker(self):
        subprocess.Popen(["xdg-open", "https://gitlab.com/tile-os/tileos/-/issues"])

    def on_clicked_contribute(self):
        subprocess.Popen(["xdg-open", "https://gitlab.com/tile-os"])

    def on_clicked_doc(self):
        subprocess.Popen(["xdg-open", "https://git.tile-os.com/TileOS/tileos/wiki/?action=_pages"])

    def on_clicked_telegram(self):
        subprocess.Popen(["xdg-open", "https://t.me/tile_os"])

    def on_clicked_gtk_theme(self):
        try:
            subprocess.Popen("/usr/bin/nwg-look")
        except FileNotFoundError:
            print("Programm nwg-look is not installed!")

    def on_clicked_qt_theme(self):
        try:
            subprocess.Popen("/usr/bin/kvantummanager")
        except FileNotFoundError:
            print("Programm kvantummanager is not installed!")

    def on_clicked_display_settings(self):
        try:
            if desktop == "sway":
                subprocess.Popen(["/usr/bin/nwg-displays"])
            else:
                subprocess.Popen(["/usr/bin/wdisplays"])
        except FileNotFoundError as e:
            print(f"Programm not installed: {e.filename}")

    def on_clicked_shell_select(self):
        self.shell_selector = ShellSelector()
        self.shell_selector.setWindowTitle("Shell Selector")
        self.shell_selector.setModal(True)
        self.shell_selector.show()

    def on_clicked_input_settings(self):
        try:
            subprocess.Popen("/usr/bin/sway-input-config")
        except FileNotFoundError:
            print("Programm sway-input-config is not installed!")

    def on_clicked_kernel_manager(self):
        try:
            subprocess.Popen("/usr/bin/tileos-kernel-manager")
        except FileNotFoundError:
            print("Programm tileos-kernel-manager is not installed!")

    def on_clicked_software(self):
        try:
            subprocess.Popen(["/usr/bin/gnome-software", "--mode=overview"])
        except FileNotFoundError:
            print("Programm gnome-software is not installed!")
    
    def on_page_switch(self):
        if self.ui.stackedWidget.currentIndex() == 0:
            self.ui.stackedWidget.setCurrentIndex(1)
        else:
            self.ui.stackedWidget.setCurrentIndex(0)

    def exitApp(self):
        self.close()


class WarningMessage(QDialog):
    def __init__(self):
        super().__init__()
        self.warningDialog = Ui_WarningMessage()
        self.warningDialog.setupUi(self)


class ShellSelector(QDialog):
    def __init__(self):
        super().__init__()
        self.shell_selector = Ui_shellSelect()
        self.shell_selector.setupUi(self)

        defaultShell = os.environ['SHELL']
        if defaultShell == "/bin/bash":
            self.shell_selector.btnBash.setChecked(True)
        elif defaultShell == "/bin/zsh":
            self.shell_selector.btnZSH.setChecked(True)
        elif defaultShell == "/bin/fish":
            self.shell_selector.btnFish.setChecked(True)

        self.btnApply = self.shell_selector.buttonBox.button(QDialogButtonBox.StandardButton.Apply)
        self.btnApply.clicked.connect(self.apply)

    def apply(self):
        if self.shell_selector.btnBash.isChecked():
            self.shell = "/usr/bin/bash"
            subprocess.run(["pkexec", "chsh", "-s", self.shell, user])
        elif self.shell_selector.btnFish.isChecked():
            self.shell = "/usr/bin/fish"
            subprocess.run(["pkexec", "chsh", "-s", self.shell, user])
        elif self.shell_selector.btnZSH.isChecked():
            self.shell = "/usr/bin/zsh"
            subprocess.run(["pkexec", "chsh", "-s", self.shell, user])

def main():
    app = QApplication(["Welcome to TileOS!"])
    app.setDesktopFileName("tileos-welcome")
    win = MainWindow()
    win.show()
    sys.exit(app.exec())

if __name__ == "__main__":
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    main()
