"""
LLM Factory — підтримка Anthropic Claude / DeepSeek / OpenAI / fallback.

Пріоритет:
  1. ANTHROPIC_API_KEY  → claude-sonnet-4-5     (через langchain-anthropic / crewai)
  2. DEEPSEEK_API_KEY   → deepseek-chat          (через langchain-openai compatible)
  3. OPENAI_API_KEY     → gpt-4o-mini            (через langchain-openai)
  4. None               → повертає None

Змінні середовища:
  ANTHROPIC_API_KEY     — ключ Anthropic Claude (найвищий пріоритет для Sofiia)
  ANTHROPIC_MODEL       — модель (default: claude-sonnet-4-5)
  DEEPSEEK_API_KEY      — ключ DeepSeek
  DEEPSEEK_MODEL        — модель (default: deepseek-chat)
  OPENAI_API_KEY        — ключ OpenAI (fallback)
  OPENAI_MODEL          — модель (default: gpt-4o-mini)

Використання:
  from crews.agromatrix_crew.llm_factory import make_llm
  agent = Agent(..., llm=make_llm())
"""

from __future__ import annotations

import logging
import os

logger = logging.getLogger(__name__)


def make_llm(force_provider: str | None = None):
    """
    Повертає LLM-інстанс для crewAI агентів.
    Fail-safe: якщо жоден ключ не знайдений — повертає None і логує warning.

    Args:
        force_provider: 'anthropic', 'deepseek', 'openai' — примусово обрати провайдера.
    """
    anthropic_key = os.getenv("ANTHROPIC_API_KEY", "").strip()
    deepseek_key = os.getenv("DEEPSEEK_API_KEY", "").strip()
    openai_key = os.getenv("OPENAI_API_KEY", "").strip()

    # ── Варіант 0: Anthropic Claude ──────────────────────────────────────────
    if anthropic_key and force_provider in (None, "anthropic"):
        # Try langchain-anthropic first
        try:
            from langchain_anthropic import ChatAnthropic  # type: ignore[import-untyped]
            model = os.getenv("ANTHROPIC_MODEL", "claude-sonnet-4-5")
            llm = ChatAnthropic(
                model=model,
                api_key=anthropic_key,
                temperature=0.2,
                max_tokens=8192,
            )
            logger.info("LLM: Anthropic Claude via langchain-anthropic (model=%s)", model)
            return llm
        except ImportError:
            pass
        except Exception as exc:
            logger.warning("langchain-anthropic init failed (%s), trying crewai.LLM", exc)

        # Try crewai.LLM with anthropic provider
        try:
            from crewai import LLM  # type: ignore[import-untyped]
            model = os.getenv("ANTHROPIC_MODEL", "claude-sonnet-4-5")
            llm = LLM(
                model=f"anthropic/{model}",
                api_key=anthropic_key,
                temperature=0.2,
                max_tokens=8192,
            )
            logger.info("LLM: Anthropic Claude via crewai.LLM (model=%s)", model)
            return llm
        except (ImportError, Exception) as exc:
            logger.warning("crewai.LLM Anthropic init failed (%s), trying DeepSeek fallback", exc)

    # ── Варіант 1: DeepSeek через OpenAI-compatible API ──────────────────────
    if deepseek_key and force_provider in (None, "deepseek"):
        try:
            from langchain_openai import ChatOpenAI
            model = os.getenv("DEEPSEEK_MODEL", "deepseek-chat")
            base_url = os.getenv("DEEPSEEK_BASE_URL", "https://api.deepseek.com")
            llm = ChatOpenAI(
                model=model,
                api_key=deepseek_key,
                base_url=base_url,
                temperature=0.3,
            )
            logger.info("LLM: DeepSeek via ChatOpenAI (model=%s, base_url=%s)", model, base_url)
            return llm
        except (ImportError, Exception) as exc:
            logger.warning("DeepSeek LLM init failed (%s), trying OpenAI fallback", exc)

    # ── Варіант 2: OpenAI ────────────────────────────────────────────────────
    if openai_key and force_provider in (None, "openai"):
        try:
            from langchain_openai import ChatOpenAI
            model = os.getenv("OPENAI_MODEL", "gpt-4o-mini")
            llm = ChatOpenAI(
                model=model,
                api_key=openai_key,
                temperature=0.3,
            )
            logger.info("LLM: OpenAI ChatOpenAI (model=%s)", model)
            return llm
        except ImportError:
            pass

        try:
            from crewai import LLM
            model = os.getenv("OPENAI_MODEL", "gpt-4o-mini")
            llm = LLM(
                model=f"openai/{model}",
                api_key=openai_key,
                temperature=0.3,
            )
            logger.info("LLM: OpenAI via crewai.LLM (model=%s)", model)
            return llm
        except (ImportError, Exception) as exc:
            logger.warning("OpenAI LLM init failed: %s", exc)

    # ── Нічого немає ────────────────────────────────────────────────────────
    logger.error(
        "LLM: no API key configured! "
        "Set ANTHROPIC_API_KEY (preferred for Sofiia), DEEPSEEK_API_KEY, or OPENAI_API_KEY."
    )
    return None


def make_sofiia_llm():
    """Спеціалізований LLM для Sofiia — Claude Sonnet з розширеним контекстом."""
    return make_llm(force_provider="anthropic")
