import tkinter as tk
from tkinter import ttk
from multiprocessing import set_start_method
from .gui_elements import spacrButton, create_menu_bar, set_dark_style
from .gui_core import initiate_root
from screeninfo import get_monitors

class MainApp(tk.Tk):
    def __init__(self, default_app=None):
        super().__init__()

        # Initialize the window
        self.geometry("100x100")
        self.update_idletasks()

        # Get the current window position
        self.update_idletasks()
        x = self.winfo_x()
        y = self.winfo_y()

        # Find the monitor where the window is located
        for monitor in get_monitors():
            if monitor.x <= x < monitor.x + monitor.width and monitor.y <= y < monitor.y + monitor.height:
                width = monitor.width
                height = monitor.height
                break
        else:
            monitor = get_monitors()[0]
            width = monitor.width
            height = monitor.height

        # Set the window size to the dimensions of the monitor where it is located
        self.geometry(f"{width}x{height}")
        self.title("SpaCr GUI Collection")
        self.configure(bg='#333333')

        style = ttk.Style()
        self.color_settings = set_dark_style(style, parent_frame=self)
        self.main_buttons = {}
        self.additional_buttons = {}

        self.main_gui_apps = {
            "Mask": (lambda frame: initiate_root(self, 'mask'), "Generate cellpose masks for cells, nuclei and pathogen images."),
            "Measure": (lambda frame: initiate_root(self, 'measure'), "Measure single object intensity and morphological feature. Crop and save single object image"),
            "Annotate": (lambda frame: initiate_root(self, 'annotate'), "Annotation single object images on a grid. Annotations are saved to database."),
            "Make Masks": (lambda frame: initiate_root(self, 'make_masks'), "Adjust pre-existing Cellpose models to your specific dataset for improved performance"),
            "Classify": (lambda frame: initiate_root(self, 'classify'), "Train Torch Convolutional Neural Networks (CNNs) or Transformers to classify single object images."),
        }

        self.additional_gui_apps = {
            "Umap": (lambda frame: initiate_root(self, 'umap'), "Generate UMAP embeddings with datapoints represented as images."),
            "Train Cellpose": (lambda frame: initiate_root(self, 'train_cellpose'), "Train custom Cellpose models."),
            "ML Analyze": (lambda frame: initiate_root(self, 'ml_analyze'), "Machine learning analysis of data."),
            "Cellpose Masks": (lambda frame: initiate_root(self, 'cellpose_masks'), "Generate Cellpose masks."),
            "Cellpose All": (lambda frame: initiate_root(self, 'cellpose_all'), "Run Cellpose on all images."),
            "Map Barcodes": (lambda frame: initiate_root(self, 'map_barcodes'), "Map barcodes to data."),
            "Regression": (lambda frame: initiate_root(self, 'regression'), "Perform regression analysis."),
            "Recruitment": (lambda frame: initiate_root(self, 'recruitment'), "Analyze recruitment data."),
            "Activation": (lambda frame: initiate_root(self, 'activation'), "Generate activation maps of computer vision models and measure channel-activation correlation."),
            "Plaque": (lambda frame: initiate_root(self, 'analyze_plaques'), "Analyze plaque data.")
        }

        self.selected_app = tk.StringVar()
        self.create_widgets()

        if default_app in self.main_gui_apps:
            self.load_app(default_app, self.main_gui_apps[default_app][0])
        elif default_app in self.additional_gui_apps:
            self.load_app(default_app, self.additional_gui_apps[default_app][0])

    def create_widgets(self):
        create_menu_bar(self)

        # Use a grid layout for centering
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

        self.content_frame = tk.Frame(self)
        self.content_frame.grid(row=0, column=0, sticky="nsew")
        
        # Center the content frame within the window
        self.content_frame.grid_rowconfigure(0, weight=1)
        self.content_frame.grid_columnconfigure(0, weight=1)

        self.inner_frame = tk.Frame(self.content_frame)
        self.inner_frame.grid(row=0, column=0)
        
        set_dark_style(ttk.Style(), containers=[self.content_frame, self.inner_frame])

        self.create_startup_screen()

    def create_startup_screen(self):
        self.clear_frame(self.inner_frame)

        main_buttons_frame = tk.Frame(self.inner_frame)
        main_buttons_frame.pack(pady=10)
        set_dark_style(ttk.Style(), containers=[main_buttons_frame])

        additional_buttons_frame = tk.Frame(self.inner_frame)
        additional_buttons_frame.pack(pady=10)
        set_dark_style(ttk.Style(), containers=[additional_buttons_frame])

        description_frame = tk.Frame(self.inner_frame, height=70)
        description_frame.pack(fill=tk.X, pady=10)
        description_frame.pack_propagate(False)
        set_dark_style(ttk.Style(), containers=[description_frame])

        self.description_label = tk.Label(description_frame, text="", wraplength=800, justify="center", font=('Helvetica', 12), fg=self.color_settings['fg_color'], bg=self.color_settings['bg_color'])
        self.description_label.pack(fill=tk.BOTH, pady=10)

        logo_button = spacrButton(main_buttons_frame, text="SpaCr", command=lambda: self.load_app("logo_spacr", initiate_root), icon_name="logo_spacr", size=100, show_text=False)
        logo_button.grid(row=0, column=0, padx=5, pady=5)
        self.main_buttons[logo_button] = "SpaCr provides a flexible toolset to extract single-cell images and measurements from high-content cell painting experiments, train deep-learning models to classify cellular/subcellular phenotypes, simulate, and analyze pooled CRISPR-Cas9 imaging screens."

        for i, (app_name, app_data) in enumerate(self.main_gui_apps.items()):
            app_func, app_desc = app_data
            button = spacrButton(main_buttons_frame, text=app_name, command=lambda app_name=app_name, app_func=app_func: self.load_app(app_name, app_func), icon_name=app_name.lower(), size=100, show_text=False)
            button.grid(row=0, column=i + 1, padx=5, pady=5)
            self.main_buttons[button] = app_desc

        for i, (app_name, app_data) in enumerate(self.additional_gui_apps.items()):
            app_func, app_desc = app_data
            button = spacrButton(additional_buttons_frame, text=app_name, command=lambda app_name=app_name, app_func=app_func: self.load_app(app_name, app_func), icon_name=app_name.lower(), size=75, show_text=False)
            button.grid(row=0, column=i, padx=5, pady=5)
            self.additional_buttons[button] = app_desc

        self.update_description()

    def update_description(self):
        for button, desc in {**self.main_buttons, **self.additional_buttons}.items():
            if button.canvas.itemcget(button.button_bg, "fill") == self.color_settings['active_color']:
                self.show_description(desc)
                return
        self.clear_description()

    def show_description(self, description):
        if self.description_label.winfo_exists():
            self.description_label.config(text=description)
            self.description_label.update_idletasks()

    def clear_description(self):
        if self.description_label.winfo_exists():
            self.description_label.config(text="")
            self.description_label.update_idletasks()

    def load_app(self, app_name, app_func):
        self.clear_frame(self.inner_frame)

        app_frame = tk.Frame(self.inner_frame)
        app_frame.pack(fill=tk.BOTH, expand=True)
        set_dark_style(ttk.Style(), containers=[app_frame])
        app_func(app_frame)

    def clear_frame(self, frame):
        for widget in frame.winfo_children():
            widget.destroy()

def gui_app():
    app = MainApp()
    app.mainloop()

if __name__ == "__main__":
    set_start_method('spawn', force=True)
    gui_app()
