"""
Telegram Mini App — валидация initData.

Telegram передаёт подписанные данные при открытии WebApp.
Мы проверяем HMAC-SHA256 подпись через BOT_TOKEN,
чтобы убедиться что запрос пришёл от реального пользователя.

Документация: https://core.telegram.org/bots/webapps#validating-data
"""

import hashlib
import hmac
import json
import os
import time
from urllib.parse import parse_qs

BOT_TOKEN = os.getenv("BOT_TOKEN", "")


def validate_init_data(init_data: str, max_age_seconds: int = 86400) -> dict | None:
    """
    Валидирует initData из Telegram WebApp.

    Возвращает dict с данными пользователя при успехе, None при ошибке.
    """
    if not init_data or not BOT_TOKEN:
        return None

    try:
        parsed = parse_qs(init_data, keep_blank_values=True)

        # Извлекаем hash
        received_hash = parsed.get("hash", [None])[0]
        if not received_hash:
            return None

        # Собираем data-check-string (все поля кроме hash, отсортированные)
        data_pairs = []
        for key, values in parsed.items():
            if key == "hash":
                continue
            data_pairs.append(f"{key}={values[0]}")
        data_pairs.sort()
        data_check_string = "\n".join(data_pairs)

        # Вычисляем секретный ключ
        secret_key = hmac.new(
            b"WebAppData", BOT_TOKEN.encode("utf-8"), hashlib.sha256
        ).digest()

        # Вычисляем HMAC
        computed_hash = hmac.new(
            secret_key, data_check_string.encode("utf-8"), hashlib.sha256
        ).hexdigest()

        if not hmac.compare_digest(computed_hash, received_hash):
            return None

        # Проверяем auth_date (не старше max_age_seconds)
        auth_date_str = parsed.get("auth_date", [None])[0]
        if auth_date_str:
            auth_date = int(auth_date_str)
            if time.time() - auth_date > max_age_seconds:
                return None

        # Парсим user
        user_str = parsed.get("user", [None])[0]
        if not user_str:
            return None

        user_data = json.loads(user_str)
        return {
            "user_id": user_data.get("id"),
            "first_name": user_data.get("first_name", ""),
            "last_name": user_data.get("last_name", ""),
            "username": user_data.get("username", ""),
            "language_code": user_data.get("language_code", "ru"),
        }

    except Exception:
        return None
