"""
LLMOptimize v3.2.1 - AI Cost Optimization SDK

FIX vs original:
  Session ID file now stored in a temp-safe location and never crashes
  when the home directory is read-only (e.g. some cloud envs).
"""

__version__ = "3.2.2"
__author__  = "LLMOptimize Team"

import os
import uuid
import logging
import requests

log = logging.getLogger(__name__)

from llmoptimize.dashboard import (
    Colors,
    print_gradient_header,
    print_loading_animation,
    print_stat_card,
    print_recommendation_card,
    print_divider,
    print_savings_celebration,
    LLMOptimize as DashboardClient,
)

SERVER_URL = os.getenv("AIOPTIMIZE_SERVER_URL", "https://aioptimize.up.railway.app")


def _get_session_id() -> str:
    """Get or create a persistent anonymous session ID."""
    session_file = os.path.expanduser("~/.llmoptimize_session")
    try:
        if os.path.exists(session_file):
            with open(session_file) as f:
                sid = f.read().strip()
                if sid:
                    return sid
        sid = str(uuid.uuid4())
        with open(session_file, "w") as f:
            f.write(sid)
        return sid
    except OSError:
        # Read-only filesystem — use an in-memory ID for this process
        return str(uuid.uuid4())


SESSION_ID = _get_session_id()


# ── Auto-patching ─────────────────────────────────────────────────────────────

def _track_call(
    model:             str,
    prompt_tokens:     int,
    completion_tokens: int = 0,
    provider:          str = "unknown",
    prompt_preview:    str = "",
) -> None:
    """Fire-and-forget tracking POST. Never blocks or raises."""
    try:
        requests.post(
            f"{SERVER_URL}/track",
            json={
                "model":             model,
                "prompt_tokens":     prompt_tokens,
                "completion_tokens": completion_tokens,
                "session_id":        SESSION_ID,
                "provider":          provider,
                "prompt_preview":    prompt_preview[:100],   # privacy cap
                "sdk_version":       __version__,
            },
            timeout=3,
        )
    except Exception:
        pass   # never crash user code


def _patch_openai() -> None:
    try:
        import openai

        # Chat completions
        _orig_chat = openai.resources.chat.completions.Completions.create

        def _tracked_chat(self, *args, **kwargs):
            response = _orig_chat(self, *args, **kwargs)
            if hasattr(response, "usage") and response.usage:
                _track_call(
                    model             = kwargs.get("model", "gpt-unknown"),
                    prompt_tokens     = response.usage.prompt_tokens,
                    completion_tokens = response.usage.completion_tokens,
                    provider          = "openai",
                )
            return response

        openai.resources.chat.completions.Completions.create = _tracked_chat

        # Embeddings
        _orig_emb = openai.resources.embeddings.Embeddings.create

        def _tracked_emb(self, *args, **kwargs):
            response = _orig_emb(self, *args, **kwargs)
            if hasattr(response, "usage") and response.usage:
                _track_call(
                    model         = kwargs.get("model", "embedding-unknown"),
                    prompt_tokens = response.usage.prompt_tokens,
                    provider      = "openai",
                )
            return response

        openai.resources.embeddings.Embeddings.create = _tracked_emb

    except ImportError:
        pass
    except Exception as exc:
        log.debug("OpenAI patch failed: %s", exc)


def _patch_anthropic() -> None:
    try:
        import anthropic

        _orig = anthropic.resources.messages.Messages.create

        def _tracked(self, *args, **kwargs):
            response = _orig(self, *args, **kwargs)
            if hasattr(response, "usage"):
                _track_call(
                    model             = kwargs.get("model", "claude-unknown"),
                    prompt_tokens     = response.usage.input_tokens,
                    completion_tokens = response.usage.output_tokens,
                    provider          = "anthropic",
                )
            return response

        anthropic.resources.messages.Messages.create = _tracked
    except ImportError:
        pass
    except Exception as exc:
        log.debug("Anthropic patch failed: %s", exc)


def _patch_groq() -> None:
    try:
        import groq

        _orig = groq.resources.chat.completions.Completions.create

        def _tracked(self, *args, **kwargs):
            response = _orig(self, *args, **kwargs)
            if hasattr(response, "usage") and response.usage:
                _track_call(
                    model             = kwargs.get("model", "groq-unknown"),
                    prompt_tokens     = response.usage.prompt_tokens,
                    completion_tokens = response.usage.completion_tokens,
                    provider          = "groq",
                )
            return response

        groq.resources.chat.completions.Completions.create = _tracked
    except ImportError:
        pass
    except Exception as exc:
        log.debug("Groq patch failed: %s", exc)


# Patch on import — order doesn't matter
_patch_openai()
_patch_anthropic()
_patch_groq()


# ── Dashboard ─────────────────────────────────────────────────────────────────
_dashboard_client = DashboardClient()


def report(interactive: bool = True) -> None:
    """Show cost and recommendation report."""
    _dashboard_client.report(interactive=interactive)


def track(
    model:             str,
    prompt_tokens:     int,
    completion_tokens: int  = 0,
    provider:          str  = "custom",
    prompt_preview:    str  = "",
) -> dict:
    """Manually track a call."""
    _track_call(model, prompt_tokens, completion_tokens, provider, prompt_preview)
    return {"status": "tracked"}


__all__ = ["report", "track", "__version__", "SESSION_ID", "SERVER_URL"]