"""
stats_reporter.py — собирает метрики использования и отправляет на сервер каждые 5 мин.
"""
import time
import json
import threading
import logging
import urllib.request
import ssl

from config import TELEPUSH_SERVER_URL, TELEPUSH_VERSION, DB_PATH, USERS_DIR, ACCOUNTS_DIR
from utils.hwid import generate_hwid

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

_INTERVAL = 300  # 5 min
_running = False
_thread = None
_start_time = time.time()
_error_count = 0
_counter_lock = threading.Lock()


def _ssl_ctx():
    # Validating SSL context — важно чтобы MITM не подменил ответ сервера
    try:
        return ssl.create_default_context()
    except Exception:
        return None


def _count_accounts():
    """Считаем .session файлов во всех папках аккаунтов."""
    try:
        # Рекурсивно по всей папке Аккаунты/
        count = sum(1 for f in ACCOUNTS_DIR.rglob("*.session"))
        if count == 0:
            # Fallback: USERS_DIR
            count = sum(1 for f in USERS_DIR.glob("*.session"))
        return count
    except Exception:
        return 0


def _query_db():
    """Достаём метрики из quota_events."""
    result = {"chat_sends": 0, "dm_sends": 0, "joins": 0}
    try:
        import sqlite3
        conn = sqlite3.connect(str(DB_PATH), timeout=5)
        conn.row_factory = sqlite3.Row

        # Всего рассылок по чатам (kind='spam')
        row = conn.execute("SELECT COUNT(*) as c FROM quota_events WHERE kind='spam'").fetchone()
        result["chat_sends"] = row["c"] if row else 0

        # chat_targets = уникальные чаты (из payload нет, считаем как chat_sends)
        result["chat_targets"] = result["chat_sends"]

        # DM (kind='spam_user' или 'dm')
        row = conn.execute("SELECT COUNT(*) as c FROM quota_events WHERE kind IN ('spam_user','dm')").fetchone()
        result["dm_sends"] = row["c"] if row else 0
        result["dm_targets"] = result["dm_sends"]

        # Вступлений (kind='join')
        row = conn.execute("SELECT COUNT(*) as c FROM quota_events WHERE kind='join'").fetchone()
        result["joins"] = row["c"] if row else 0

        conn.close()
    except Exception as e:
        logger.debug("stats db query: %s", e)
    return result


def _collect():
    """Собираем все метрики."""
    global _error_count
    db = _query_db()
    return {
        "hwid": generate_hwid(),
        "version": TELEPUSH_VERSION,
        "accounts": _count_accounts(),
        "chat_sends": db["chat_sends"],
        "chat_targets": db.get("chat_targets", 0),
        "dm_sends": db["dm_sends"],
        "dm_targets": db.get("dm_targets", 0),
        "joins": db["joins"],
        "parsed_users": 0,  # обновляется через increment_parsed()
        "parsed_links": 0,
        "uptime_sec": int(time.time() - _start_time),
        "errors": _error_count,
    }


# Counters that modules can increment (thread-safe)
_parsed_users = 0
_parsed_links = 0
_warmup_msgs = 0
_invites_sent = 0


def increment_parsed(users=0, links=0):
    global _parsed_users, _parsed_links
    with _counter_lock:
        _parsed_users += users
        _parsed_links += links


def increment_warmup_msgs(n=1):
    global _warmup_msgs
    with _counter_lock:
        _warmup_msgs += n


def increment_invites(n=1):
    global _invites_sent
    with _counter_lock:
        _invites_sent += n


def increment_errors(n=1):
    global _error_count
    with _counter_lock:
        _error_count += n


def _send(data):
    try:
        body = json.dumps(data).encode()
        req = urllib.request.Request(
            f"{TELEPUSH_SERVER_URL}/api/stats",
            data=body,
            headers={"Content-Type": "application/json", "User-Agent": "TelePush"},
        )
        ctx = _ssl_ctx()
        if ctx:
            urllib.request.urlopen(req, timeout=10, context=ctx)
        else:
            urllib.request.urlopen(req, timeout=10)
    except Exception as e:
        logger.debug("stats send: %s", e)


def _loop():
    global _running
    while _running:
        try:
            data = _collect()
            data["parsed_users"] = _parsed_users
            data["parsed_links"] = _parsed_links
            data["warmup_msgs"] = _warmup_msgs
            data["invites_sent"] = _invites_sent
            _send(data)
        except Exception as e:
            logger.debug("stats loop: %s", e)
        time.sleep(_INTERVAL)


def start():
    """Запустить фоновый поток отправки статистики."""
    global _running, _thread, _start_time
    if _running:
        return
    _start_time = time.time()
    _running = True
    _thread = threading.Thread(target=_loop, daemon=True, name="stats-reporter")
    _thread.start()
    logger.info("Stats reporter started (every %ds)", _INTERVAL)


def stop():
    global _running
    _running = False
