"""Cost estimation and token counting — single source of truth.

Extracted from engine.py to unify all pricing/cost logic in one place.
Used by engine, slash commands, usage tracking, and API responses.
"""

from __future__ import annotations

from typing import Dict


def estimate_tokens(text: str) -> int:
    """Estimate tokens: Korean /2, English /4, mixed weighted."""
    if not text:
        return 0
    kr_chars = sum(1 for c in text if "\uac00" <= c <= "\ud7a3" or "\u3131" <= c <= "\u318e")
    kr_ratio = kr_chars / max(len(text), 1)
    if kr_ratio > 0.3:
        # Korean: ~1 token per character (CJK tokenizers split per char)
        return max(1, int(kr_chars + (len(text) - kr_chars) / 4))
    elif kr_ratio < 0.05:
        return int(len(text) / 4)
    return int(len(text) / 3)


# Model pricing (USD per 1M tokens)
# Last updated: 2026-02-21 — verify at provider pricing pages
PRICING_VERSION = "2026-02-21"
MODEL_PRICING: Dict[str, dict] = {
    "claude-opus-4": {"input": 15.0, "output": 75.0, "cache_read": 1.5, "cache_write": 18.75},
    "claude-sonnet-4": {"input": 3.0, "output": 15.0, "cache_read": 0.3, "cache_write": 3.75},
    "claude-haiku-4-5": {"input": 1.0, "output": 5.0, "cache_read": 0.1, "cache_write": 1.25},
    "gemini-2.5-pro": {"input": 1.25, "output": 10.0, "cache_read": 0.315, "cache_write": 1.25},
    "gemini-2.5-flash": {"input": 0.15, "output": 0.60, "cache_read": 0.0375, "cache_write": 0.15},
    "gemini-2.0-flash": {"input": 0.10, "output": 0.40, "cache_read": 0.025, "cache_write": 0.10},
    "gemini-3-pro": {"input": 1.25, "output": 10.0, "cache_read": 0.315, "cache_write": 1.25},
    "gemini-3-flash": {"input": 0.15, "output": 0.60, "cache_read": 0.0375, "cache_write": 0.15},
    "grok-4": {"input": 3.0, "output": 15.0, "cache_read": 0.3, "cache_write": 3.75},
    "grok-3": {"input": 3.0, "output": 15.0, "cache_read": 0.3, "cache_write": 3.75},
    "grok-3-mini": {"input": 0.30, "output": 0.50, "cache_read": 0.03, "cache_write": 0.375},
}


def get_pricing(model: str) -> dict:
    """Get pricing for a model string (fuzzy match)."""
    m = model.lower().replace("-", "").replace("/", "")
    for key, pricing in MODEL_PRICING.items():
        if key.replace("-", "") in m:
            return pricing
    if "gemini" in m:
        if "pro" in m:
            return MODEL_PRICING["gemini-2.5-pro"]
        return MODEL_PRICING["gemini-2.5-flash"]
    return MODEL_PRICING["claude-sonnet-4"]


def estimate_cost(model: str, usage: dict) -> float:
    """Estimate cost in USD from usage dict."""
    pricing = get_pricing(model)
    inp = usage.get("input", 0)
    out = usage.get("output", 0)
    cache_write = usage.get("cache_creation_input_tokens", 0)
    cache_read = usage.get("cache_read_input_tokens", 0)
    regular_input = max(0, inp - cache_write - cache_read)
    return (
        regular_input * pricing["input"] / 1_000_000
        + out * pricing["output"] / 1_000_000
        + cache_write * pricing["cache_write"] / 1_000_000
        + cache_read * pricing["cache_read"] / 1_000_000
    )
