# retoor <retoor@molodetz.nl>

from .core import datetime, db, get_table, timezone


def _add_usage(usage_table: str, user_uid: str, totals: dict) -> None:
    if not user_uid or int(totals.get("calls") or 0) <= 0 or usage_table not in db.tables:
        return
    with db:
        db.query(
            f"INSERT INTO {usage_table} "
            "(user_uid, calls, prompt_tokens, completion_tokens, total_tokens, cost_usd, "
            "upstream_latency_ms, total_latency_ms, updated_at) "
            "VALUES (:user_uid, :calls, :prompt, :completion, :total, :cost, :ulat, :tlat, :now) "
            "ON CONFLICT(user_uid) DO UPDATE SET "
            "calls = calls + excluded.calls, "
            "prompt_tokens = prompt_tokens + excluded.prompt_tokens, "
            "completion_tokens = completion_tokens + excluded.completion_tokens, "
            "total_tokens = total_tokens + excluded.total_tokens, "
            "cost_usd = cost_usd + excluded.cost_usd, "
            "upstream_latency_ms = upstream_latency_ms + excluded.upstream_latency_ms, "
            "total_latency_ms = total_latency_ms + excluded.total_latency_ms, "
            "updated_at = excluded.updated_at",
            user_uid=user_uid,
            calls=int(totals.get("calls") or 0),
            prompt=int(totals.get("prompt_tokens") or 0),
            completion=int(totals.get("completion_tokens") or 0),
            total=int(totals.get("total_tokens") or 0),
            cost=float(totals.get("cost_usd") or 0.0),
            ulat=float(totals.get("upstream_latency_ms") or 0.0),
            tlat=float(totals.get("total_latency_ms") or 0.0),
            now=datetime.now(timezone.utc).isoformat(),
        )


def _get_usage(usage_table: str, user_uid: str) -> dict:
    empty = {
        "calls": 0,
        "prompt_tokens": 0,
        "completion_tokens": 0,
        "total_tokens": 0,
        "cost_usd": 0.0,
        "upstream_latency_ms": 0.0,
        "total_latency_ms": 0.0,
        "avg_tokens": 0.0,
        "avg_upstream_latency_ms": 0.0,
        "avg_total_latency_ms": 0.0,
        "avg_tokens_per_second": 0.0,
        "avg_cost_usd": 0.0,
        "updated_at": None,
    }
    if not user_uid or usage_table not in db.tables:
        return empty
    row = get_table(usage_table).find_one(user_uid=user_uid)
    if not row:
        return empty
    calls = int(row.get("calls") or 0)
    completion = int(row.get("completion_tokens") or 0)
    total_tokens = int(row.get("total_tokens") or 0)
    cost = float(row.get("cost_usd") or 0.0)
    upstream_ms = float(row.get("upstream_latency_ms") or 0.0)
    total_ms = float(row.get("total_latency_ms") or 0.0)
    return {
        "calls": calls,
        "prompt_tokens": int(row.get("prompt_tokens") or 0),
        "completion_tokens": completion,
        "total_tokens": total_tokens,
        "cost_usd": cost,
        "upstream_latency_ms": upstream_ms,
        "total_latency_ms": total_ms,
        "avg_tokens": round(total_tokens / calls, 1) if calls else 0.0,
        "avg_upstream_latency_ms": round(upstream_ms / calls, 1) if calls else 0.0,
        "avg_total_latency_ms": round(total_ms / calls, 1) if calls else 0.0,
        "avg_tokens_per_second": round(completion / (upstream_ms / 1000.0), 1)
        if upstream_ms > 0
        else 0.0,
        "avg_cost_usd": (cost / calls) if calls else 0.0,
        "updated_at": row.get("updated_at"),
    }


def add_correction_usage(user_uid: str, totals: dict) -> None:
    _add_usage("correction_usage", user_uid, totals)


def get_correction_usage(user_uid: str) -> dict:
    return _get_usage("correction_usage", user_uid)


def add_modifier_usage(user_uid: str, totals: dict) -> None:
    _add_usage("modifier_usage", user_uid, totals)


def get_modifier_usage(user_uid: str) -> dict:
    return _get_usage("modifier_usage", user_uid)


NEWS_USAGE_KEY = "news"


def add_news_usage(totals: dict) -> None:
    _add_usage("news_usage", NEWS_USAGE_KEY, totals)


def get_news_usage() -> dict:
    return _get_usage("news_usage", NEWS_USAGE_KEY)


ISSUE_USAGE_KEY = "issues"


def add_issue_usage(totals: dict) -> None:
    _add_usage("issue_usage", ISSUE_USAGE_KEY, totals)


def get_issue_usage() -> dict:
    return _get_usage("issue_usage", ISSUE_USAGE_KEY)


SEO_USAGE_KEY = "seo_meta"


def add_seo_usage(totals: dict) -> None:
    _add_usage("seo_usage", SEO_USAGE_KEY, totals)


def get_seo_usage() -> dict:
    return _get_usage("seo_usage", SEO_USAGE_KEY)


AWARD_USAGE_KEY = "award"


def add_award_usage(totals: dict) -> None:
    _add_usage("award_usage", AWARD_USAGE_KEY, totals)


def get_award_usage() -> dict:
    return _get_usage("award_usage", AWARD_USAGE_KEY)
