# radar_data_reader/core/segment_processor.py

"""
Contains the business logic for the Segment Processor feature.
This class now acts as an orchestrator, delegating the processing of
individual .out files to the AppController to ensure consistent logic.
"""
import threading
import re
from pathlib import Path
from typing import Dict, Any, List
from tkinter import messagebox

try:
    import pandas as pd
except ImportError:
    pd = None

from ..utils import logger

log = logger.get_logger(__name__)

class SegmentProcessor:
    """Manages the batch processing of exported flight segments by orchestrating the AppController."""

    def __init__(self, controller: "AppController"):
        self.controller = controller
        self.config: Dict[str, Any] = {}
        self._worker_thread: threading.Thread = None
        self._stop_event = threading.Event()

    def load_segments_for_processing(self):
        """Loads and verifies segments from a flight analysis directory."""
        log.info("Loading segments for batch processing...")
        if self.controller.is_processing:
            messagebox.showwarning("Busy", "Cannot load segments while another process is running.", parent=self.controller.view)
            return

        tab = self.controller.view.segment_processor_tab
        flight_folder_str = tab.flight_analysis_dir_var.get()
        if not flight_folder_str:
            messagebox.showerror("No Directory Selected", "Please select a flight analysis directory first.", parent=self.controller.view)
            return
            
        flight_folder = Path(flight_folder_str)
        summary_file = flight_folder / "flight_summary.csv"

        if not flight_folder.is_dir() or not summary_file.is_file():
            messagebox.showerror(
                "Invalid Directory",
                f"The selected directory is not a valid flight analysis directory.\nMissing: {summary_file.name}",
                parent=self.controller.view
            )
            return

        try:
            if pd is None:
                log.error("Pandas is not installed. Cannot load segments."); return
            
            summary_df = pd.read_csv(summary_file)

            export_config = self.controller.config_manager.get("segment_export_config", {})
            naming_template = export_config.get("naming_options", {}).get("folder_name_template", "{Segment}_{StartBatch}-{EndBatch}")
            
            verified_segments = self.scan_for_segments(flight_folder, summary_df, naming_template)
            
            if not verified_segments:
                log.warning("No segments found in the summary or none are valid.")
            
            tab.populate_segments(verified_segments)
            log.info(f"Found and verified {len(verified_segments)} segments from {flight_folder.name}.")
            
            sp_config = self.controller.config_manager.get("segment_processor_config", {})
            sp_config["last_flight_analysis_dir"] = flight_folder_str
            self.controller.config_manager.set("segment_processor_config", sp_config)
            self.controller.config_manager.save_config()

        except Exception as e:
            log.error(f"Failed to load and verify segments: {e}", exc_info=True)
            messagebox.showerror("Error", f"An error occurred while loading segments:\n{e}", parent=self.controller.view)

    def start_batch_processing(self):
        """Starts the batch processing in a background thread."""
        if self.controller.is_processing:
            messagebox.showwarning("Busy", "Another process is already running.", parent=self.controller.view)
            return

        tab = self.controller.view.segment_processor_tab
        selected_segments = tab.get_selected_segments_data()
        
        if not selected_segments:
            messagebox.showinfo("No Selection", "Please select at least one 'Ready' segment to process.", parent=self.controller.view)
            return

        self.config = {
            "segments_to_process": selected_segments,
            "output_dir": tab.output_dir_var.get(),
            "generate_csv": tab.generate_csv_var.get(),
            "generate_json": tab.generate_json_var.get(),
            "create_separate_folders": tab.create_separate_folders_var.get(),
            "csv_profile_name": tab.csv_profile_var.get(),
            "json_profile_name": tab.json_profile_var.get(),
            "csv_use_tab": tab.csv_use_tab_var.get(),
            "use_full_path_headers": tab.use_full_path_var.get(),
        }

        if not self.config["output_dir"]:
            messagebox.showerror("Configuration Error", "Please specify an output directory.", parent=self.controller.view)
            return
        if not self.config["generate_csv"] and not self.config["generate_json"]:
            messagebox.showerror("Configuration Error", "Please select at least one output format (CSV or JSON).", parent=self.controller.view)
            return
        
        sp_config = self.controller.config_manager.get("segment_processor_config", {})
        sp_config["last_output_dir"] = self.config["output_dir"]
        sp_config["create_separate_folders"] = self.config["create_separate_folders"]
        self.controller.config_manager.set("segment_processor_config", sp_config)
        self.controller.config_manager.save_config()

        self._stop_event.clear()
        self._worker_thread = threading.Thread(
            target=self._run_batch_processing, daemon=True
        )
        self._worker_thread.start()

    def stop(self):
        """Signals the worker thread to stop processing."""
        self._stop_event.set()

    def _run_batch_processing(self):
        """The main loop that iterates through segments and calls the controller."""
        self.controller.is_processing = True
        self.controller.view.start_processing_ui()

        segments = self.config.get("segments_to_process", [])
        total_segments = len(segments)

        for i, segment_info in enumerate(segments):
            if self._stop_event.is_set():
                log.info("Stop command received, halting batch processing.")
                break

            segment_name = segment_info.get("folder_name")
            out_file_path = Path(segment_info.get("out_file_path"))
            
            # Update UI progress
            self.controller.result_queue.put(
                {
                    "type": "batch_progress",
                    "current": i + 1,
                    "total": total_segments,
                    "segment_name": segment_name,
                }
            )
            log.info(f"Processing segment {i+1}/{total_segments}: {segment_name}")
            
            output_dir_base = Path(self.config.get("output_dir"))
            current_output_dir = (
                output_dir_base / segment_name
                if self.config.get("create_separate_folders")
                else output_dir_base
            )
            current_output_dir.mkdir(parents=True, exist_ok=True)
            
            # --- DELEGA AL CONTROLLER ---
            self.controller.process_single_out_file(
                filepath=out_file_path,
                output_dir=current_output_dir,
                basename=segment_name,
                options=self.config # Passa le opzioni di output
            )

        log.info("Batch processing finished.")
        self.controller.result_queue.put(
            {"type": "complete", "message": "Segment batch processing complete."}
        )
        # Il reset dello stato 'is_processing' è gestito da handle_worker_completion
        # chiamato dall'ultimo messaggio "complete" nella coda.

    @staticmethod
    def scan_for_segments(
        flight_path: Path, flight_summary_df: pd.DataFrame, naming_template: str
    ) -> List[Dict[str, Any]]:
        """Scans for exported segments based on a flight summary and verifies them."""
        if flight_summary_df is None or flight_summary_df.empty:
            return []

        verified_segments = []
        for _, row in flight_summary_df.iterrows():
            placeholders = {
                "{Segment}": str(row.get("Segment (Mode | Scale | WF)", "")),
                "{StartBatch}": str(row.get("Start Batch", "")),
                "{EndBatch}": str(row.get("End Batch", "")),
                "{BatchCount}": str(row.get("Batch Count", "")),
            }
            folder_name = naming_template
            for key, value in placeholders.items():
                folder_name = folder_name.replace(key, value)
            
            safe_folder_name = re.sub(r'[\\/*?:"<>|]', "-", folder_name)

            segment_path = flight_path / safe_folder_name
            out_file_path = segment_path / f"{safe_folder_name}.out"

            segment_info = row.to_dict()
            segment_info["folder_name"] = safe_folder_name

            if (
                segment_path.is_dir()
                and out_file_path.is_file()
                and out_file_path.stat().st_size > 0
            ):
                segment_info["is_exported_and_valid"] = True
                segment_info["out_file_path"] = out_file_path
            else:
                segment_info["is_exported_and_valid"] = False
                segment_info["out_file_path"] = None

            verified_segments.append(segment_info)

        return verified_segments