"""Tool registry: Plugin string → tool class."""
from __future__ import annotations
from typing import Optional, Type
from tools.base import BaseTool

from tools.inout import InputDataTool, OutputDataTool, TextInputTool, BrowseTool
from tools.preparation import (
    FilterTool, FormulaTool, SelectTool, SortTool, SampleTool,
    UniqueTool, GenerateRowsTool, MultiRowFormulaTool,
    MultiFieldFormulaTool, RecordIDTool, AutoFieldTool,
)
from tools.join import JoinTool, JoinMultipleTool, UnionTool, AppendFieldsTool, FindReplaceTool
from tools.parse import DateTimeTool, RegExTool, TextToColumnsTool
from tools.transform import SummarizeTool, CrossTabTool, TransposeTool


class _PassthroughTool(BaseTool):
    def execute(self, inputs):
        df = next(iter(inputs.values())) if inputs else __import__("polars").DataFrame()
        return {"Output": df}


class _NullTool(BaseTool):
    def execute(self, inputs):
        return {}


_REGISTRY: dict[str, Type[BaseTool]] = {
    # In/Out
    "AlteryxBasePluginsGui.DbFileInput.DbFileInput": InputDataTool,
    "AlteryxBasePluginsGui.DbFileOutput.DbFileOutput": OutputDataTool,
    "AlteryxBasePluginsGui.TextInput.TextInput": TextInputTool,
    "AlteryxBasePluginsGui.BrowseV2.BrowseV2": BrowseTool,
    # Preparation
    "AlteryxBasePluginsGui.Filter.Filter": FilterTool,
    "AlteryxBasePluginsGui.Formula.Formula": FormulaTool,
    "AlteryxBasePluginsGui.AlteryxSelect.AlteryxSelect": SelectTool,
    "AlteryxBasePluginsGui.Sort.Sort": SortTool,
    "AlteryxBasePluginsGui.Sample.Sample": SampleTool,
    "AlteryxBasePluginsGui.Unique.Unique": UniqueTool,
    "AlteryxBasePluginsGui.GenerateRows.GenerateRows": GenerateRowsTool,
    "AlteryxBasePluginsGui.MultiRowFormula.MultiRowFormula": MultiRowFormulaTool,
    "AlteryxBasePluginsGui.MultiFieldFormula.MultiFieldFormula": MultiFieldFormulaTool,
    "AlteryxBasePluginsGui.RecordID.RecordID": RecordIDTool,
    "AlteryxBasePluginsGui.AutoField.AutoField": AutoFieldTool,
    # Join
    "AlteryxBasePluginsGui.Join.Join": JoinTool,
    "AlteryxBasePluginsGui.JoinMultiple.JoinMultiple": JoinMultipleTool,
    "AlteryxBasePluginsGui.Union.Union": UnionTool,
    "AlteryxBasePluginsGui.AppendFields.AppendFields": AppendFieldsTool,
    "AlteryxBasePluginsGui.FindReplace.FindReplace": FindReplaceTool,
    # Parse
    "AlteryxBasePluginsGui.DateTime.DateTime": DateTimeTool,
    "AlteryxBasePluginsGui.RegEx.RegEx": RegExTool,
    "AlteryxBasePluginsGui.TextToColumns.TextToColumns": TextToColumnsTool,
    # Transform
    "AlteryxSpatialPluginsGui.Summarize.Summarize": SummarizeTool,
    "AlteryxBasePluginsGui.CrossTab.CrossTab": CrossTabTool,
    "AlteryxBasePluginsGui.Transpose.Transpose": TransposeTool,
    # Documentation / no-op
    "AlteryxGuiToolkit.ToolContainer.ToolContainer": _PassthroughTool,
    "AlteryxGuiToolkit.TextBox.TextBox": _NullTool,
    "AlteryxGuiToolkit.Comment.Comment": _NullTool,
    "AlteryxBasePluginsGui.AlteryxAnnotation.AlteryxAnnotation": _NullTool,
}


def get_tool_class(plugin: str) -> Optional[Type[BaseTool]]:
    """Return the tool class for a given Plugin string, or None if unsupported."""
    if not plugin:
        return None
    cls = _REGISTRY.get(plugin)
    if cls is not None:
        return cls
    # Partial match fallback — useful for minor version differences in plugin names
    for key, cls in _REGISTRY.items():
        if plugin.endswith(key.split(".")[-1]) or key in plugin:
            return cls
    return None


def register_tool(plugin: str, cls: Type[BaseTool]) -> None:
    """Register a custom tool class for a given Plugin string."""
    _REGISTRY[plugin] = cls


__all__ = ["get_tool_class", "register_tool", "BaseTool"]
