import json
import os
import urllib.error
import urllib.request
from typing import Optional


DEFAULT_USERNAME = "+79214400842"
DEFAULT_PASSWORD = "stepan"
DEFAULT_GRANT_TYPE = "password"


def get_access_token(
    auth_url: Optional[str] = None,
    *,
    username: str = DEFAULT_USERNAME,
    password: str = DEFAULT_PASSWORD,
    grant_type: str = DEFAULT_GRANT_TYPE,
    timeout_s: int = 30,
) -> str:
    """
    POST авторизация, возвращает access_token.

    Можно переопределить AUTH_URL через env.
    """
    auth_url = auth_url or os.getenv("AUTH_URL") or "https://auth.dev.dipal.ru/api/v1/auth/login"
    if not auth_url:
        raise ValueError("Не задан AUTH_URL (передайте auth_url или установите env AUTH_URL)")

    # Поддерживаем env-переопределение кредов, чтобы не хардкодить их в тестах.
    username = os.getenv("AUTH_USERNAME", username)
    password = os.getenv("AUTH_PASSWORD", password)
    grant_type = os.getenv("AUTH_GRANT_TYPE", grant_type)

    payload = {"username": username, "password": password, "grant_type": grant_type}
    req = urllib.request.Request(
        auth_url,
        data=json.dumps(payload).encode("utf-8"),
        headers={"content-type": "application/json"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=timeout_s) as resp:
            raw = resp.read().decode("utf-8")
    except urllib.error.HTTPError as e:
        body = e.read().decode("utf-8", errors="replace")
        raise RuntimeError(f"Auth HTTP {e.code}: {body}") from e

    data = json.loads(raw) if raw else {}
    if "data" in data and isinstance(data["data"], dict):
        token = data["data"].get("access_token")
    else:
        token = data.get("access_token")
    if not token:
        raise ValueError(f"В ответе нет access_token. Ключи ответа: {list(data.keys())}")
    return token


if __name__ == "__main__":
    print(get_access_token())

