"""Telegram WebApp initData verification (HMAC-SHA-256)."""
from __future__ import annotations
import hmac
import hashlib
import json
import time
from typing import Any
from urllib.parse import parse_qsl


def verify_init_data(init_data: str, bot_token: str, max_age_sec: int = 86400) -> dict[str, Any] | None:
    """
    Проверяет подпись initData от Telegram WebApp.
    Возвращает распарсенные данные с ключом 'user' (dict) или None при невалидной/просроченной подписи.

    Спецификация: https://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-app
    """
    if not init_data:
        return None
    parsed = dict(parse_qsl(init_data, keep_blank_values=True))
    received_hash = parsed.pop("hash", None)
    if not received_hash:
        return None

    # data_check_string: ключ=значение, отсортированы алфавитно, разделитель \n
    data_check_string = "\n".join(f"{k}={parsed[k]}" for k in sorted(parsed))

    # secret_key = HMAC-SHA-256(key="WebAppData", data=BOT_TOKEN)
    secret_key = hmac.new(b"WebAppData", bot_token.strip().encode(), hashlib.sha256).digest()
    expected_hash = hmac.new(secret_key, data_check_string.encode(), hashlib.sha256).hexdigest()

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

    # Свежесть подписи (24 часа по умолчанию)
    auth_date = int(parsed.get("auth_date", "0"))
    if time.time() - auth_date > max_age_sec:
        return None

    user = None
    if "user" in parsed:
        try:
            user = json.loads(parsed["user"])
        except json.JSONDecodeError:
            user = None

    return {
        "user": user,
        "auth_date": auth_date,
        "start_param": parsed.get("start_param"),
        "chat_instance": parsed.get("chat_instance"),
    }
