"""
warmup_ai.py -- Gemini API wrapper for warmup message generation.
Free tier: gemini-2.5-flash, 10 RPM, 250 req/day.
Uses raw requests (no extra dependencies).
"""
import json
import time
import logging
import asyncio
from pathlib import Path
from typing import Optional, List

logger = logging.getLogger("telepush.warmup_ai")

GEMINI_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent"

# Rate limiter state
_last_requests: List[float] = []
_MAX_RPM = 8  # safe margin under 10 RPM limit
_daily_count = 0
_daily_reset_at = 0.0
_MAX_DAILY = 240  # safe margin under 250

# Cache
_msg_cache: List[str] = []
_CACHE_FILE = None


def _get_cache_file() -> Path:
    global _CACHE_FILE
    if _CACHE_FILE is None:
        from config import DATA_DIR
        _CACHE_FILE = DATA_DIR / "warmup_msg_cache.json"
    return _CACHE_FILE


def _load_cache() -> List[str]:
    global _msg_cache
    try:
        p = _get_cache_file()
        if p.exists():
            _msg_cache = json.loads(p.read_text(encoding="utf-8"))
    except Exception:
        _msg_cache = []
    return _msg_cache


def _save_cache():
    try:
        p = _get_cache_file()
        p.parent.mkdir(parents=True, exist_ok=True)
        # Keep last 500 messages
        trimmed = _msg_cache[-500:] if len(_msg_cache) > 500 else _msg_cache
        p.write_text(json.dumps(trimmed, ensure_ascii=False), encoding="utf-8")
    except Exception:
        pass


def _can_request() -> bool:
    """Check rate limits."""
    global _daily_count, _daily_reset_at
    now = time.time()

    # Daily reset
    if now - _daily_reset_at > 86400:
        _daily_count = 0
        _daily_reset_at = now

    if _daily_count >= _MAX_DAILY:
        return False

    # RPM check
    cutoff = now - 60
    recent = [t for t in _last_requests if t > cutoff]
    return len(recent) < _MAX_RPM


def _record_request():
    global _daily_count
    _last_requests.append(time.time())
    _daily_count += 1
    # Trim old entries
    cutoff = time.time() - 120
    while _last_requests and _last_requests[0] < cutoff:
        _last_requests.pop(0)


async def _gemini_request(prompt: str, api_key: str) -> Optional[str]:
    """Make async HTTP request to Gemini API."""
    import requests as req

    headers = {
        "Content-Type": "application/json",
        "x-goog-api-key": api_key,
    }
    payload = {
        "contents": [{"parts": [{"text": prompt}]}],
        "generationConfig": {
            "maxOutputTokens": 100,
            "temperature": 0.9,
        },
    }

    try:
        loop = asyncio.get_event_loop()
        resp = await loop.run_in_executor(
            None,
            lambda: req.post(GEMINI_URL, json=payload, headers=headers, timeout=15),
        )
        if resp.status_code != 200:
            logger.debug("[warmup_ai] Gemini %d: %s", resp.status_code, resp.text[:200])
            return None

        data = resp.json()
        text = data["candidates"][0]["content"]["parts"][0]["text"]
        return text.strip()
    except Exception as e:
        logger.debug("[warmup_ai] Gemini error: %s", e)
        return None


def _validate_response(text: str, blacklist: List[str]) -> bool:
    """Check that generated text doesn't contain trigger words."""
    low = text.lower()
    for word in blacklist:
        if word.lower() in low:
            return False
    return True


async def generate_warmup_reply(
    context: str,
    topic: str,
    blacklist: List[str],
    api_key: str,
    lang: str = "ru",
) -> Optional[str]:
    """Generate a warmup reply via Gemini. Returns None if unavailable."""
    if not api_key or not api_key.strip():
        return None

    if not _can_request():
        logger.debug("[warmup_ai] Rate limit reached, using cache/templates")
        return _get_cached_message(blacklist)

    blacklist_csv = ", ".join(blacklist[:30])
    prompt = (
        f"Ты участник дружеского чата в Telegram. "
        f"Напиши одну короткую (1-2 предложения) casual реплику на тему \"{topic}\". "
        f"Контекст: {context}\n"
        f"ЗАПРЕЩЕНО использовать слова: {blacklist_csv}.\n"
        f"Пиши как обычный человек, без формальностей, можно сленг и эмодзи. "
        f"Не предлагай работу, деньги, услуги. Просто дружеский разговор. "
        f"Ответь ТОЛЬКО текстом реплики, без кавычек и пояснений."
    )

    _record_request()
    text = await _gemini_request(prompt, api_key)

    if text and _validate_response(text, blacklist):
        # Clean up: remove quotes if Gemini wraps them
        text = text.strip('"\'«»')
        # Cache good messages
        if text not in _msg_cache:
            _msg_cache.append(text)
            if len(_msg_cache) % 20 == 0:
                _save_cache()
        return text

    # Retry once if triggers found
    if text:
        logger.debug("[warmup_ai] Trigger found in response, retrying")
        _record_request()
        text2 = await _gemini_request(prompt + "\nВАЖНО: не используй запрещённые слова!", api_key)
        if text2 and _validate_response(text2, blacklist):
            text2 = text2.strip('"\'«»')
            _msg_cache.append(text2)
            return text2

    return _get_cached_message(blacklist)


def _get_cached_message(blacklist: List[str]) -> Optional[str]:
    """Return a random cached message that passes blacklist."""
    if not _msg_cache:
        _load_cache()
    if not _msg_cache:
        return None

    import random
    candidates = [m for m in _msg_cache if _validate_response(m, blacklist)]
    return random.choice(candidates) if candidates else None


async def check_gemini_key(api_key: str) -> dict:
    """Verify API key works. Returns {ok: bool, error: str}."""
    if not api_key:
        return {"ok": False, "error": "Ключ не указан"}
    try:
        text = await _gemini_request("Скажи 'привет' одним словом.", api_key)
        if text:
            return {"ok": True, "error": ""}
        return {"ok": False, "error": "Пустой ответ от API"}
    except Exception as e:
        return {"ok": False, "error": str(e)}


def get_ai_stats() -> dict:
    """Return current AI usage stats."""
    return {
        "daily_used": _daily_count,
        "daily_limit": _MAX_DAILY,
        "cache_size": len(_msg_cache),
        "rpm_used": len([t for t in _last_requests if t > time.time() - 60]),
        "rpm_limit": _MAX_RPM,
    }
