"""
Performance Feedback Tool for Agent

This module provides a Tool wrapper for the PerformanceAnalyzer,
allowing the Agent to analyze trading performance and generate reports.
"""

import time
from typing import Dict, Any
from openfund_agent.tools.base import BaseTool, register_tool
from openfund_agent.feedback.analyzer import PerformanceAnalyzer
from openfund_agent.feedback.notification import NotificationService
from openfund_agent.models.trading import Trade


@register_tool
class PerformanceFeedbackTool(BaseTool):
    """
    Tool for analyzing trading performance and generating feedback reports

    This tool wraps the PerformanceAnalyzer and provides a unified interface
    for the Agent to analyze trades, calculate metrics, and generate reports.
    """

    def __init__(
        self,
        analyzer: PerformanceAnalyzer = None,
        notification_service: NotificationService = None,
    ):
        """
        Initialize the Performance Feedback Tool

        Args:
            analyzer: PerformanceAnalyzer instance (creates new if None)
            notification_service: Optional notification service for alerts
        """
        super().__init__(
            name="performance_feedback",
            description="Analyze trading performance and generate feedback reports",
        )

        if analyzer is None:
            analyzer = PerformanceAnalyzer(notification_service=notification_service)

        self.analyzer = analyzer

    def _define_parameters(self) -> Dict[str, Any]:
        """
        Define parameter schema for the tool

        Returns:
            Parameter schema dictionary
        """
        return {
            "action": {
                "type": str,
                "required": True,
                "enum": ["analyze_trade", "analyze_period", "generate_report"],
                "description": "Action to perform: analyze_trade, analyze_period, or generate_report",
            },
            "trade": {
                "type": dict,
                "required": False,
                "description": "Trade record dictionary (required for analyze_trade action)",
            },
            "start_time": {
                "type": int,
                "required": False,
                "description": "Period start timestamp (required for analyze_period action)",
            },
            "end_time": {
                "type": int,
                "required": False,
                "description": "Period end timestamp (required for analyze_period action)",
            },
            "period": {
                "type": str,
                "required": False,
                "enum": ["daily", "weekly", "monthly"],
                "description": "Report period (for generate_report action, default: daily)",
            },
        }

    def execute(self, parameters: Dict[str, Any]) -> Any:
        """
        Execute the tool with given parameters

        Args:
            parameters: Tool parameters including action and action-specific params

        Returns:
            Execution result based on the action

        Raises:
            ValueError: If parameters are invalid or action fails
        """
        start_time = time.time()
        action = parameters["action"]

        try:
            if action == "analyze_trade":
                result = self._analyze_trade(parameters)
            elif action == "analyze_period":
                result = self._analyze_period(parameters)
            elif action == "generate_report":
                result = self._generate_report(parameters)
            else:
                raise ValueError(f"Unknown action: {action}")

            execution_time = time.time() - start_time
            return {
                "success": True,
                "action": action,
                "result": result,
                "execution_time": execution_time,
            }

        except Exception as e:
            execution_time = time.time() - start_time
            return {
                "success": False,
                "action": action,
                "error": str(e),
                "execution_time": execution_time,
            }

    def _analyze_trade(self, parameters: Dict[str, Any]) -> Dict[str, Any]:
        """
        Analyze a single trade

        Args:
            parameters: Parameters including 'trade' dictionary

        Returns:
            Trade metrics dictionary

        Raises:
            ValueError: If trade parameter is missing or invalid
        """
        if "trade" not in parameters:
            raise ValueError("Missing required parameter: trade")

        trade_dict = parameters["trade"]

        # Convert dictionary to Trade object
        trade = Trade(**trade_dict)

        # Analyze the trade
        trade_metrics = self.analyzer.analyze_trade(trade)

        # Convert to dictionary for serialization
        from dataclasses import asdict

        return asdict(trade_metrics)

    def _analyze_period(self, parameters: Dict[str, Any]) -> Dict[str, Any]:
        """
        Analyze performance for a time period

        Args:
            parameters: Parameters including 'start_time' and 'end_time'

        Returns:
            Period metrics dictionary

        Raises:
            ValueError: If required parameters are missing
        """
        if "start_time" not in parameters:
            raise ValueError("Missing required parameter: start_time")
        if "end_time" not in parameters:
            raise ValueError("Missing required parameter: end_time")

        start_time = parameters["start_time"]
        end_time = parameters["end_time"]

        # Analyze the period
        period_metrics = self.analyzer.analyze_period(start_time, end_time)

        # Convert to dictionary for serialization
        from dataclasses import asdict

        result = asdict(period_metrics)

        # Handle infinity in profit_factor
        if result["profit_factor"] == float("inf"):
            result["profit_factor"] = "infinity"

        return result

    def _generate_report(self, parameters: Dict[str, Any]) -> Dict[str, Any]:
        """
        Generate a comprehensive performance report

        Args:
            parameters: Parameters including optional 'period'

        Returns:
            Performance report dictionary

        Raises:
            ValueError: If report generation fails
        """
        period = parameters.get("period", "daily")

        # Generate the report
        report = self.analyzer.generate_report(period)

        # Convert to dictionary for serialization
        return report.to_dict()

    def add_trade_to_history(self, trade: Trade) -> None:
        """
        Add a trade to the analyzer's history

        This is a helper method to populate the analyzer with trade data.

        Args:
            trade: Trade object to add
        """
        self.analyzer.trade_history.append(trade)

    def clear_trade_history(self) -> None:
        """
        Clear all trades from the analyzer's history

        This is useful for testing or resetting the analyzer.
        """
        self.analyzer.trade_history.clear()

    def get_trade_count(self) -> int:
        """
        Get the number of trades in history

        Returns:
            Number of trades in the analyzer's history
        """
        return len(self.analyzer.trade_history)
