"""
Decision-making Tool for Agent
"""

from typing import Any, Dict

from openfund_agent.decision.engine import DecisionEngine
from openfund_agent.models.decision import (
    ImprovementPlan,
    Issue,
    PerformanceAnalysis,
    ReviewRequest,
)
from openfund_agent.models.performance import PerformanceReport
from openfund_agent.tools.base import BaseTool, register_tool


@register_tool
class DecisionMakingTool(BaseTool):
    """
    Tool for making strategic decisions based on performance analysis

    This tool wraps the DecisionEngine and provides a unified interface for
    the Agent to analyze performance, identify issues, and generate improvement plans.
    """

    def __init__(self, engine: DecisionEngine):
        """
        Initialize the decision-making tool

        Args:
            engine: DecisionEngine instance
        """
        super().__init__(
            name="decision_making",
            description="Analyze strategy performance and generate improvement plans",
        )
        self.engine = engine

    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_performance",
                    "identify_issues",
                    "generate_improvement_plan",
                    "request_human_review",
                ],
                "description": "Action to perform",
            },
            "performance_report": {
                "type": dict,
                "required": False,
                "description": "Performance report for analysis (required for analyze_performance)",
            },
            "strategy_config": {
                "type": dict,
                "required": False,
                "description": "Current strategy configuration (required for analyze_performance and generate_improvement_plan)",
            },
            "analysis": {
                "type": dict,
                "required": False,
                "description": "Performance analysis result (required for identify_issues)",
            },
            "issues": {
                "type": list,
                "required": False,
                "description": "List of identified issues (required for generate_improvement_plan)",
            },
            "plan": {
                "type": dict,
                "required": False,
                "description": "Improvement plan (required for request_human_review)",
            },
            "reason": {
                "type": str,
                "required": False,
                "description": "Reason for review request (required for request_human_review)",
            },
        }

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

        Args:
            parameters: Tool parameters

        Returns:
            Result based on the action performed

        Raises:
            ValueError: If required parameters are missing or invalid
            Exception: If execution fails
        """
        action = parameters["action"]

        if action == "analyze_performance":
            return self._analyze_performance(parameters)
        elif action == "identify_issues":
            return self._identify_issues(parameters)
        elif action == "generate_improvement_plan":
            return self._generate_improvement_plan(parameters)
        elif action == "request_human_review":
            return self._request_human_review(parameters)
        else:
            raise ValueError(f"Unknown action: {action}")

    def _analyze_performance(self, parameters: Dict[str, Any]) -> PerformanceAnalysis:
        """
        Analyze strategy performance

        Args:
            parameters: Tool parameters

        Returns:
            PerformanceAnalysis object

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

        # Convert dict to PerformanceReport if needed
        report_data = parameters["performance_report"]
        if isinstance(report_data, dict):
            # Reconstruct PerformanceReport from dict
            from openfund_agent.models.performance import PeriodMetrics, TradeMetrics

            metrics = PeriodMetrics(**report_data["metrics"])
            trade_list = [TradeMetrics(**t) for t in report_data.get("trade_list", [])]

            performance_report = PerformanceReport(
                period=report_data["period"],
                start_time=report_data["start_time"],
                end_time=report_data["end_time"],
                metrics=metrics,
                trade_list=trade_list,
                equity_curve=report_data.get("equity_curve", []),
                anomalies=report_data.get("anomalies", []),
            )
        else:
            performance_report = report_data

        strategy_config = parameters["strategy_config"]

        return self.engine.analyze_performance(performance_report, strategy_config)

    def _identify_issues(self, parameters: Dict[str, Any]) -> list:
        """
        Identify strategy issues

        Args:
            parameters: Tool parameters

        Returns:
            List of Issue objects

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

        # Convert dict to PerformanceAnalysis if needed
        analysis_data = parameters["analysis"]
        if isinstance(analysis_data, dict):
            analysis = PerformanceAnalysis(**analysis_data)
        else:
            analysis = analysis_data

        return self.engine.identify_issues(analysis)

    def _generate_improvement_plan(self, parameters: Dict[str, Any]) -> ImprovementPlan:
        """
        Generate improvement plan

        Args:
            parameters: Tool parameters

        Returns:
            ImprovementPlan object

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

        # Convert dicts to Issue objects if needed
        issues_data = parameters["issues"]
        if issues_data and isinstance(issues_data[0], dict):
            issues = [Issue(**issue_dict) for issue_dict in issues_data]
        else:
            issues = issues_data

        current_strategy = parameters["current_strategy"]

        return self.engine.generate_improvement_plan(issues, current_strategy)

    def _request_human_review(self, parameters: Dict[str, Any]) -> ReviewRequest:
        """
        Request human review

        Args:
            parameters: Tool parameters

        Returns:
            ReviewRequest object

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

        # Convert dict to ImprovementPlan if needed
        plan_data = parameters["plan"]
        if isinstance(plan_data, dict):
            from openfund_agent.models.decision import CodeModification

            modifications = [CodeModification(**mod) for mod in plan_data.get("modifications", [])]

            plan = ImprovementPlan(
                plan_id=plan_data["plan_id"],
                issues_addressed=plan_data.get("issues_addressed", []),
                modifications=modifications,
                expected_impact=plan_data.get("expected_impact", {}),
                risk_level=plan_data.get("risk_level", "medium"),
                requires_review=plan_data.get("requires_review", False),
                rationale=plan_data.get("rationale", ""),
                timestamp=plan_data.get("timestamp", 0),
            )
        else:
            plan = plan_data

        reason = parameters["reason"]

        return self.engine.request_human_review(plan, reason)
