# ruff: noqa: T201
"""Setup handler for AWS Bedrock."""

from boto3 import Session

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


class BedrockSetup(BaseProviderSetup):
    """Setup handler for AWS Bedrock provider credentials and models.

    Manages credential detection, validation, and model fetching for the
    AWS Bedrock API. Supports both automatic import from boto3 session
    (environment variables, AWS CLI config, or IAM roles) and interactive
    credential entry.
    """

    def __init__(self):
        """Initialise the AWS Bedrock setup handler."""
        super().__init__("bedrock")

    def detect_creds(self) -> dict[str, str] | None:
        """Detect AWS Bedrock credentials from boto3 session.

        Attempts to retrieve credentials from the default boto3 session,
        which can be configured via environment variables, AWS CLI config,
        IAM roles, or other boto3-supported credential sources.

        Returns:
            Dictionary with "access_key", "secret_key", and "region" if
            credentials are available in the boto3 session, otherwise None.
        """
        sess = Session()
        creds = sess.get_credentials()

        if creds is None:
            return None

        return {
            "access_key": creds.access_key,
            "secret_key": creds.secret_key,
            "region": sess.region_name,
        }

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

        Asks for AWS access key ID, secret access key, and region through
        interactive prompts.

        Returns:
            Dictionary with "access_key", "secret_key", and "region" if user
            provides credentials, otherwise None if user declines to enter
            credentials.
        """
        ask = self._confirm_ask_for_creds()
        if not ask:
            return None

        fields = ["access_key", "secret_key", "region"]
        delimiter = "\n * "
        print(
            "To get everything set up we will need your "
            f"AWS details:{delimiter}{delimiter.join(fields)}"
        )
        print("You can find these in your AWS IAM console or AWS CLI configuration")

        creds = {}

        for field in fields:
            if field == "region":
                print(
                    "Please enter your AWS region (e.g., us-east-1, us-west-2, eu-west-1):"
                )
            else:
                print(f"Please enter your AWS {field.replace('_', ' ')}:")
            creds[field] = input(" > ")

        return creds

    def validate_creds(self, creds: dict[str, str]) -> None:
        """Validate AWS Bedrock credentials format.

        Performs basic validation of credential field presence and format,
        including minimum length checks for access keys, secret keys, and
        region format.

        Args:
            creds: Dictionary containing "access_key", "secret_key", and
                "region" to validate.

        Raises:
            ValueError: If required fields are missing, if the access key
                appears too short (< 16 characters), if the secret key
                appears too short (< 28 characters), or if the region
                appears invalid (< 8 characters).
        """
        required_fields = ["access_key", "secret_key", "region"]
        missing = [f for f in required_fields if f not in creds or not creds[f]]

        if missing:
            raise ValueError(f"Missing required fields: {', '.join(missing)}")

            # Basic format validation
        access_key = creds["access_key"]
        if len(access_key) < 16:
            raise ValueError("Access Key ID appears too short")

        secret_key = creds["secret_key"]
        if len(secret_key) < 28:
            raise ValueError("Secret Access Key appears too short")

        region = creds["region"]
        if not region or len(region) < 8:
            raise ValueError("Region appears invalid")

    def fetch_models(self, creds_map: CredentialsMap) -> ModelRegistry:
        """Fetch available foundation models from AWS Bedrock.

        Retrieves the list of available foundation models from Bedrock and
        filters for models that support text output modalities.

        Args:
            creds_map: Credentials map containing Bedrock provider credentials.

        Returns:
            ModelRegistry containing LLMConfig entries for all available
            Bedrock foundation models that support text output.
        """
        creds = {
            k: DevKeyring.get(f"providers.{v}")
            for k, v in creds_map.providers["bedrock"].items()
        }
        sess = Session(
            aws_access_key_id=creds["access_key"],
            aws_secret_access_key=creds["secret_key"],
            region_name=creds["region"],
        )
        bedrock = sess.client("bedrock")

        res = bedrock.list_foundation_models()
        models = [m for m in res["modelSummaries"] if "TEXT" in m["outputModalities"]]

        def build_id(model_id: str) -> str:
            provider, *parts = model_id.split(".")
            identifier = "-".join(parts).replace(":", "-")
            return f"{provider}.{identifier}".lower()

        def _make_model_config(model: dict) -> LLMConfig:
            return LLMConfig(
                id=f"bedrock.{build_id(model['modelId'])}",
                display_name=model["modelName"],
                credentials="bedrock",
                provider=model["providerName"],
                interface="bedrock",
                model_id=model["modelId"],
            )

        model_configs = [_make_model_config(m) for m in models]

        print(f"  Adding {len(model_configs)} models from Bedrock")

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