# FlightMonitor/gui/panels/historical_download_panel.py
"""
Panel for controlling the historical data download feature.
"""
import tkinter as tk
from tkinter import ttk, font as tkFont
from typing import Dict, Any, Optional
from datetime import datetime, timedelta, timezone  

from flightmonitor.utils.logger import get_logger

module_logger = get_logger(__name__)

# Constants for default values
DEFAULT_SCAN_RATE_SEC = 15
DEFAULT_SAMPLING_INTERVAL_SEC = 30

# Button colors (matching the live monitoring panel)
COLOR_START_BG = "#28a745"
COLOR_START_ACTIVE = "#218838"
COLOR_STOP_BG = "#dc3545"
COLOR_STOP_ACTIVE = "#c82333"
COLOR_DISABLED_BG = "#e0e0e0"
COLOR_DISABLED_FG = "#a0a0a0"
COLOR_TEXT = "white"


class HistoricalDownloadPanel:
    """
    Manages the UI for the Historical Download function tab.
    """
    def __init__(self, parent_frame: ttk.Frame, controller: Any):
        """
        Initializes the HistoricalDownloadPanel.

        Args:
            parent_frame: The parent ttk.Frame (the tab in the notebook).
            controller: The application controller instance.
        """
        self.parent_frame = parent_frame
        self.controller = controller
        
        # --- StringVars for UI elements ---
        self.start_date_var = tk.StringVar()
        self.start_time_var = tk.StringVar()
        self.end_date_var = tk.StringVar()
        self.end_time_var = tk.StringVar()
        self.scan_rate_var = tk.StringVar(value=str(DEFAULT_SCAN_RATE_SEC))
        self.sampling_interval_var = tk.StringVar(value=str(DEFAULT_SAMPLING_INTERVAL_SEC))
        self.virtual_clock_var = tk.StringVar(value="--/--/---- --:--:--")

        self._build_ui()
        self.set_default_datetime()
        module_logger.debug("HistoricalDownloadPanel initialized.")

    def _build_ui(self):
        """Builds all the widgets for the panel."""
        self.parent_frame.columnconfigure(0, weight=1) # Allow centering

        # --- Main container frame ---
        container = ttk.Frame(self.parent_frame, padding="10 10 10 10")
        container.grid(row=0, column=0, sticky="ew")
        container.columnconfigure(1, weight=1)
        container.columnconfigure(3, weight=1)
        
        # --- Input Fields ---
        input_frame = ttk.LabelFrame(container, text="Download Parameters", padding=10)
        input_frame.pack(fill=tk.X, expand=True, pady=(0, 10))
        input_frame.columnconfigure(1, weight=1)
        input_frame.columnconfigure(3, weight=1)

        # Start Date/Time
        # MODIFICA: Aggiunto "(UTC)" all'etichetta
        ttk.Label(input_frame, text="Start Date (UTC):").grid(row=0, column=0, sticky="w", pady=2)
        self.start_date_entry = ttk.Entry(input_frame, textvariable=self.start_date_var, width=12)
        self.start_date_entry.grid(row=0, column=1, sticky="ew", padx=(5, 10))
        
        # MODIFICA: Aggiunto "(UTC)" all'etichetta
        ttk.Label(input_frame, text="Start Time (UTC):").grid(row=0, column=2, sticky="w", pady=2)
        self.start_time_entry = ttk.Entry(input_frame, textvariable=self.start_time_var, width=10)
        self.start_time_entry.grid(row=0, column=3, sticky="ew", padx=(5, 0))

        # End Date/Time
        # MODIFICA: Aggiunto "(UTC)" all'etichetta
        ttk.Label(input_frame, text="End Date (UTC):").grid(row=1, column=0, sticky="w", pady=2)
        self.end_date_entry = ttk.Entry(input_frame, textvariable=self.end_date_var, width=12)
        self.end_date_entry.grid(row=1, column=1, sticky="ew", padx=(5, 10))

        # MODIFICA: Aggiunto "(UTC)" all'etichetta
        ttk.Label(input_frame, text="End Time (UTC):").grid(row=1, column=2, sticky="w", pady=2)
        self.end_time_entry = ttk.Entry(input_frame, textvariable=self.end_time_var, width=10)
        self.end_time_entry.grid(row=1, column=3, sticky="ew", padx=(5, 0))
        
        # Scan Rate and Sampling Interval
        ttk.Label(input_frame, text="API Scan Rate (sec):").grid(row=2, column=0, sticky="w", pady=5)
        self.scan_rate_entry = ttk.Entry(input_frame, textvariable=self.scan_rate_var, width=12)
        self.scan_rate_entry.grid(row=2, column=1, sticky="ew", padx=(5, 10))
        
        ttk.Label(input_frame, text="Sampling Interval (sec):").grid(row=2, column=2, sticky="w", pady=5)
        self.sampling_interval_entry = ttk.Entry(input_frame, textvariable=self.sampling_interval_var, width=10)
        self.sampling_interval_entry.grid(row=2, column=3, sticky="ew", padx=(5, 0))

        # --- Virtual Clock Display ---
        # MODIFICA: Aggiunto "(UTC)" al titolo del frame
        clock_frame = ttk.LabelFrame(container, text="Virtual Clock (UTC)", padding=10)
        clock_frame.pack(fill=tk.X, expand=True, pady=(5, 15))
        clock_font = tkFont.Font(family="Courier New", size=14, weight="bold")
        self.virtual_clock_label = ttk.Label(
            clock_frame,
            textvariable=self.virtual_clock_var,
            font=clock_font,
            anchor="center",
            foreground="#333"
        )
        self.virtual_clock_label.pack(fill=tk.X, expand=True)

        # --- Action Buttons ---
        button_font = tkFont.Font(family="Helvetica", size=10, weight="bold")
        button_container = ttk.Frame(container)
        button_container.pack(fill=tk.X)
        
        # Spacers for centering
        button_container.columnconfigure(0, weight=1)
        button_container.columnconfigure(3, weight=1)

        self.start_button = tk.Button(
            button_container, text="Start Download", command=self._on_start,
            font=button_font, bg=COLOR_START_BG, fg=COLOR_TEXT,
            activebackground=COLOR_START_ACTIVE, activeforeground=COLOR_TEXT,
            relief=tk.RAISED, borderwidth=2, padx=10, pady=5
        )
        self.start_button.grid(row=0, column=1, padx=10)
        
        self.stop_button = tk.Button(
            button_container, text="Stop Download", command=self._on_stop,
            font=button_font, bg=COLOR_DISABLED_BG, fg=COLOR_DISABLED_FG,
            activebackground=COLOR_DISABLED_BG, activeforeground=COLOR_DISABLED_FG,
            state=tk.DISABLED, relief=tk.RAISED, borderwidth=2, padx=10, pady=5
        )
        self.stop_button.grid(row=0, column=2, padx=10)

    def _on_start(self):
        """Callback for the 'Start Download' button."""
        if self.controller and hasattr(self.controller, "start_historical_download"):
            self.controller.start_historical_download()

    def _on_stop(self):
        """Callback for the 'Stop Download' button."""
        if self.controller and hasattr(self.controller, "stop_historical_download"):
            self.controller.stop_historical_download()
            
    def get_download_parameters(self) -> Optional[Dict[str, Any]]:
        """
        Retrieves and validates download parameters from the UI.
        
        Returns:
            A dictionary with validated parameters, or None if validation fails.
        """
        try:
            start_str = f"{self.start_date_var.get()} {self.start_time_var.get()}"
            end_str = f"{self.end_date_var.get()} {self.end_time_var.get()}"
            
            start_dt = datetime.strptime(start_str, "%Y-%m-%d %H:%M:%S")
            end_dt = datetime.strptime(end_str, "%Y-%m-%d %H:%M:%S")

            scan_rate = int(self.scan_rate_var.get())
            sampling_interval = int(self.sampling_interval_var.get())

            if start_dt >= end_dt:
                module_logger.error("Start time must be before end time.")
                return None
            if scan_rate <= 0 or sampling_interval <= 0:
                module_logger.error("Scan rate and sampling interval must be positive.")
                return None

            return {
                "start_time": start_dt.timestamp(),
                "end_time": end_dt.timestamp(),
                "scan_rate_sec": scan_rate,
                "sampling_interval_sec": sampling_interval,
            }
        except (ValueError, TypeError) as e:
            module_logger.error(f"Invalid input for download parameters: {e}")
            return None

    def set_controls_state(self, is_downloading: bool):
        """Enables or disables UI controls based on download state."""
        if is_downloading:
            # Downloading is active
            self.start_button.config(state=tk.DISABLED, bg=COLOR_DISABLED_BG, fg=COLOR_DISABLED_FG)
            self.stop_button.config(state=tk.NORMAL, bg=COLOR_STOP_BG, fg=COLOR_TEXT)
            for widget in [self.start_date_entry, self.start_time_entry, self.end_date_entry,
                           self.end_time_entry, self.scan_rate_entry, self.sampling_interval_entry]:
                widget.config(state=tk.DISABLED)
        else:
            # Downloading is stopped
            self.start_button.config(state=tk.NORMAL, bg=COLOR_START_BG, fg=COLOR_TEXT)
            self.stop_button.config(state=tk.DISABLED, bg=COLOR_DISABLED_BG, fg=COLOR_DISABLED_FG)
            for widget in [self.start_date_entry, self.start_time_entry, self.end_date_entry,
                           self.end_time_entry, self.scan_rate_entry, self.sampling_interval_entry]:
                widget.config(state=tk.NORMAL)
    
    def set_default_datetime(self):
        """
        Sets default date and time values to a recent window within the last hour
        (e.g., from 30 mins ago to 10 mins ago) to respect OpenSky API limits.
        """
        # Get the current time in UTC
        #now_utc = datetime.now(timezone.utc)
        now_utc = datetime.now()
        
        # --- MODIFICA CHIAVE ---
        # Imposta un intervallo di tempo che sia GARANTITO essere nell'ultima ora.
        # Ad esempio, un intervallo di 20 minuti che finisce 10 minuti fa.
        start_datetime = now_utc - timedelta(minutes=59)
        end_datetime = now_utc - timedelta(minutes=1)
        # --- FINE MODIFICA ---
        
        # Set the string variables for the UI
        self.start_date_var.set(start_datetime.strftime("%Y-%m-%d"))
        self.start_time_var.set(start_datetime.strftime("%H:%M:%S"))
        self.end_date_var.set(end_datetime.strftime("%Y-%m-%d"))
        self.end_time_var.set(end_datetime.strftime("%H:%M:%S"))
        
    def update_virtual_clock(self, timestamp: float):
        """Updates the virtual clock display."""
        try:
            dt_object = datetime.fromtimestamp(timestamp)
            self.virtual_clock_var.set(dt_object.strftime("%Y-%m-%d %H:%M:%S"))
        except (ValueError, TypeError):
            self.virtual_clock_var.set("Invalid Timestamp")