import json
import logging
from typing import Any

from ...contexts import CompletionChoice, GenerationUsage


def get_finish_reason(response_obj: Any) -> str | None:
    """Extract finish reason from Anthropic response."""
    try:
        if hasattr(response_obj, "stop_reason"):
            return response_obj.stop_reason
        return None
    except Exception as e:
        logging.warning("Error getting finish reason from Anthropic", exc_info=e)
        return None


def get_completion_choices(response_obj: Any) -> list[CompletionChoice]:
    """Extract completion choices from Anthropic response."""
    try:
        choices = []
        if hasattr(response_obj, "content") and response_obj.content:
            for content_block in response_obj.content:
                if hasattr(content_block, "type") and content_block.type == "tool_use":
                    tool_call = {
                        "id": content_block.id,
                        "type": "function",
                        "function": {
                            "name": content_block.name,
                            "arguments": json.dumps(
                                content_block.input, ensure_ascii=False, default=repr
                            ),
                        },
                    }
                    choices.append(
                        CompletionChoice(
                            message={
                                "role": getattr(response_obj, "role", "assistant"),
                                "content": None,
                                "function_call": None,
                                "name": None,
                                "tool_calls": [tool_call],
                            },
                            delta=None,
                            text=None,
                        )
                    )
                elif hasattr(content_block, "text"):
                    choices.append(
                        CompletionChoice(
                            message={
                                "role": getattr(response_obj, "role", "assistant"),
                                "content": content_block.text,
                                "function_call": None,
                                "name": None,
                                "tool_calls": None,
                            },
                            delta=None,
                            text=content_block.text,
                        )
                    )
        return choices
    except Exception as e:
        logging.warning("Error getting completion choices from Anthropic", exc_info=e)
        return []


def get_usage_from_response(response_obj: Any) -> GenerationUsage:
    """Extract usage information from Anthropic response."""
    try:
        usage = getattr(response_obj, "usage", None)
        if usage:
            input_tokens = getattr(usage, "input_tokens", None)
            output_tokens = getattr(usage, "output_tokens", None)
            total_tokens = None
            if input_tokens is not None and output_tokens is not None:
                total_tokens = input_tokens + output_tokens

            return {
                "input_tokens": input_tokens,
                "output_tokens": output_tokens,
                "prompt_tokens": input_tokens,
                "completion_tokens": output_tokens,
                "total_tokens": total_tokens,
                "max_tokens": None,
                "temperature": None,
                "top_p": None,
                "stream": None,
                "tool_calls": None,
            }
        return {}
    except Exception as e:
        logging.warning("Error getting usage from Anthropic response", exc_info=e)
        return {}


def get_request_parameters(kwargs: dict) -> GenerationUsage:
    """Extract request parameters from kwargs."""
    try:
        return {
            "max_tokens": kwargs.get("max_tokens"),
            "temperature": kwargs.get("temperature"),
            "top_p": kwargs.get("top_p"),
            "stream": kwargs.get("stream", False),
            "input_tokens": None,
            "output_tokens": None,
            "prompt_tokens": None,
            "completion_tokens": None,
            "total_tokens": None,
            "tool_calls": None,
        }
    except Exception as e:
        logging.warning("Error getting request parameters from Anthropic", exc_info=e)
        return {}


def format_messages_for_tracing(messages: list[dict]) -> list[dict]:
    """Format Anthropic messages for tracing."""
    try:
        formatted_messages = []
        for msg in messages:
            role = msg.get("role", "user")
            content = msg.get("content", "")

            if isinstance(content, list):
                text_content = []
                for block in content:
                    if isinstance(block, dict):
                        if block.get("type") == "text":
                            text_content.append(block.get("text", ""))
                        elif block.get("type") == "tool_result":
                            text_content.append(f"[Tool Result: {block.get('content', '')}]")
                    elif hasattr(block, "type"):
                        if block.type == "text":
                            text_content.append(getattr(block, "text", ""))
                        elif block.type == "tool_result":
                            text_content.append(f"[Tool Result: {getattr(block, 'content', '')}]")
                content = "\n".join(text_content)

            formatted_messages.append({
                "role": role,
                "content": str(content),
                "function_call": None,
                "name": None,
                "tool_calls": None,
            })
        return formatted_messages
    except Exception as e:
        logging.warning("Error formatting messages for tracing", exc_info=e)
        return []


def get_stream_text(chunk: Any) -> str:
    """Extract text from streaming chunk."""
    try:
        if hasattr(chunk, "delta"):
            delta = chunk.delta
            if hasattr(delta, "text"):
                return delta.text or ""
        if hasattr(chunk, "content_block"):
            content_block = chunk.content_block
            if hasattr(content_block, "text"):
                return content_block.text or ""
        return ""
    except Exception:
        return ""
