"""Internal type definitions for mcp-forge."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any


@dataclass(frozen=True)
class ToolInfo:
    """Metadata about an MCP tool."""

    name: str
    description: str | None = None
    input_schema: dict[str, Any] = field(default_factory=dict)
    output_schema: dict[str, Any] | None = None

    def has_required_params(self) -> bool:
        """Check if the tool has any required parameters."""
        return bool(self.input_schema.get("required"))

    @property
    def param_names(self) -> list[str]:
        """Get the list of parameter names."""
        props = self.input_schema.get("properties", {})
        return list(props.keys())

    @property
    def required_params(self) -> list[str]:
        """Get the list of required parameter names."""
        return list(self.input_schema.get("required", []))

    def to_dict(self) -> dict[str, Any]:
        """Convert to a serializable dict."""
        d: dict[str, Any] = {
            "name": self.name,
            "description": self.description,
            "input_schema": self.input_schema,
        }
        if self.output_schema is not None:
            d["output_schema"] = self.output_schema
        return d


@dataclass
class ContentBlock:
    """A single content block from a tool response."""

    type: str
    text: str | None = None
    data: str | None = None
    mime_type: str | None = None
    raw: dict[str, Any] = field(default_factory=dict)


@dataclass
class ToolResult:
    """Result from calling an MCP tool."""

    content: list[ContentBlock]
    is_error: bool = False
    raw: dict[str, Any] = field(default_factory=dict)

    @property
    def is_success(self) -> bool:
        """Check if the tool call succeeded."""
        return not self.is_error

    @property
    def text(self) -> str:
        """Get the concatenated text from all text content blocks."""
        parts = []
        for block in self.content:
            if block.type == "text" and block.text is not None:
                parts.append(block.text)
        return "\n".join(parts)

    @property
    def first_text(self) -> str | None:
        """Get text from the first text content block."""
        for block in self.content:
            if block.type == "text" and block.text is not None:
                return block.text
        return None

    def to_dict(self) -> dict[str, Any]:
        """Convert to a serializable dict for snapshot comparison."""
        return {
            "is_error": self.is_error,
            "content": [
                {
                    "type": b.type,
                    "text": b.text,
                    "data": b.data,
                    "mime_type": b.mime_type,
                }
                for b in self.content
            ],
        }


@dataclass(frozen=True)
class ResourceInfo:
    """Metadata about an MCP resource."""

    uri: str
    name: str | None = None
    description: str | None = None
    mime_type: str | None = None


@dataclass
class ResourceResult:
    """Result from reading an MCP resource."""

    content: list[ContentBlock]
    is_error: bool = False

    @property
    def is_success(self) -> bool:
        return not self.is_error

    @property
    def text(self) -> str:
        parts = []
        for block in self.content:
            if block.type == "text" and block.text is not None:
                parts.append(block.text)
        return "\n".join(parts)


@dataclass(frozen=True)
class PromptInfo:
    """Metadata about an MCP prompt."""

    name: str
    description: str | None = None
    arguments: list[dict[str, Any]] = field(default_factory=list)


@dataclass
class PromptResult:
    """Result from getting an MCP prompt."""

    messages: list[dict[str, Any]] = field(default_factory=list)
    description: str | None = None
    is_error: bool = False

    @property
    def is_success(self) -> bool:
        return not self.is_error


@dataclass
class ServerCapabilities:
    """Capabilities reported by the MCP server during initialization."""

    tools: bool = False
    resources: bool = False
    prompts: bool = False
    logging: bool = False
    raw: dict[str, Any] = field(default_factory=dict)
