"""
Examples of different ToolRegistry usage patterns.

1. Using Registry as a Base Class (auto-registration of methods).
2. Using @tool decorator without the ToolRunner (manual tool dispatch/schema generation).
"""

import json

from openai_resptools import ToolRegistry


def _print_section(title: str) -> None:
    print(f"\n--- {title} ---")


class MyServiceTools(ToolRegistry):
    """Service exposing its public methods as tools."""

    def __init__(self, db_conn: str) -> None:
        super().__init__()
        self.db_conn = db_conn

    def get_user_status(self, user_id: int) -> str:
        """Return the status of a user."""
        return f"User {user_id} is active (DB: {self.db_conn})"

    def _internal_helper(self) -> None:
        """Private helper; not registered as a tool."""
        return None


def pattern_registry_subclass() -> None:
    _print_section("Pattern 1: Registry as a Class")

    service = MyServiceTools(db_conn="postgres://localhost:5432")
    print(f"Registered tools: {service.names()}")

    schemas = service.as_openai_tools()
    if schemas:
        print("OpenAI Tool Schema (first one):")
        print(json.dumps(schemas[0], indent=2))

    result = service.get("get_user_status").call({"user_id": 123})
    print(f"Execution Result: {result}")


def pattern_manual_dispatch() -> None:
    _print_section("Pattern 2: Using @tool without ToolRunner")

    manual_registry = ToolRegistry()

    @manual_registry.tool()
    def calculator(a: int, b: int, op: str) -> int:
        """Perform basic arithmetic."""
        if op == "+":
            return a + b
        if op == "-":
            return a - b
        raise ValueError(f"Unsupported operation: {op!r}")

    tools_payload = manual_registry.as_openai_tools()
    print(f"Tools payload ready for OpenAI API: {len(tools_payload)} tool(s)")

    mock_openai_call = {
        "name": "calculator",
        "arguments": '{"a": 10, "b": 5, "op": "+"}',
    }
    print(
        f"Received call request: {mock_openai_call['name']} "
        f"with {mock_openai_call['arguments']}"
    )

    tool_name = mock_openai_call["name"]
    try:
        args = json.loads(mock_openai_call["arguments"])
    except json.JSONDecodeError as exc:
        print(f"Invalid JSON arguments: {exc}")
        return

    if tool_name not in manual_registry:
        print(f"Tool {tool_name!r} not found!")
        return

    output = manual_registry.get(tool_name).call(args)
    print(f"Manual Execution Output: {output}")


def main() -> None:
    pattern_registry_subclass()
    pattern_manual_dispatch()


if __name__ == "__main__":
    main()
