"""Per-account rate limiter на мутации через MCP (канон mcp.md: чувствительные
операции). Token bucket в памяти процесса; после рестарт окно чистое — для
защиты от спама агента хватает (Telegram сам флудит глубже).

Ключ — account_id: у каждого аккаунта свой Telegram-флуд, лимит честнее
per-user. Плюс отдельное окно — на выдачу кодов логина (login_flow сам).
"""

import time
from collections import defaultdict, deque

_windows: dict[int, deque] = defaultdict(deque)


def check_write(account_id: int, limit_n: int, window_s: float) -> dict | None:
    """None — проход; dict — {"error": 429, "detail": …} для возврата как данных."""
    now = time.monotonic()
    win = _windows[account_id]
    while win and now - win[0] > window_s:
        win.popleft()
    if len(win) >= limit_n:
        retry = int(window_s - (now - win[0])) + 1
        return {"error": 429, "detail": f"rate limit: {limit_n} writes / {int(window_s)}s per account, retry in ~{retry}s"}
    win.append(now)
    return None