from typing import Any
from .widget_sources.welcome_wizard_ui import Ui_Wizard
from PySide6 import QtWidgets, QtCore, QtGui
from src import settings, LOG_DIR
from src.backend import Database
import sys
from appdirs import AppDirs
from pathlib import Path
import loguru

appdirs = AppDirs("SemesterApparatsManager", "SAM")

log = loguru.logger
log.remove()
log.add(sys.stdout, level="INFO")
log.add(f"{LOG_DIR}/application.log", rotation="1 MB", retention="10 days")


class WelcomeWizard(QtWidgets.QWizard, Ui_Wizard):
    def __init__(self, parent=None):
        super().__init__(parent)
        log.info("Initializing WelcomeWizard")
        self.setupUi(self)
        self.btn_database.clicked.connect(self.open_database_settings)
        self.btn_temp.clicked.connect(self.open_temp_settings)
        self.btn_test.clicked.connect(self.test_login_data)
        self.btn_create.clicked.connect(self.create_sam_user)
        # mail password field
        self.settings_mail_password.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
        self.settings_zotero_api_key.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
        self.settings_openai_api_key.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
        self.sam_password.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)

        # allow user to toggle password visibility
        self.settings_mail_password.setContextMenuPolicy(
            QtCore.Qt.ContextMenuPolicy.CustomContextMenu
        )
        self.settings_zotero_api_key.setContextMenuPolicy(
            QtCore.Qt.ContextMenuPolicy.CustomContextMenu
        )
        self.settings_openai_api_key.setContextMenuPolicy(
            QtCore.Qt.ContextMenuPolicy.CustomContextMenu
        )
        self.sam_password.setContextMenuPolicy(
            QtCore.Qt.ContextMenuPolicy.CustomContextMenu
        )
        self.settings_mail_password.customContextMenuRequested.connect(
            lambda pos: self.toggle_password_visibility(
                pos, self.settings_mail_password
            )
        )
        self.settings_zotero_api_key.customContextMenuRequested.connect(
            lambda pos: self.toggle_password_visibility(
                pos, self.settings_zotero_api_key
            )
        )
        self.settings_openai_api_key.customContextMenuRequested.connect(
            lambda pos: self.toggle_password_visibility(
                pos, self.settings_openai_api_key
            )
        )
        self.sam_password.customContextMenuRequested.connect(
            lambda pos: self.toggle_password_visibility(pos, self.sam_password)
        )
        # if button for next page is clicked, run function to store settings
        self.button(QtWidgets.QWizard.WizardButton.NextButton).clicked.connect(
            self.store_settings
        )
        self.settings_mail_use_user_name.toggled.connect(self.set_check_text)
        # set initial values for checkbox, database
        self.set_check_text(self.settings_mail_use_user_name.isChecked())
        self.settings_database.setText(
            str(settings.database.path)
            if settings.database.path is not None
            else str(appdirs.user_data_dir)
        )

        self.settings_temp.setText(
            str(settings.database.temp)
            if settings.database.temp is not None
            else str(appdirs.user_cache_dir)
        )
        self.settings_database_name.setText("semesterapparate.db")

    def test_login_data(self):
        from src.backend import AdminCommands

        log.info("Testing login data for SAM user")
        db_path = (
            self.settings_database.text() + "/" + self.settings_database_name.text()
        )
        db_path = Path(db_path).expanduser()
        db = Database(db_path=db_path)
        db.overwritePath(db_path)
        db.initializeDatabase()
        sam_users = AdminCommands(db_path=db_path).list_users()
        sam_users = [user[2] for user in sam_users]

        username = self.sam_username.text()
        if username in sam_users:
            QtWidgets.QMessageBox.information(
                self,
                "Information",
                f"User '{username}' exists in SAM.",
            )
        else:
            QtWidgets.QMessageBox.information(
                self,
                "Information",
                f"User '{username}' does not exist in SAM.",
            )

    def create_sam_user(self):
        """Create a SAM user in the database."""
        from src.backend import AdminCommands

        db_path = (
            self.settings_database.text() + "/" + self.settings_database_name.text()
        )
        db_path = Path(db_path).expanduser()
        db = Database(db_path=db_path)
        db.overwritePath(db_path)
        db.initializeDatabase()
        admin = AdminCommands(db_path=db_path)
        admin.create_admin()
        if not admin.create_user(self.sam_username.text(), self.sam_password.text()):
            QtWidgets.QMessageBox.critical(
                self,
                "Error",
                "Failed to create SAM user",
            )
        else:
            QtWidgets.QMessageBox.information(
                self,
                "Success",
                "SAM user created successfully",
            )

    def set_check_text(self, checked):
        """Set the text of the checkbox based on its state."""
        if checked:
            self.settings_mail_use_user_name.setText("Nutzername wird verwendet")
        else:
            self.settings_mail_use_user_name.setText("Nutzername wird nicht verwendet")

    def toggle_password_visibility(self, pos: Any, field):
        """Toggle the visibility of the password field."""
        if field.echoMode() == QtWidgets.QLineEdit.EchoMode.Password:
            field.setEchoMode(QtWidgets.QLineEdit.EchoMode.Normal)
        else:
            field.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)

    def store_settings(self):
        # database page
        db_path = self.settings_database.text()
        temp_path = self.settings_temp.text()
        db_name = self.settings_database_name.text()

        # mail page
        smtp_server = self.settings_mail_smtp_server.text()
        smtp_port = self.settings_mail_smtp_port.text()
        mail_sender = self.settings_mail_address.text()
        mail_user_name = self.settings_mail_user_name.text()
        mail_password = self.settings_mail_password.text()
        mail_printer_mail = self.settings_mail_printer.text()
        mail_signature = self.settings_mail_signature.toPlainText()
        use_user_name = self.settings_mail_use_user_name.isChecked()

        # zotero page
        zotero__api_key = self.settings_zotero_api_key.text()
        zotero_user_id = self.settings_zotero_library_id.text()
        zotero_library_type = self.settings_zotero_library_type.text()

        # openai page
        openai_api_key = self.settings_openai_api_key.text()
        openai_model = self.settings_openai_model.currentText()

        # store settings in config
        settings.set_database_attr("path", db_path)
        settings.set_database_attr("name", db_name)
        settings.set_database_attr("temp", temp_path)
        settings.set_mail_attr("smtp_server", smtp_server)
        settings.set_mail_attr("port", smtp_port)
        settings.set_mail_attr("sender", mail_sender)
        settings.set_mail_attr("user_name", mail_user_name)
        settings.set_mail_attr("password", mail_password)
        settings.set_mail_attr("printer_mail", mail_printer_mail)
        settings.set_mail_attr("signature", mail_signature)
        settings.set_mail_attr("use_user_name", use_user_name)
        settings.set_zotero_attr("api_key", zotero__api_key)
        settings.set_zotero_attr("library_id", zotero_user_id)
        settings.set_zotero_attr("library_type", zotero_library_type)
        settings.set_openai_attr("api_key", openai_api_key)
        settings.set_openai_attr("model", openai_model)
        # save settings to file
        print("Saving settings...")
        settings.save()

    def open_database_settings(self):
        #open filepicker dialog to select database file folder
        file_dialog = QtWidgets.QFileDialog(self, "Select Database File")
        file_dialog.setFileMode(QtWidgets.QFileDialog.FileMode.Directory)
        file_dialog.setViewMode(QtWidgets.QFileDialog.ViewMode.List)
        file_dialog.setWindowFlags(file_dialog.windowFlags() | QtCore.Qt.WindowType.WindowStaysOnTopHint)
        # set start dir to appdir.user_data_dir
        file_dialog.setDirectory(str(appdirs.user_data_dir))
        if file_dialog.exec():
            selected_files = file_dialog.selectedFiles()
            if selected_files:
                # Do something with the selected database file
                db_path = selected_files[0]
                self.settings_database.setText(db_path)

    def open_temp_settings(self):
        #open filepicker dialog to select temporary directory
        dir_dialog = QtWidgets.QFileDialog(self, "Select Temporary Directory")
        dir_dialog.setFileMode(QtWidgets.QFileDialog.FileMode.Directory)
        dir_dialog.setViewMode(QtWidgets.QFileDialog.ViewMode.List)

        if dir_dialog.exec():
            selected_dirs = dir_dialog.selectedFiles()
            if selected_dirs:
                # Do something with the selected temporary directory
                temp_path = selected_dirs[0]
                self.settings_temp.setText(temp_path)

def launch_wizard():
    """Launch the welcome wizard."""
    app = QtWidgets.QApplication.instance()
    if not app:
        app = QtWidgets.QApplication([])
    wizard = WelcomeWizard()
    # wizard.setWindowTitle("Welcome to the Semester Apparatus Manager")
    # wizard.setWindowIcon(settings.Icon("welcome").icon)
    wizard.setWizardStyle(QtWidgets.QWizard.WizardStyle.ModernStyle)
    wizard.setStartId(0)
    wizard.show()
    return wizard.exec()