"""
Main application window — sidebar + tabview layout.
"""

import customtkinter as ctk
from tkinter import messagebox

from core.server_store import ServerStore
from core.status_checker import StatusChecker
from core import i18n
from core.i18n import t, LANGUAGES
from gui.sidebar import Sidebar
from gui.server_dialog import ServerDialog
from gui.about_dialog import AboutDialog
from gui.tabs.terminal_tab import TerminalTab
from gui.tabs.files_tab import FilesTab
from gui.tabs.info_tab import InfoTab
from gui.tabs.keys_tab import KeysTab
from gui.tabs.setup_tab import SetupTab
from gui.tabs.totp_tab import TOTPTab


class App(ctk.CTk):
    def __init__(self):
        super().__init__()

        # Window config
        self.title("ServerManager")
        self.geometry("1100x700")
        self.minsize(900, 500)

        ctk.set_appearance_mode("dark")
        ctk.set_default_color_theme("blue")

        # Core
        self.store = ServerStore()
        self.checker = StatusChecker(self.store, interval=60)

        # Layout
        self._build_layout()

        # Status checker
        self.checker.set_gui_callback(lambda: self.after(0, self._on_status_update))
        self.checker.start()
        self.checker.check_all_now()

        # Cleanup on close
        self.protocol("WM_DELETE_WINDOW", self._on_close)

    def _build_layout(self):
        # Sidebar
        self.sidebar = Sidebar(self, self.store, on_select=self._on_server_select)
        self.sidebar.pack(side="left", fill="y")
        self.sidebar.add_callback = self._add_server
        self.sidebar.edit_callback = self._edit_server
        self.sidebar.delete_callback = self._delete_server

        # Main area
        main = ctk.CTkFrame(self, fg_color="transparent")
        main.pack(side="right", fill="both", expand=True)

        # Header bar (language + about)
        header_bar = ctk.CTkFrame(main, fg_color="transparent", height=40)
        header_bar.pack(fill="x", padx=10, pady=(8, 0))
        header_bar.pack_propagate(False)

        # Language selector
        lang_values = list(LANGUAGES.values())
        current_display = LANGUAGES.get(i18n.get_language(), "English")
        self._lang_var = ctk.StringVar(value=current_display)
        self.lang_menu = ctk.CTkOptionMenu(
            header_bar, values=lang_values, variable=self._lang_var,
            width=110, height=30, command=self._change_language
        )
        self.lang_menu.pack(side="right", padx=(5, 0))

        # About button
        self.about_btn = ctk.CTkButton(
            header_bar, text="ⓘ", width=30, height=30,
            corner_radius=15, fg_color="#6b7280", hover_color="#4b5563",
            command=self._show_about
        )
        self.about_btn.pack(side="right", padx=(5, 5))

        # Tabview
        self.tabview = ctk.CTkTabview(main)
        self.tabview.pack(fill="both", expand=True, padx=10, pady=10)

        # Tab names stored for language updates
        self._tab_keys = ["terminal", "files", "info", "keys", "totp", "setup"]
        for key in self._tab_keys:
            self.tabview.add(t(key))

        self.terminal_tab = TerminalTab(self.tabview.tab(t("terminal")), self.store)
        self.terminal_tab.pack(fill="both", expand=True)

        self.files_tab = FilesTab(self.tabview.tab(t("files")), self.store)
        self.files_tab.pack(fill="both", expand=True)

        self.info_tab = InfoTab(self.tabview.tab(t("info")), self.store, edit_callback=self._edit_server)
        self.info_tab.pack(fill="both", expand=True)

        self.keys_tab = KeysTab(self.tabview.tab(t("keys")), self.store)
        self.keys_tab.pack(fill="both", expand=True)

        self.totp_tab = TOTPTab(self.tabview.tab(t("totp")), self.store)
        self.totp_tab.pack(fill="both", expand=True)

        self.setup_tab = SetupTab(self.tabview.tab(t("setup")), self.store)
        self.setup_tab.pack(fill="both", expand=True)

    def _on_server_select(self, alias: str):
        self.terminal_tab.set_server(alias)
        self.files_tab.set_server(alias)
        self.info_tab.set_server(alias)
        self.keys_tab.set_server(alias)
        self.totp_tab.set_server(alias)

    def _add_server(self):
        dialog = ServerDialog(self, self.store)
        self.wait_window(dialog)

    def _edit_server(self, alias: str):
        server = self.store.get_server(alias)
        if server:
            dialog = ServerDialog(self, self.store, server=server)
            self.wait_window(dialog)
            self.info_tab.refresh()

    def _delete_server(self, alias: str):
        if messagebox.askyesno(t("delete_server"), t("delete_confirm").format(alias=alias)):
            self.store.remove_server(alias)
            self._on_server_select(None)

    def _on_status_update(self):
        self.sidebar.update_statuses()
        self.info_tab.refresh()

    def _show_about(self):
        AboutDialog(self)

    def _get_current_tab_key(self) -> str:
        """Get the i18n key of the currently active tab."""
        try:
            current_name = self.tabview.get()
            # Match against current language translations
            for key in self._tab_keys:
                if t(key) == current_name:
                    return key
        except Exception:
            pass
        return self._tab_keys[0]

    def _change_language(self, display_name: str):
        # Remember current tab KEY before language switch
        active_tab_key = self._get_current_tab_key()

        # Find lang code from display name
        lang_code = "en"
        for code, name in LANGUAGES.items():
            if name == display_name:
                lang_code = code
                break
        i18n.set_language(lang_code)
        self.store._save_settings()
        self._apply_language(active_tab_key)

    def _apply_language(self, restore_tab_key: str | None = None):
        # Remember selected server
        alias = self.sidebar.get_selected()
        # Use provided key or default to first tab
        current_key = restore_tab_key or self._tab_keys[0]

        # Detach tab contents
        self.terminal_tab.pack_forget()
        self.files_tab.pack_forget()
        self.info_tab.pack_forget()
        self.keys_tab.pack_forget()
        self.totp_tab.pack_forget()
        self.setup_tab.pack_forget()

        # Get the main frame and destroy old tabview
        main = self.tabview.master
        self.tabview.destroy()

        # Create new tabview with translated names
        self.tabview = ctk.CTkTabview(main)
        self.tabview.pack(fill="both", expand=True, padx=10, pady=10)

        for key in self._tab_keys:
            self.tabview.add(t(key))

        # Re-parent tab contents
        self.terminal_tab = TerminalTab(self.tabview.tab(t("terminal")), self.store)
        self.terminal_tab.pack(fill="both", expand=True)

        self.files_tab = FilesTab(self.tabview.tab(t("files")), self.store)
        self.files_tab.pack(fill="both", expand=True)

        self.info_tab = InfoTab(self.tabview.tab(t("info")), self.store, edit_callback=self._edit_server)
        self.info_tab.pack(fill="both", expand=True)

        self.keys_tab = KeysTab(self.tabview.tab(t("keys")), self.store)
        self.keys_tab.pack(fill="both", expand=True)

        self.totp_tab = TOTPTab(self.tabview.tab(t("totp")), self.store)
        self.totp_tab.pack(fill="both", expand=True)

        self.setup_tab = SetupTab(self.tabview.tab(t("setup")), self.store)
        self.setup_tab.pack(fill="both", expand=True)

        # Restore active tab by key
        try:
            self.tabview.set(t(current_key))
        except Exception:
            pass

        # Restore server selection
        if alias:
            self._on_server_select(alias)

        # Update sidebar
        self.sidebar.update_language()

    def _on_close(self):
        self.checker.stop()
        self.destroy()
