# FlightMonitor/gui/panels/data_logging_panel.py
"""
Defines the GUI panel for controlling raw data logging functionality.
This panel is designed to be shared across different monitoring modes.
"""
import tkinter as tk
from tkinter import ttk, filedialog, font as tkFont
from typing import Optional, Any
from datetime import datetime, timezone, timedelta
import time

from flightmonitor.utils.logger import get_logger

module_logger = get_logger(__name__)


class DataLoggingPanel:
    """
    Manages the GUI elements for enabling and configuring raw data logging.
    """

    def __init__(self, parent_frame: ttk.Frame, controller: Any):
        """
        Initializes the DataLoggingPanel.

        Args:
            parent_frame: The parent ttk.Frame where this panel will be placed.
            controller: The application controller instance.
        """
        self.parent_frame = parent_frame
        self.controller = controller

        # --- Internal State ---
        self.session_start_time: Optional[float] = None
        self.session_query_count: int = 0
        self.session_query_rate_sec: Optional[int] = None
        self._session_update_after_id: Optional[str] = None

        # --- Tkinter Variables ---
        self.enable_logging_var = tk.BooleanVar(value=False)
        self.log_directory_var = tk.StringVar(value="")
        self.last_query_result_var = tk.StringVar(value="Last query result: N/A")
        self.session_info_var = tk.StringVar(value="Session not active.")

        # --- Widget References ---
        self.log_dir_entry: Optional[ttk.Entry] = None
        self.browse_button: Optional[ttk.Button] = None
        self.open_folder_button: Optional[ttk.Button] = None
        self.summary_table: Optional[ttk.Treeview] = None

        self._build_ui()
        module_logger.debug("DataLoggingPanel initialized.")

    def _build_ui(self):
        """Builds all the widgets for the panel."""
        container = ttk.LabelFrame(
            self.parent_frame, text="Data Logging Session", padding=10
        )
        container.pack(fill=tk.X, expand=True, padx=2, pady=5)

        self.enable_checkbox = ttk.Checkbutton(
            container,
            text="Enable Raw Data Logging",
            variable=self.enable_logging_var,
            command=self._on_toggle_logging,
        )
        self.enable_checkbox.pack(anchor=tk.W, pady=(0, 5))

        dir_frame = ttk.Frame(container)
        dir_frame.pack(fill=tk.X, expand=True)
        dir_frame.columnconfigure(1, weight=1)

        ttk.Label(dir_frame, text="Save to:").grid(
            row=0, column=0, sticky=tk.W, padx=(0, 5)
        )
        self.log_dir_entry = ttk.Entry(
            dir_frame, textvariable=self.log_directory_var, state=tk.DISABLED
        )
        self.log_dir_entry.grid(row=0, column=1, sticky=tk.EW)

        self.browse_button = ttk.Button(
            dir_frame,
            text="Browse...",
            command=self._on_browse_directory,
            state=tk.DISABLED,
        )
        self.browse_button.grid(row=0, column=2, sticky=tk.E, padx=(5, 2))

        self.open_folder_button = ttk.Button(
            dir_frame,
            text="Open Folder",
            command=self._on_open_folder,
            state=tk.DISABLED,
        )
        self.open_folder_button.grid(row=0, column=3, sticky=tk.E, padx=(2, 0))

        info_font = tkFont.Font(family="Helvetica", size=9, slant="italic")
        last_result_label = ttk.Label(
            container,
            textvariable=self.last_query_result_var,
            font=info_font,
            foreground="navy",
        )
        last_result_label.pack(anchor=tk.W, pady=(8, 0))

        session_info_label = ttk.Label(
            container,
            textvariable=self.session_info_var,
            font=info_font,
            foreground="darkgreen",
        )
        session_info_label.pack(anchor=tk.W, pady=(0, 2))

        table_frame = ttk.Frame(container)
        table_frame.pack(fill=tk.BOTH, expand=True, pady=(2, 0))

        self.summary_table = ttk.Treeview(
            table_frame, columns=("timestamp", "count"), show="headings", height=4
        )
        self.summary_table.heading("timestamp", text="Fetch Timestamp (UTC)")
        self.summary_table.heading("count", text="Aircraft Count")
        self.summary_table.column("timestamp", width=160, anchor=tk.W)
        self.summary_table.column("count", width=100, anchor=tk.CENTER)

        scrollbar = ttk.Scrollbar(
            table_frame, orient="vertical", command=self.summary_table.yview
        )
        self.summary_table.configure(yscrollcommand=scrollbar.set)

        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.summary_table.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

    def _on_toggle_logging(self):
        is_enabled = self.enable_logging_var.get()
        new_state = tk.NORMAL if is_enabled else tk.DISABLED
        if self.log_dir_entry:
            self.log_dir_entry.config(state=new_state)
        if self.browse_button:
            self.browse_button.config(state=new_state)
        if self.open_folder_button:
            self.open_folder_button.config(state=new_state)

    def _on_browse_directory(self):
        directory = filedialog.askdirectory(
            title="Select Directory to Save Raw Data", parent=self.parent_frame
        )
        if directory:
            self.log_directory_var.set(directory)

    def _on_open_folder(self):
        directory_path = self.get_log_directory()
        if self.controller and hasattr(self.controller, "open_log_directory"):
            self.controller.open_log_directory(directory_path)

    def session_started(self, start_timestamp: float, query_rate_sec: Optional[int]):
        """To be called by the controller when a monitoring/download session starts."""
        self.session_start_time = start_timestamp
        self.session_query_count = 0
        self.session_query_rate_sec = query_rate_sec
        
        if self._session_update_after_id:
            self.parent_frame.after_cancel(self._session_update_after_id)
        
        self._update_session_duration()
        module_logger.info(f"DataLoggingPanel session timer started at {start_timestamp}.")

    def session_stopped(self):
        """To be called by the controller when a session stops."""
        if self._session_update_after_id:
            self.parent_frame.after_cancel(self._session_update_after_id)
            self._session_update_after_id = None
        
        self.session_start_time = None
        self.session_query_count = 0
        self.session_query_rate_sec = None
        self.session_info_var.set("Session not active.")
        module_logger.info("DataLoggingPanel session timer stopped.")

    def _update_session_duration(self):
        """Periodically updates the session duration label."""
        if self.session_start_time is None:
            return

        elapsed_seconds = time.time() - self.session_start_time
        duration_str = str(timedelta(seconds=int(elapsed_seconds)))
        start_time_str = datetime.fromtimestamp(self.session_start_time, timezone.utc).strftime('%H:%M:%S')
        
        rate_str = ""
        if self.session_query_rate_sec is not None and self.session_query_rate_sec > 0:
            rate_str = f" (1 per {self.session_query_rate_sec:.0f}s)"
        
        session_text = (
            f"Session started: {start_time_str} (UTC) | "
            f"Duration: {duration_str} | "
            f"Queries: {self.session_query_count}{rate_str}"
        )
        self.session_info_var.set(session_text)

        self._session_update_after_id = self.parent_frame.after(1000, self._update_session_duration)
    
    def increment_query_count(self):
        """Increments the session query counter."""
        self.session_query_count += 1
        # The label will be updated by the next scheduled _update_session_duration call

    def is_logging_enabled(self) -> bool:
        return self.enable_logging_var.get()

    def get_log_directory(self) -> str:
        return self.log_directory_var.get()

    def add_summary_entry(self, timestamp: float, count: int):
        if not self.summary_table or not self.summary_table.winfo_exists():
            return
        try:
            dt_object = datetime.fromtimestamp(timestamp, timezone.utc)
            time_str = dt_object.strftime("%Y-%m-%d %H:%M:%S")
            self.summary_table.insert("", 0, values=(time_str, count))
        except (ValueError, TypeError, tk.TclError):
            pass

    def update_last_query_result(self, timestamp: float, count: int):
        try:
            dt_object = datetime.fromtimestamp(timestamp, timezone.utc)
            time_str = dt_object.strftime("%H:%M:%S")
            result_text = f"Last query result: {count} aircraft at {time_str} UTC"
            self.last_query_result_var.set(result_text)
        except (ValueError, TypeError, tk.TclError):
            pass

    def clear_summary_table(self):
        if not self.summary_table or not self.summary_table.winfo_exists():
            return
            
        self.last_query_result_var.set("Last query result: N/A")
        self.session_stopped()

        try:
            for item in self.summary_table.get_children():
                self.summary_table.delete(item)
        except tk.TclError:
            pass

    def update_settings(self, enabled: bool, directory: str):
        self.enable_logging_var.set(enabled)
        self.log_directory_var.set(directory)
        self._on_toggle_logging()