import hashlib
import hmac
import json
import time
from datetime import datetime, timedelta, timezone
from urllib.parse import parse_qs, unquote

import jwt


def verify_telegram_login(data: dict, bot_token: str) -> bool:
    """Verify data from Telegram Login Widget."""
    data = dict(data)
    check_hash = data.pop("hash", "")
    if not check_hash:
        return False

    data_check_string = "\n".join(
        f"{k}={v}" for k, v in sorted(data.items())
    )
    secret_key = hashlib.sha256(bot_token.encode()).digest()
    computed = hmac.new(secret_key, data_check_string.encode(), hashlib.sha256).hexdigest()

    if int(data.get("auth_date", 0)) < time.time() - 86400:
        return False

    return hmac.compare_digest(computed, check_hash)


def verify_telegram_webapp(init_data: str, bot_token: str) -> dict | None:
    """Verify Telegram WebApp initData and return parsed user dict."""
    parsed = parse_qs(init_data)
    data = {k: v[0] for k, v in parsed.items()}

    check_hash = data.pop("hash", "")
    if not check_hash:
        return None

    data_check_string = "\n".join(
        f"{k}={v}" for k, v in sorted(data.items())
    )
    secret_key = hmac.new(b"WebAppData", bot_token.encode(), hashlib.sha256).digest()
    computed = hmac.new(secret_key, data_check_string.encode(), hashlib.sha256).hexdigest()

    if not hmac.compare_digest(computed, check_hash):
        return None

    user_raw = data.get("user")
    if not user_raw:
        return None

    return json.loads(unquote(user_raw))


def create_access_token(
    rider_id: str,
    telegram_id: int,
    secret: str,
    algorithm: str,
    expires_minutes: int,
) -> str:
    payload = {
        "sub": rider_id,
        "tg_id": telegram_id,
        "exp": datetime.now(timezone.utc) + timedelta(minutes=expires_minutes),
    }
    return jwt.encode(payload, secret, algorithm=algorithm)


def decode_access_token(token: str, secret: str, algorithm: str) -> dict:
    return jwt.decode(token, secret, algorithms=[algorithm])
