"""
Evolution monitoring module

This module provides monitoring and control capabilities for the evolution process,
allowing real-time status queries and process control.
"""

import logging
from typing import Dict, List, Any, Optional

from ..models.evolution import IterationResult
from .orchestrator import EvolutionOrchestrator

logger = logging.getLogger(__name__)


class EvolutionMonitor:
    """
    Evolution process monitor

    Provides real-time monitoring and control of the evolution process,
    including status queries, iteration history, and process control
    (pause/resume/stop).

    Attributes:
        orchestrator: Evolution orchestrator instance to monitor
    """

    def __init__(self, orchestrator: EvolutionOrchestrator):
        """
        Initialize evolution monitor

        Args:
            orchestrator: Evolution orchestrator instance
        """
        self.orchestrator = orchestrator

    def get_current_status(self) -> Dict[str, Any]:
        """
        Get current evolution status

        Returns comprehensive status information including:
        - Current status (running/paused/completed/etc.)
        - Current iteration number
        - Maximum iterations
        - Current performance metrics
        - Optimization goal

        Returns:
            Dictionary containing current status information
        """
        return {
            "status": self.orchestrator.state.status,
            "current_iteration": len(self.orchestrator.iteration_history),
            "max_iterations": self.orchestrator.config.max_iterations,
            "current_metrics": (
                {
                    "sharpe_ratio": self.orchestrator.state.current_metrics.sharpe_ratio,
                    "win_rate": self.orchestrator.state.current_metrics.win_rate,
                    "profit_factor": self.orchestrator.state.current_metrics.profit_factor,
                    "max_drawdown": self.orchestrator.state.current_metrics.max_drawdown,
                }
                if self.orchestrator.state.current_metrics
                else None
            ),
            "optimization_goal": (
                {
                    "target_metric": self.orchestrator.state.optimization_goal.target_metric,
                    "target_value": self.orchestrator.state.optimization_goal.target_value,
                    "description": self.orchestrator.state.optimization_goal.description,
                }
                if self.orchestrator.state.optimization_goal
                else None
            ),
        }

    def get_iteration_history(self, limit: Optional[int] = None) -> List[IterationResult]:
        """
        Get iteration history

        Retrieves the history of all completed iterations, optionally
        limited to the most recent N iterations.

        Args:
            limit: Maximum number of iterations to return (most recent first)

        Returns:
            List of IterationResult objects
        """
        history = self.orchestrator.iteration_history
        if limit:
            return history[-limit:]
        return history

    def pause_evolution(self) -> bool:
        """
        Pause evolution process

        Pauses the evolution loop if it is currently running.
        The process can be resumed later with resume_evolution().

        Returns:
            True if successfully paused, False otherwise
        """
        if self.orchestrator.state.status == "running":
            self.orchestrator.state.status = "paused"
            logger.info("Evolution process paused")
            return True

        logger.warning(
            f"Cannot pause evolution: current status is {self.orchestrator.state.status}"
        )
        return False

    def resume_evolution(self) -> bool:
        """
        Resume paused evolution process

        Resumes the evolution loop if it was previously paused.

        Returns:
            True if successfully resumed, False otherwise
        """
        if self.orchestrator.state.status == "paused":
            self.orchestrator.state.status = "running"
            logger.info("Evolution process resumed")
            return True

        logger.warning(
            f"Cannot resume evolution: current status is {self.orchestrator.state.status}"
        )
        return False

    def stop_evolution(self) -> bool:
        """
        Stop evolution process

        Stops the evolution loop permanently. Unlike pause, a stopped
        process cannot be resumed and must be restarted from scratch.

        Returns:
            True if successfully stopped, False otherwise
        """
        if self.orchestrator.state.status in ["running", "paused"]:
            self.orchestrator.state.status = "stopped"
            logger.info("Evolution process stopped")
            return True

        logger.warning(f"Cannot stop evolution: current status is {self.orchestrator.state.status}")
        return False

    def get_performance_trend(self) -> Dict[str, List[float]]:
        """
        Get performance metrics trend

        Extracts performance metrics from all iterations to show
        how metrics have evolved over time.

        Returns:
            Dictionary mapping metric names to lists of values
        """
        metrics_history = [
            i.metrics for i in self.orchestrator.iteration_history if i.metrics is not None
        ]

        return {
            "sharpe_ratio": [m.sharpe_ratio for m in metrics_history],
            "win_rate": [m.win_rate for m in metrics_history],
            "profit_factor": [m.profit_factor for m in metrics_history],
            "max_drawdown": [m.max_drawdown for m in metrics_history],
        }

    def get_detailed_status(self) -> Dict[str, Any]:
        """
        Get detailed evolution status

        Provides comprehensive status information including current state,
        iteration history summary, and performance trends.

        Returns:
            Dictionary with detailed status information
        """
        current_status = self.get_current_status()
        performance_trend = self.get_performance_trend()

        # Calculate success rate
        total_iterations = len(self.orchestrator.iteration_history)
        successful_iterations = len(
            [i for i in self.orchestrator.iteration_history if i.status == "success"]
        )
        success_rate = successful_iterations / total_iterations if total_iterations > 0 else 0.0

        # Get latest iteration
        latest_iteration = (
            self.orchestrator.iteration_history[-1] if self.orchestrator.iteration_history else None
        )

        return {
            **current_status,
            "total_iterations": total_iterations,
            "successful_iterations": successful_iterations,
            "success_rate": success_rate,
            "latest_iteration": (
                {
                    "iteration_num": latest_iteration.iteration_num,
                    "status": latest_iteration.status,
                    "timestamp": latest_iteration.timestamp,
                }
                if latest_iteration
                else None
            ),
            "performance_trend": performance_trend,
        }
