"""
Server add/edit dialog — modal window with all server fields.
"""

import customtkinter as ctk
from core.server_store import SERVER_TYPES, DEFAULT_PORTS


class ServerDialog(ctk.CTkToplevel):
    def __init__(self, master, store, server: dict | None = None):
        super().__init__(master)
        self.store = store
        self.editing = server
        self.result = None

        self.title("Edit Server" if server else "Add Server")
        self.geometry("450x520")
        self.resizable(False, False)
        self.grab_set()

        # Center on parent
        self.transient(master)

        self._build_ui(server)

    def _build_ui(self, server: dict | None):
        pad = {"padx": 20, "pady": (5, 0)}
        entry_pad = {"padx": 20, "pady": (2, 5)}

        # Alias
        ctk.CTkLabel(self, text="Alias", anchor="w").pack(fill="x", **pad)
        self.alias_entry = ctk.CTkEntry(self, placeholder_text="my-server")
        self.alias_entry.pack(fill="x", **entry_pad)

        # IP
        ctk.CTkLabel(self, text="IP / Hostname", anchor="w").pack(fill="x", **pad)
        self.ip_entry = ctk.CTkEntry(self, placeholder_text="1.2.3.4")
        self.ip_entry.pack(fill="x", **entry_pad)

        # Type + Port row
        row = ctk.CTkFrame(self, fg_color="transparent")
        row.pack(fill="x", padx=20, pady=(5, 5))

        type_frame = ctk.CTkFrame(row, fg_color="transparent")
        type_frame.pack(side="left", fill="x", expand=True, padx=(0, 5))
        ctk.CTkLabel(type_frame, text="Type", anchor="w").pack(fill="x")
        self.type_var = ctk.StringVar(value="ssh")
        self.type_menu = ctk.CTkOptionMenu(
            type_frame, values=SERVER_TYPES, variable=self.type_var,
            command=self._on_type_change
        )
        self.type_menu.pack(fill="x")

        port_frame = ctk.CTkFrame(row, fg_color="transparent")
        port_frame.pack(side="left", fill="x", expand=True, padx=(5, 0))
        ctk.CTkLabel(port_frame, text="Port", anchor="w").pack(fill="x")
        self.port_entry = ctk.CTkEntry(port_frame, placeholder_text="22")
        self.port_entry.pack(fill="x")

        # User
        ctk.CTkLabel(self, text="Username", anchor="w").pack(fill="x", **pad)
        self.user_entry = ctk.CTkEntry(self, placeholder_text="root")
        self.user_entry.pack(fill="x", **entry_pad)

        # Password
        ctk.CTkLabel(self, text="Password", anchor="w").pack(fill="x", **pad)
        pass_frame = ctk.CTkFrame(self, fg_color="transparent")
        pass_frame.pack(fill="x", padx=20, pady=(2, 5))
        self.password_entry = ctk.CTkEntry(pass_frame, show="*", placeholder_text="password")
        self.password_entry.pack(side="left", fill="x", expand=True, padx=(0, 5))
        self.show_pass = ctk.CTkButton(pass_frame, text="Show", width=60, command=self._toggle_password)
        self.show_pass.pack(side="right")
        self._pass_visible = False

        # Notes
        ctk.CTkLabel(self, text="Notes", anchor="w").pack(fill="x", **pad)
        self.notes_entry = ctk.CTkEntry(self, placeholder_text="optional description")
        self.notes_entry.pack(fill="x", **entry_pad)

        # Buttons
        btn_frame = ctk.CTkFrame(self, fg_color="transparent")
        btn_frame.pack(fill="x", padx=20, pady=(15, 20))
        ctk.CTkButton(btn_frame, text="Cancel", fg_color="#6b7280", command=self.destroy).pack(side="left", expand=True, padx=(0, 5))
        ctk.CTkButton(btn_frame, text="Save", command=self._save).pack(side="right", expand=True, padx=(5, 0))

        # Fill values if editing
        if server:
            self.alias_entry.insert(0, server.get("alias", ""))
            self.alias_entry.configure(state="disabled")
            self.ip_entry.insert(0, server.get("ip", ""))
            self.type_var.set(server.get("type", "ssh"))
            self.port_entry.insert(0, str(server.get("port", 22)))
            self.user_entry.insert(0, server.get("user", ""))
            self.password_entry.insert(0, server.get("password", ""))
            self.notes_entry.insert(0, server.get("notes", ""))

    def _on_type_change(self, value):
        default_port = DEFAULT_PORTS.get(value, 22)
        self.port_entry.delete(0, "end")
        self.port_entry.insert(0, str(default_port))

    def _toggle_password(self):
        self._pass_visible = not self._pass_visible
        self.password_entry.configure(show="" if self._pass_visible else "*")
        self.show_pass.configure(text="Hide" if self._pass_visible else "Show")

    def _save(self):
        alias = self.alias_entry.get().strip()
        ip = self.ip_entry.get().strip()
        port_str = self.port_entry.get().strip()
        user = self.user_entry.get().strip()
        password = self.password_entry.get()
        server_type = self.type_var.get()
        notes = self.notes_entry.get().strip()

        # Validation
        if not alias:
            self._show_error("Alias is required")
            return
        if not ip:
            self._show_error("IP is required")
            return
        try:
            port = int(port_str) if port_str else DEFAULT_PORTS.get(server_type, 22)
        except ValueError:
            self._show_error("Port must be a number")
            return

        server_data = {
            "alias": alias,
            "ip": ip,
            "port": port,
            "user": user or "root",
            "password": password,
            "type": server_type,
            "notes": notes,
        }

        try:
            if self.editing:
                self.store.update_server(alias, server_data)
            else:
                self.store.add_server(server_data)
            self.result = server_data
            self.destroy()
        except ValueError as e:
            self._show_error(str(e))

    def _show_error(self, message: str):
        # Simple error via title flash
        self.title(f"Error: {message}")
        self.after(2000, lambda: self.title("Edit Server" if self.editing else "Add Server"))
