# ruff: noqa: T201
"""Configuration import handler for Ollama."""

import os
from typing import Any

import requests as r

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


class OllamaSetup(BaseProviderSetup):
    """Setup handler for Ollama provider credentials and models.

    Manages connection setup and model fetching for local Ollama.
    Supports both automatic detection of running Ollama servers and interactive
    configuration of custom base URLs.
    """

    def __init__(self):
        """Initialise the Ollama setup handler."""
        super().__init__("ollama")

    @staticmethod
    def _is_ollama_running(base_url: str) -> bool:
        try:
            response = r.get(f"{base_url}/api/tags", timeout=2)
            return response.status_code == 200
        except Exception:
            return False

    def detect_creds(self) -> dict[str, str] | None:
        """Detect Ollama connection from environment or default location.

        Checks OLLAMA_BASE_URL environment variable or defaults to
        http://localhost:11434. Verifies that Ollama is actually running.

        Returns:
            Dictionary with "base_url" if Ollama is running, otherwise None.
        """
        base_url = os.environ.get("OLLAMA_BASE_URL", "http://localhost:11434")

        if self._is_ollama_running(base_url):
            return {"base_url": base_url}
        return None

    def ask_for_creds(self) -> dict[str, str] | None:
        """Prompt user to configure Ollama connection interactively.

        Allows user to specify a custom base URL or use the default. Verifies
        that Ollama is running at the specified URL before accepting.

        Returns:
            Dictionary with "base_url" if Ollama is running at the specified
            URL, otherwise None if user declines or connection fails.
        """
        ask = self._confirm_ask_for_creds()
        if not ask:
            return None

        print("  Is Ollama running on a custom URL? (default: http://localhost:11434)")
        print("  Press Enter to use default, or enter custom URL:")
        base_url = input(" > ").strip()

        if not base_url:
            base_url = "http://localhost:11434"

        if not self._is_ollama_running(base_url):
            print(f"  ⚠️  Cannot connect to Ollama at {base_url}")
            print("  Make sure Ollama is installed and running: https://ollama.ai")
            return None

        return {"base_url": base_url}

    def validate_creds(self, creds: dict[str, str]) -> None:
        """Validate that Ollama is running at the configured URL.

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

        Raises:
            ValueError: If Ollama is not running at the specified URL.
        """
        base_url = creds.get("base_url", "http://localhost:11434")

        if not self._is_ollama_running(base_url):
            raise ValueError(
                f"Cannot connect to Ollama at {base_url}\n"
                "Make sure Ollama is installed and running.\n"
                "Install from: https://ollama.ai"
            )

    def fetch_models(self, creds_map: CredentialsMap) -> ModelRegistry:
        """Fetch available models from local Ollama instance.

        Retrieves the list of models currently installed in Ollama.

        Args:
            creds_map: Credentials map containing Ollama provider configuration.

        Returns:
            ModelRegistry containing LLMConfig entries for all installed
            Ollama models, or empty registry if none found or on error.
        """
        creds = {
            k: DevKeyring.get(f"providers.{v}")
            for k, v in creds_map.providers["ollama"].items()
        }

        base_url = creds.get("base_url", "http://localhost:11434")

        try:
            response = r.get(f"{base_url}/api/tags", timeout=5)
            response.raise_for_status()
            data = response.json()

            models = data.get("models", [])

            if not models:
                print(
                    "  ⚠️  No models found. Pull models with: ollama pull <model-name>"
                )
                print("  Popular models: llama3.1, mistral, codellama, phi3")
                return ModelRegistry()

            model_configs = [self._make_model_cfg(m) for m in models]

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

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

        except Exception as e:
            print(f"  ⚠️  Error fetching Ollama models: {e}")
            return ModelRegistry()

    def _make_model_cfg(self, model: dict[str, Any]) -> LLMConfig:
        model_name = model["name"]

        display_name = model_name.replace(":", " ")

        return LLMConfig(
            id=f"ollama.{model_name}".lower(),
            display_name=display_name,
            credentials="ollama",
            provider="ollama",
            interface="ollama",  # Ollama uses OpenAI-compatible API
            model_id=model_name,
        )
