"""Integration between error pattern learning and tool system."""

from typing import Any, Optional

from oclawma.learning import ErrorPatternLearner, get_default_learner
from oclawma.tools.base import BaseTool, ToolResult


class LearningToolWrapper:
    """Wrapper that adds error pattern learning to any tool."""

    def __init__(
        self,
        tool: BaseTool,
        learner: Optional[ErrorPatternLearner] = None,
        enable_auto_correct: bool = True,
    ) -> None:
        """Initialize the learning wrapper.

        Args:
            tool: The tool to wrap
            learner: Optional error pattern learner
            enable_auto_correct: Whether to enable auto-correction
        """
        self.tool = tool
        self.learner = learner or get_default_learner()
        self.enable_auto_correct = enable_auto_correct
        self._wrapped = True

    @property
    def name(self) -> str:
        """Get the tool name."""
        return self.tool.name

    @property
    def description(self) -> str:
        """Get the tool description."""
        return self.tool.description

    @property
    def schema(self):
        """Get the tool schema."""
        return self.tool.schema

    async def execute(self, **kwargs: Any) -> ToolResult:
        """Execute the tool with error learning and auto-correction.

        Args:
            **kwargs: Tool parameters

        Returns:
            ToolResult from execution
        """
        # Validate parameters first
        validated = self.tool.validate_params(kwargs)

        # Execute the tool
        result = await self.tool.execute(**validated)

        # If successful, return result
        if result.success:
            return result

        # Log the error
        self.learner.log_tool_error(
            tool_name=self.name,
            result=result,
            context={"params": validated},
        )

        # Try auto-correction if enabled
        if self.enable_auto_correct:
            error_message = result.error_message or result.output
            correction = self.learner.try_auto_correct(
                tool_name=self.name,
                params=validated,
                error_message=error_message,
            )

            if correction:
                # Check if we should switch tools
                if "tool_switch" in correction:
                    # Return a result suggesting tool switch
                    return ToolResult(
                        tool_name=self.name,
                        success=False,
                        output=result.output,
                        error_message=result.error_message,
                        metadata={
                            **result.metadata,
                            "auto_correction": correction,
                            "suggestion": f"Try using '{correction['tool_switch']}' tool instead",
                        },
                    )

                # Retry with corrected parameters
                retry_result = await self.tool.execute(**correction)

                # Record the correction result
                self.learner.record_correction_result(
                    pattern_name=self.learner._classify_error(error_message),
                    original=str(validated),
                    corrected=str(correction),
                    success=retry_result.success,
                )

                if retry_result.success:
                    # Return the successful retry with metadata
                    return ToolResult(
                        tool_name=self.name,
                        success=True,
                        output=retry_result.output,
                        metadata={
                            **retry_result.metadata,
                            "auto_corrected": True,
                            "original_params": validated,
                        },
                    )
                else:
                    # Log the retry failure
                    self.learner.log_tool_error(
                        tool_name=self.name,
                        result=retry_result,
                        context={"params": correction, "retry": True},
                    )

        return result

    def validate_params(self, params: dict[str, Any]) -> dict[str, Any]:
        """Validate parameters."""
        return self.tool.validate_params(params)

    def to_dict(self) -> dict[str, Any]:
        """Convert to dictionary."""
        return self.tool.to_dict()


def wrap_tool_with_learning(
    tool: BaseTool,
    learner: Optional[ErrorPatternLearner] = None,
) -> LearningToolWrapper:
    """Wrap a tool with error pattern learning.

    Args:
        tool: The tool to wrap
        learner: Optional error pattern learner

    Returns:
        Wrapped tool
    """
    return LearningToolWrapper(tool, learner)
