"""Anthropic Claude provider."""

from __future__ import annotations

from typing import Any

from ai_qa.exceptions import ProviderAPIError, ProviderNotConfiguredError
from ai_qa.providers.base import BaseProvider


class AnthropicProvider(BaseProvider):
    """Provider for Anthropic Claude models.

    Requires anthropic SDK installed:
        pip install ai-qa-sdk[anthropic]

    Attributes:
        name: Always "anthropic".
        model: Model name (e.g., "claude-3-sonnet").
        api_key: API key for authentication.
    """

    name = "anthropic"

    def __init__(self, model: str, api_key: str | None = None, **kwargs: Any) -> None:
        """Initialize Anthropic provider.

        Args:
            model: Model name (e.g., "claude-3-sonnet").
            api_key: Optional API key (uses ANTHROPIC_API_KEY env var if not set).
            **kwargs: Additional config (max_tokens, temperature, etc.).

        Raises:
            ProviderNotConfiguredError: If anthropic SDK is not installed.
        """
        super().__init__(model, **kwargs)
        self.api_key = api_key

        try:
            import anthropic
        except ImportError as e:
            raise ProviderNotConfiguredError(
                "Anthropic provider requires the anthropic package.\n"
                "Install it with: pip install ai-qa-sdk[anthropic]"
            ) from e

        self.client = anthropic.Anthropic(api_key=api_key)

    def judge(
        self,
        system: str,
        user: str,
    ) -> dict[str, Any]:
        """Call Claude to judge output.

        Args:
            system: System prompt.
            user: User prompt.

        Returns:
            Dict with score, evidence, cost_usd, tokens.

        Raises:
            ProviderAPIError: If API call fails.
        """
        try:
            response = self.client.messages.create(
                model=self.model,
                max_tokens=self.config.get("max_tokens", 1024),
                system=system,
                messages=[{"role": "user", "content": user}],
                temperature=self.config.get("temperature", 0.0),
            )

            # Parse response content
            content = response.content[0].text if response.content else ""

            # Extract score and evidence (simple parsing)
            # Format expected: "score: 0.85\nevidence: ..."
            lines = content.split("\n")
            score = 0.5
            evidence = content

            for line in lines:
                if line.startswith("score:"):
                    try:
                        score = float(line.split(":", 1)[1].strip())
                        score = min(1.0, max(0.0, score))  # Clamp to [0, 1]
                    except (ValueError, IndexError):
                        pass
                elif line.startswith("evidence:"):
                    evidence = line.split(":", 1)[1].strip()
                    break

            # Calculate cost (rough estimate)
            input_tokens = response.usage.input_tokens
            output_tokens = response.usage.output_tokens
            cost_usd = (input_tokens * 0.003 + output_tokens * 0.015) / 1000

            return {
                "score": score,
                "evidence": evidence if evidence else content[:500],
                "cost_usd": cost_usd,
                "tokens": {
                    "input": input_tokens,
                    "output": output_tokens,
                },
            }
        except Exception as e:
            if "ProviderAPIError" in str(type(e).__mro__):
                raise
            raise ProviderAPIError(
                f"Anthropic API call failed: {type(e).__name__}: {str(e)}"
            ) from e

    def generate(
        self,
        prompt: str,
        system: str | None = None,
    ) -> str:
        """Generate text using Claude.

        Args:
            prompt: Input prompt.
            system: Optional system prompt.

        Returns:
            Generated text.

        Raises:
            ProviderAPIError: If API call fails.
        """
        try:
            messages = [{"role": "user", "content": prompt}]
            kwargs: dict[str, Any] = {
                "model": self.model,
                "max_tokens": self.config.get("max_tokens", 1024),
                "messages": messages,
                "temperature": self.config.get("temperature", 0.7),
            }
            if system:
                kwargs["system"] = system

            response = self.client.messages.create(**kwargs)
            return response.content[0].text if response.content else ""
        except Exception as e:
            if "ProviderAPIError" in str(type(e).__mro__):
                raise
            raise ProviderAPIError(
                f"Anthropic API call failed: {type(e).__name__}: {str(e)}"
            ) from e
