# ruff: noqa: T201
"""Configuration and credentials import handler for Anthropic."""

import os
import re

from anthropic import Anthropic
from anthropic.types import ModelInfo

from yera.config2.dataclasses import CredentialsMap, LLMConfig, ModelRegistry
from yera.config2.keyring import DevKeyring
from yera.config2.setup_handlers.base import BaseProviderSetup


class AnthropicSetup(BaseProviderSetup):
    """Setup handler for Anthropic provider credentials and models.

    Manages credential detection, validation, and model fetching for the
    Anthropic API. Supports both automatic import from environment variables
    and interactive credential entry.
    """

    def __init__(self):
        """Initialise the Anthropic setup handler."""
        super().__init__("anthropic")

    def detect_creds(self) -> dict[str, str] | None:
        """Detect Anthropic credentials from environment variables.

        Returns:
            Dictionary with "api_key" if ANTHROPIC_API_KEY environment variable
            is set, otherwise None.
        """
        api_key = os.environ.get("ANTHROPIC_API_KEY")
        if api_key:
            return {"api_key": api_key}
        return None

    def ask_for_creds(self) -> dict[str, str] | None:
        """Prompt user to enter Anthropic API credentials interactively.

        Returns:
            Dictionary with "api_key" if user provides credentials, otherwise
            None if user declines to enter credentials.
        """
        ask = self._confirm_ask_for_creds()
        if ask:
            print("  Please enter your Anthropic API Key:")
            api_key = input(" > ")
            return {"api_key": api_key}
        return None

    def validate_creds(self, creds: dict[str, str]) -> None:
        """Validate Anthropic API key format.

        Args:
            creds: Dictionary containing "api_key" to validate.

        Raises:
            ValueError: If the API key format is invalid (wrong prefix, invalid
                characters, or appears incomplete).
        """
        api_key = creds["api_key"]

        pattern = r"^sk-ant-[A-Za-z0-9_-]+$"

        if not api_key.startswith("sk-ant-"):
            raise ValueError(
                "Invalid API key format. Anthropic API keys should start with 'sk-ant-'\n"
                "Please ensure you've copied the complete API key from the Anthropic Console."
            )

        if not re.match(pattern, api_key):
            raise ValueError(
                "Invalid API key format. Key contains invalid characters.\n"
                "Please ensure you've copied the complete API key from the Anthropic Console."
            )

        # Basic length check - Anthropic keys are typically quite long
        if len(api_key) < 40:
            raise ValueError(
                "API key appears too short. Please ensure you've copied the complete key."
            )

    def fetch_models(self, creds_map: CredentialsMap) -> ModelRegistry:
        """Fetch available models from Anthropic API.

        Retrieves the list of available Claude models and creates LLMConfig
        entries for each. Model IDs are normalised to lowercase with hyphens.

        Args:
            creds_map: Credentials map containing Anthropic provider credential labels.

        Returns:
            ModelRegistry containing LLMConfig entries for all available
            Anthropic models.
        """
        creds = {
            k: DevKeyring.get(f"providers.{v}")
            for k, v in creds_map.providers["anthropic"].items()
        }

        client = Anthropic(**creds)

        def _make_model_cfg(model_info: ModelInfo) -> LLMConfig:
            model_id = (
                model_info.display_name.lower().replace(" ", "-").replace(".", "-")
            )
            return LLMConfig(
                id=f"anthropic.{model_id}".lower(),
                display_name=model_info.display_name,
                credentials="anthropic",
                provider="anthropic",
                interface="anthropic-sdk",
                model_id=model_info.id,
            )

        model_list_result = client.models.list()
        model_configs = [_make_model_cfg(info) for info in model_list_result.data]

        names = "  \n   * ".join(m.display_name for m in model_configs)
        print(f"  Adding {len(model_configs)} LLMs from Anthropic:\n   * {names}")

        return ModelRegistry(
            llm={m.id: m for m in model_configs},
        )
