# FlightMonitor/gui/panels/function_notebook_panel.py
"""
Panel managing the area profiles, BBox input, and the function notebooks.
"""
import tkinter as tk
from tkinter import ttk, messagebox
from typing import Dict, Any, Optional

from ...utils.logger import get_logger
from ...data import config as app_config
from ...map.map_utils import _is_valid_bbox_dict
from ...data.area_profile_manager import DEFAULT_PROFILE_NAME

module_logger = get_logger(__name__)

class FunctionNotebookPanel:
    """
    Manages the combined Area Profiles, BBox, and Function Notebooks panel.
    """
    def __init__(self, parent_frame: ttk.Frame, controller: Any):
        self.parent_frame = parent_frame
        self.controller = controller

        # --- Tkinter Variables ---
        self.lat_min_var = tk.StringVar()
        self.lon_min_var = tk.StringVar()
        self.lat_max_var = tk.StringVar()
        self.lon_max_var = tk.StringVar()
        self.selected_profile_var = tk.StringVar()

        self._build_ui()
        self.update_profile_list()
        self.set_selected_profile(DEFAULT_PROFILE_NAME)

        module_logger.debug("FunctionNotebookPanel (unified) initialized.")

    def _build_ui(self):
        # --- Main Container for Area Management ---
        area_frame = ttk.LabelFrame(self.parent_frame, text="Area Profiles & BBox", padding=10)
        area_frame.pack(side=tk.TOP, fill=tk.X, padx=2, pady=(0, 5))

        # Configure grid for the area frame
        area_frame.columnconfigure(1, weight=1)

        # --- Row 0: Profile Selection and Buttons ---
        profile_controls_frame = ttk.Frame(area_frame)
        profile_controls_frame.grid(row=0, column=0, columnspan=4, sticky="ew", pady=(0, 10))
        profile_controls_frame.columnconfigure(0, weight=1) # Let combobox expand

        self.profile_combobox = ttk.Combobox(
            profile_controls_frame, textvariable=self.selected_profile_var, state="readonly"
        )
        self.profile_combobox.grid(row=0, column=0, sticky="ew", padx=(0, 5))
        self.profile_combobox.bind("<<ComboboxSelected>>", self._on_profile_selected)
        
        new_button = ttk.Button(profile_controls_frame, text="New", command=self._on_new_profile, width=5)
        new_button.grid(row=0, column=1, padx=(0, 2))
        
        save_button = ttk.Button(profile_controls_frame, text="Save", command=self._on_save_profile, width=5)
        save_button.grid(row=0, column=2, padx=(0, 2))
        
        delete_button = ttk.Button(profile_controls_frame, text="Delete", command=self._on_delete_profile, width=7)
        delete_button.grid(row=0, column=3)
        
        # --- Row 1 & 2: Bounding Box Entries ---
        ttk.Label(area_frame, text="Lat Min:").grid(row=1, column=0, padx=(0, 2), pady=2, sticky=tk.W)
        self.lat_min_entry = ttk.Entry(area_frame, textvariable=self.lat_min_var)
        self.lat_min_entry.grid(row=1, column=1, padx=(0, 5), pady=2, sticky=tk.EW)
        
        ttk.Label(area_frame, text="Lon Min:").grid(row=1, column=2, padx=(5, 2), pady=2, sticky=tk.W)
        self.lon_min_entry = ttk.Entry(area_frame, textvariable=self.lon_min_var)
        self.lon_min_entry.grid(row=1, column=3, padx=(0, 0), pady=2, sticky=tk.EW)

        ttk.Label(area_frame, text="Lat Max:").grid(row=2, column=0, padx=(0, 2), pady=2, sticky=tk.W)
        self.lat_max_entry = ttk.Entry(area_frame, textvariable=self.lat_max_var)
        self.lat_max_entry.grid(row=2, column=1, padx=(0, 5), pady=2, sticky=tk.EW)
        
        ttk.Label(area_frame, text="Lon Max:").grid(row=2, column=2, padx=(5, 2), pady=2, sticky=tk.W)
        self.lon_max_entry = ttk.Entry(area_frame, textvariable=self.lon_max_var)
        self.lon_max_entry.grid(row=2, column=3, padx=(0, 0), pady=2, sticky=tk.EW)
        
        # --- Function Notebook ---
        self.function_notebook = ttk.Notebook(self.parent_frame)
        self.function_notebook.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=2, pady=2)
        
        # --- Live Tab ---
        live_tab_frame = ttk.Frame(self.function_notebook, padding=10)
        self.function_notebook.add(live_tab_frame, text="Live Monitor")
        self.start_live_button = ttk.Button(live_tab_frame, text="Start Live Monitoring", command=self._on_start_live_monitoring)
        self.start_live_button.pack(side=tk.LEFT, padx=5, pady=5)
        self.stop_live_button = ttk.Button(live_tab_frame, text="Stop Live Monitoring", command=self._on_stop_live_monitoring, state=tk.DISABLED)
        self.stop_live_button.pack(side=tk.LEFT, padx=5, pady=5)
        
        # --- Historical Download Tab ---
        download_tab_frame = ttk.Frame(self.function_notebook, padding=10)
        self.function_notebook.add(download_tab_frame, text="Historical Download")
        ttk.Label(download_tab_frame, text="Historical download controls...").pack()
        
        # --- Playback Tab ---
        playback_tab_frame = ttk.Frame(self.function_notebook, padding=10)
        self.function_notebook.add(playback_tab_frame, text="Playback")
        ttk.Label(playback_tab_frame, text="Playback controls...").pack()

        self.function_notebook.bind("<<NotebookTabChanged>>", self._on_tab_change)

    # --- Event Handlers ---
    def _on_start_live_monitoring(self):
        if self.controller: self.controller.start_live_monitoring()
        
    def _on_stop_live_monitoring(self):
        if self.controller: self.controller.stop_live_monitoring()

    def _on_profile_selected(self, event=None):
        selected_name = self.selected_profile_var.get()
        if selected_name and self.controller:
            self.controller.load_area_profile(selected_name)

    def _on_new_profile(self):
        self.selected_profile_var.set("")
        self.update_bbox_gui_fields({})

    def _on_save_profile(self):
        if self.controller: self.controller.save_current_area_as_profile()

    def _on_delete_profile(self):
        profile_to_delete = self.selected_profile_var.get()
        if not profile_to_delete or profile_to_delete == DEFAULT_PROFILE_NAME:
            messagebox.showerror("Delete Error", "Cannot delete the default profile or no profile selected.", parent=self.parent_frame)
            return
        if messagebox.askyesno("Confirm Delete", f"Delete profile '{profile_to_delete}'?", parent=self.parent_frame):
            if self.controller: self.controller.delete_area_profile(profile_to_delete)

    def _on_tab_change(self, event=None):
        if not self.function_notebook: return
        tab_text = self.function_notebook.tab(self.function_notebook.index("current"), "text")
        if self.controller and hasattr(self.controller, "on_function_tab_changed"):
            self.controller.on_function_tab_changed(tab_text)

    # --- Public Methods ---
    def update_profile_list(self):
        if self.controller:
            profile_names = self.controller.get_profile_names()
            self.profile_combobox["values"] = profile_names
            self.set_selected_profile(self.selected_profile_var.get() or DEFAULT_PROFILE_NAME)

    def set_selected_profile(self, profile_name: str):
        if profile_name in self.profile_combobox["values"]:
            self.selected_profile_var.set(profile_name)
        elif self.profile_combobox["values"]:
            self.selected_profile_var.set(self.profile_combobox["values"][0])

    def get_bounding_box_input(self):
        # ... (metodo rimane invariato)
        try:
            bbox_candidate = {
                "lat_min": float(self.lat_min_var.get()), "lon_min": float(self.lon_min_var.get()),
                "lat_max": float(self.lat_max_var.get()), "lon_max": float(self.lon_max_var.get()),
            }
            return bbox_candidate if _is_valid_bbox_dict(bbox_candidate) else None
        except (ValueError, TypeError):
            return None

    def update_bbox_gui_fields(self, bbox_dict: Dict[str, float]):
        # ... (metodo rimane invariato)
        if bbox_dict and _is_valid_bbox_dict(bbox_dict):
            decimals = getattr(app_config, "COORDINATE_DECIMAL_PLACES", 5)
            self.lat_min_var.set(f"{bbox_dict['lat_min']:.{decimals}f}")
            self.lon_min_var.set(f"{bbox_dict['lon_min']:.{decimals}f}")
            self.lat_max_var.set(f"{bbox_dict['lat_max']:.{decimals}f}")
            self.lon_max_var.set(f"{bbox_dict['lon_max']:.{decimals}f}")
        else:
            self.lat_min_var.set("")
            self.lon_min_var.set("")
            self.lat_max_var.set("")
            self.lon_max_var.set("")
            
    def set_monitoring_button_states(self, is_monitoring_active: bool):
        # ... (metodo rimane invariato)
        if self.start_live_button and self.start_live_button.winfo_exists():
            self.start_live_button.config(state=tk.DISABLED if is_monitoring_active else tk.NORMAL)
        if self.stop_live_button and self.stop_live_button.winfo_exists():
            self.stop_live_button.config(state=tk.NORMAL if is_monitoring_active else tk.DISABLED)

    def set_controls_state(self, enabled: bool):
        state = tk.NORMAL if enabled else tk.DISABLED
        readonly_state = "readonly" if enabled else tk.DISABLED
        
        self.profile_combobox.config(state=readonly_state)
        for entry in [self.lat_min_entry, self.lon_min_entry, self.lat_max_entry, self.lon_max_entry]:
            if entry.winfo_exists(): entry.config(state=state)
        
        # Abilita/Disabilita i bottoni dei profili
        for child in self.profile_combobox.master.winfo_children():
             if isinstance(child, ttk.Button):
                child.config(state=state)