import traceback
from customtkinter import CTk
import threading
from tkinter import messagebox

from shared.utils import Logger
from shared.contracts import ValidatorLoginViewSignature, ValidatorWindowSignature
from validator.src.services.authentification_service import Authentification

# =============== Login View Controller ===============
class LoginViewController:
    def __init__(self, view_master: ValidatorWindowSignature, login_view: ValidatorLoginViewSignature):
        # Logger
        self.logger = Logger.create_logger(logger_name = "Login View Controller", log_file_name = "validator_app")
        
        # Views
        self.viewMaster = view_master
        self.loginView = login_view
        
        # Helper Classes Instances
        self.authInstance = Authentification()
        
        # Set widget commands
        self.loginView.authLoginButton.configure(
            command = lambda: self.handle_login()
        )
        # ========== Extra Functionality ==========
        self.loginView.authEmailEntry.bind("<Return>", self.handle_login)
        self.loginView.authPasswordEntry.bind("<Return>", self.handle_login)
        # =========================================
        
    # ========== Login ==========
    def handle_login(self, event = None) -> None:
        """Runs the login thread."""
        try:
            email = self.loginView.authEmailEntry.get()
            password = self.loginView.authPasswordEntry.get()

            # Optional: disable button while logging in
            self.loginView.authLoginButton.configure(state="disabled")

            # Start background thread
            threading.Thread(
                target=self._login_thread,
                args=(email, password),
                daemon=True
            ).start()

        except:
            traceBack = traceback.format_exc()
            self.logger.error(
                f"[{self.__class__.__name__} - {self.handle_login.__name__}] "
                f"Failed to start login thread.\n{traceBack}")
    
    def _login_thread(self, email: str, password: str) -> None:
        """The thread of the login."""
        try:
            loginResult = self.authInstance.login(email=email, password=password)
            
            if loginResult == True:
                self.loginView.after(0, self._on_login_success)
            else:
                self.loginView.after(0, lambda: self._on_login_fail(loginResult))
                    
        except:
            traceBack = traceback.format_exc()
            self.logger.error(
                f"[{self.__class__.__name__} - {self._login_thread.__name__}] "
                f"Failed to login the user. \n{traceBack}")
    
    def _on_login_success(self):
        """If the login is successful."""
        try:
            self.loginView.authLoginButton.configure(state="normal")
            self.loginView.destroy()
            self.viewMaster.delete_login_view()
            self.viewMaster.create_validator_view()
        except:
            traceBack = traceback.format_exc()
            self.logger.error(
                f"[{self.__class__.__name__} - {self._on_login_success.__name__}] "
                f"Failed to login the user. \n{traceBack}")
    
    def _on_login_fail(self, result: str):
        """If the login fails.
        
        Args:
            result (str): The result of the login (error that occurred).
        """
        try:
            self.loginView.authLoginButton.configure(state="normal")
            if result == "WrongCredentials":
                self.loginView.authWarningLabel.configure(
                    text_color = self.loginView.template["AuthFrame"]["Actives"]["WarningLabelColorWrong"]
                )
            elif result == "ConnectionError":
                self.handle_warning(
                    message = "Verificati conexiunea la internet."
                )
            else:
                self.handle_error(
                    message = "Eroare interna a validatorului."
                )
        except:
            traceBack = traceback.format_exc()
            self.logger.error(
                f"[{self.__class__.__name__} - {self._on_login_fail.__name__}] "
                f"Failed to login the user. \n{traceBack}")
    # ===========================
    
    # ========== Messageboxes ==========
    def handle_info(self, message: str):
        """Pop-up for info."""
        try:
            messagebox.showinfo(title = "Info", message = message)
        except:
            traceBack = traceback.format_exc()
            self.logger.error(
                f"[{self.__class__.__name__} - {self.handle_error.__name__}] "
                f"Failed to show info message. \n{traceBack}")
            
    def handle_warning(self, message: str):
        """Pop-up for warning."""
        try:
            messagebox.showwarning(title = "Warning", message = message)
        except:
            traceBack = traceback.format_exc()
            self.logger.error(
                f"[{self.__class__.__name__} - {self.handle_error.__name__}] "
                f"Failed to show warning. \n{traceBack}")
    
    def handle_error(self, message: str):
        """Pop-up for error."""
        try:
            messagebox.showerror(title = "Error", message = message)
        except:
            traceBack = traceback.format_exc()
            self.logger.error(
                f"[{self.__class__.__name__} - {self.handle_error.__name__}] "
                f"Failed to show error. \n{traceBack}")
    
    def handle_critical_error(self, message: str):
        """Pop-up for critical error."""
        try:
            messagebox.showerror(title = "Error", message = message)
        except:
            traceBack = traceback.format_exc()
            self.logger.error(
                f"[{self.__class__.__name__} - {self.handle_error.__name__}] "
                f"Failed to handle encountered critical error. \n{traceBack}")
    # ==================================
# =====================================================