# target_simulator/gui/connection_settings_window.py
"""
Toplevel window for configuring Target and LRU connections.
"""
import tkinter as tk
from tkinter import ttk, messagebox


class ConnectionSettingsWindow(tk.Toplevel):
    """A dialog for configuring connection settings."""

    def __init__(self, master, config_manager, connection_config):
        super().__init__(master)
        self.master_view = master
        self.config_manager = config_manager
        self.connection_config = connection_config

        self.title("Connection Settings")
        self.transient(master)
        self.grab_set()
        self.resizable(False, False)

        self._create_widgets()
        self._load_settings()
        self.protocol("WM_DELETE_WINDOW", self._on_cancel)

        # Center the window on the main view
        self.update_idletasks()
        main_x = master.winfo_rootx()
        main_y = master.winfo_rooty()
        main_w = master.winfo_width()
        main_h = master.winfo_height()
        win_w = self.winfo_width()
        win_h = self.winfo_height()
        x = main_x + (main_w // 2) - (win_w // 2)
        y = main_y + (main_h // 2) - (win_h // 2)
        self.geometry(f"{win_w}x{win_h}+{x}+{y}")

    def _load_settings(self):
        # --- Load Target Settings ---
        target_cfg = self.connection_config.get("target", {})
        self.target_vars["conn_type"].set(
            "Serial" if target_cfg.get("type", "TFTP").lower() == "serial" else "TFTP"
        )
        self.target_vars["tftp_ip"].set(
            target_cfg.get("tftp", {}).get("ip", "127.0.0.1")
        )
        self.target_vars["tftp_port"].set(target_cfg.get("tftp", {}).get("port", 69))
        self.target_vars["serial_port"].set(
            target_cfg.get("serial", {}).get("port", "COM1")
        )
        self.target_vars["serial_baud"].set(
            target_cfg.get("serial", {}).get("baudrate", 9600)
        )
        self._switch_view(self.target_vars)

        # --- Load LRU Settings ---
        lru_cfg = self.connection_config.get("lru", {})
        self.lru_vars["conn_type"].set(
            "Serial" if lru_cfg.get("type", "TFTP").lower() == "serial" else "TFTP"
        )
        self.lru_vars["tftp_ip"].set(lru_cfg.get("tftp", {}).get("ip", "127.0.0.1"))
        self.lru_vars["tftp_port"].set(lru_cfg.get("tftp", {}).get("port", 69))
        self.lru_vars["serial_port"].set(lru_cfg.get("serial", {}).get("port", "COM1"))
        self.lru_vars["serial_baud"].set(
            lru_cfg.get("serial", {}).get("baudrate", 9600)
        )
        self._switch_view(self.lru_vars)

    def _create_widgets(self):
        main_frame = ttk.Frame(self, padding="10")
        main_frame.pack(fill=tk.BOTH, expand=True)

        # --- Target Connection Frame ---
        target_frame = ttk.LabelFrame(main_frame, text="Target Connection")
        target_frame.pack(fill=tk.X, expand=True, pady=5, padx=5)
        self.target_vars = self._create_connection_panel(target_frame, "Target")

        # --- LRU Connection Frame ---
        lru_frame = ttk.LabelFrame(main_frame, text="LRU Connection")
        lru_frame.pack(fill=tk.X, expand=True, pady=5, padx=5)
        self.lru_vars = self._create_connection_panel(lru_frame, "LRU")

        # --- Buttons ---
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(pady=10, fill=tk.X, side=tk.BOTTOM)

        ttk.Button(button_frame, text="Save", command=self._on_save).pack(
            side=tk.RIGHT, padx=5
        )
        ttk.Button(button_frame, text="Cancel", command=self._on_cancel).pack(
            side=tk.RIGHT, padx=5
        )

    def _create_connection_panel(self, parent_frame, name):
        vars = {}

        # --- Connection Type Selection ---
        conn_type_frame = ttk.Frame(parent_frame)
        conn_type_frame.pack(fill=tk.X, padx=5, pady=(5, 10))

        vars["conn_type"] = tk.StringVar()

        ttk.Label(conn_type_frame, text="Type:").pack(side=tk.LEFT)
        ttk.Radiobutton(
            conn_type_frame,
            text="TFTP",
            variable=vars["conn_type"],
            value="TFTP",
            command=lambda: self._switch_view(vars),
        ).pack(side=tk.LEFT, padx=5)
        ttk.Radiobutton(
            conn_type_frame,
            text="Serial",
            variable=vars["conn_type"],
            value="Serial",
            command=lambda: self._switch_view(vars),
        ).pack(side=tk.LEFT, padx=5)

        # --- Configuration Frames (TFTP and Serial) ---
        vars["tftp_frame"] = ttk.Frame(parent_frame, padding=5)
        vars["serial_frame"] = ttk.Frame(parent_frame, padding=5)

        # --- TFTP Widgets ---
        tftp_grid = vars["tftp_frame"]
        ttk.Label(tftp_grid, text="IP Address:").grid(
            row=0, column=0, sticky=tk.W, pady=2
        )
        vars["tftp_ip"] = tk.StringVar()
        ttk.Entry(tftp_grid, textvariable=vars["tftp_ip"]).grid(
            row=0, column=1, sticky=tk.EW, padx=5
        )

        ttk.Label(tftp_grid, text="Port:").grid(row=1, column=0, sticky=tk.W, pady=2)
        vars["tftp_port"] = tk.IntVar()
        ttk.Spinbox(
            tftp_grid, from_=1, to=65535, textvariable=vars["tftp_port"], width=7
        ).grid(row=1, column=1, sticky=tk.W, padx=5)
        tftp_grid.columnconfigure(1, weight=1)

        # --- Serial Widgets ---
        serial_grid = vars["serial_frame"]
        ttk.Label(serial_grid, text="COM Port:").grid(
            row=0, column=0, sticky=tk.W, pady=2
        )
        vars["serial_port"] = tk.StringVar()
        # In a real app, you might want to auto-detect available ports
        ttk.Combobox(
            serial_grid,
            textvariable=vars["serial_port"],
            values=[f"COM{i}" for i in range(1, 17)],
        ).grid(row=0, column=1, sticky=tk.EW, padx=5)

        ttk.Label(serial_grid, text="Baud Rate:").grid(
            row=1, column=0, sticky=tk.W, pady=2
        )
        vars["serial_baud"] = tk.IntVar()
        baud_rates = [9600, 19200, 38400, 57600, 115200]
        ttk.Combobox(
            serial_grid, textvariable=vars["serial_baud"], values=baud_rates, width=7
        ).grid(row=1, column=1, sticky=tk.W, padx=5)
        serial_grid.columnconfigure(1, weight=1)

        # --- Test Button ---
        test_button = ttk.Button(
            parent_frame,
            text="Test Connection",
            command=lambda: self._test_connection(name, vars),
        )
        test_button.pack(pady=5, padx=5, anchor=tk.E)

        # Initial view setup is now done in _load_settings
        # self._switch_view(vars)

        return vars

    def _switch_view(self, vars):
        conn_type = vars["conn_type"].get()
        if conn_type == "TFTP":
            vars["serial_frame"].pack_forget()
            vars["tftp_frame"].pack(fill=tk.X, expand=True, padx=5, pady=5)
        else:  # Serial
            vars["tftp_frame"].pack_forget()
            vars["serial_frame"].pack(fill=tk.X, expand=True, padx=5, pady=5)

    def _test_connection(self, name, vars):
        conn_type = vars["conn_type"].get()
        result = False
        error = None
        if conn_type == "TFTP":
            ip = vars["tftp_ip"].get()
            port = vars["tftp_port"].get()
            try:
                port = int(port)
                from core.tftp_communicator import TFTPCommunicator

                comm = TFTPCommunicator()
                result = comm.connect({"ip": ip, "port": port})
            except Exception as e:
                error = str(e)
        else:  # Serial
            serial_port = vars["serial_port"].get()
            baudrate = vars["serial_baud"].get()
            try:
                baudrate = int(baudrate)
                from core.serial_communicator import SerialCommunicator

                comm = SerialCommunicator()
                result = comm.connect({"port": serial_port, "baudrate": baudrate})
            except Exception as e:
                error = str(e)
        if result:
            messagebox.showinfo(
                "Connection Test", f"{name} connection successful!", parent=self
            )
        else:
            msg = f"{name} connection failed."
            if error:
                msg += f"\nError: {error}"
            messagebox.showerror("Connection Test", msg, parent=self)

    def _on_save(self):
        # Save Target and LRU connection configs in a consistent structure
        new_config = {
            "target": {
                "type": self.target_vars["conn_type"].get().lower(),
                "tftp": {
                    "ip": self.target_vars["tftp_ip"].get(),
                    "port": self.target_vars["tftp_port"].get(),
                },
                "serial": {
                    "port": self.target_vars["serial_port"].get(),
                    "baudrate": self.target_vars["serial_baud"].get(),
                },
            },
            "lru": {
                "type": self.lru_vars["conn_type"].get().lower(),
                "tftp": {
                    "ip": self.lru_vars["tftp_ip"].get(),
                    "port": self.lru_vars["tftp_port"].get(),
                },
                "serial": {
                    "port": self.lru_vars["serial_port"].get(),
                    "baudrate": self.lru_vars["serial_baud"].get(),
                },
            },
        }
        self.master_view.update_connection_settings(new_config)
        print("Settings saved and applied.")
        self.destroy()

    def _on_cancel(self):
        self.destroy()


if __name__ == "__main__":
    # Example usage for testing
    root = tk.Tk()
    root.withdraw()  # Hide the root window
    app = ConnectionSettingsWindow(root)
    root.wait_window(app)
    root.destroy()
