"""LLM client for Tier 2 analysis."""

import json
import os
from dataclasses import dataclass


@dataclass
class LLMClient:
    """Unified LLM client supporting Anthropic, OpenAI, and Ollama."""

    provider: str = "anthropic"  # anthropic, openai, ollama
    model: str = "claude-haiku-4-5-20251001"
    api_key: str | None = None
    base_url: str | None = None  # For Ollama

    def __post_init__(self):
        if self.api_key is None:
            # Try loading from .env
            try:
                from dotenv import load_dotenv

                load_dotenv()
            except ImportError:
                pass
            if self.provider == "anthropic":
                self.api_key = os.environ.get("ANTHROPIC_API_KEY")
            elif self.provider == "openai":
                self.api_key = os.environ.get("OPENAI_API_KEY")

    def complete(self, system: str, user: str, max_tokens: int = 4096) -> str:
        """Send a completion request and return the response text."""
        if self.provider == "anthropic":
            return self._anthropic_complete(system, user, max_tokens)
        elif self.provider == "openai":
            return self._openai_complete(system, user, max_tokens)
        elif self.provider == "ollama":
            return self._ollama_complete(system, user, max_tokens)
        raise ValueError(f"Unknown provider: {self.provider}")

    def complete_json(self, system: str, user: str, max_tokens: int = 4096) -> dict:
        """Send a completion request and parse JSON from response."""
        text = self.complete(system, user, max_tokens)
        # Extract JSON from response (handle markdown code blocks)
        text = text.strip()
        if text.startswith("```json"):
            text = text[7:]
        if text.startswith("```"):
            text = text[3:]
        if text.endswith("```"):
            text = text[:-3]
        return json.loads(text.strip())

    def _anthropic_complete(self, system, user, max_tokens):
        import anthropic

        client = anthropic.Anthropic(api_key=self.api_key)
        response = client.messages.create(
            model=self.model,
            max_tokens=max_tokens,
            system=system,
            messages=[{"role": "user", "content": user}],
        )
        return response.content[0].text

    def _openai_complete(self, system, user, max_tokens):
        from openai import OpenAI

        client = OpenAI(api_key=self.api_key)
        response = client.chat.completions.create(
            model=self.model,
            max_tokens=max_tokens,
            messages=[
                {"role": "system", "content": system},
                {"role": "user", "content": user},
            ],
        )
        return response.choices[0].message.content

    def _ollama_complete(self, system, user, max_tokens):
        import requests

        url = self.base_url or "http://localhost:11434"
        response = requests.post(
            f"{url}/api/chat",
            json={
                "model": self.model,
                "messages": [
                    {"role": "system", "content": system},
                    {"role": "user", "content": user},
                ],
                "stream": False,
            },
        )
        return response.json()["message"]["content"]


# Convenience constructors
def get_client(model: str = "haiku", api_key: str | None = None) -> LLMClient:
    """Create an LLM client from a short model name."""
    MODEL_MAP = {
        "opus": ("anthropic", "claude-opus-4-20250514"),
        "sonnet": ("anthropic", "claude-sonnet-4-20250514"),
        "haiku": ("anthropic", "claude-haiku-4-5-20251001"),
        "gpt-4o": ("openai", "gpt-4o"),
        "gpt-4o-mini": ("openai", "gpt-4o-mini"),
    }
    if model in MODEL_MAP:
        provider, model_id = MODEL_MAP[model]
        return LLMClient(provider=provider, model=model_id, api_key=api_key)
    # Assume it's a full model ID
    if "claude" in model or "anthropic" in model:
        return LLMClient(provider="anthropic", model=model, api_key=api_key)
    if "gpt" in model or "o1" in model or "o3" in model:
        return LLMClient(provider="openai", model=model, api_key=api_key)
    # Default to Ollama for unknown models
    return LLMClient(provider="ollama", model=model)
