"""Cambia la contrasena de un usuario en la API de administracion de Popelis."""

import json
import urllib.error
import urllib.request


def popelis_set_password(
    base_url: str,
    admin_token: str,
    username: str,
    password: str,
    timeout: float = 30.0,
) -> dict:
    """Cambia la contrasena de un usuario existente en Popelis.

    Hace POST a {base_url}/api/admin/users/password con el token de admin,
    el nombre de usuario y la nueva contrasena. Devuelve 404 si el usuario
    no existe.

    Args:
        base_url: URL base del servicio, sin trailing slash.
                  Ej: "https://popelis.datardos.com"
        admin_token: Token de administracion (cabecera X-Admin-Token).
                     Mantenerlo en secreto — no logear.
        username: Nombre de usuario cuya contrasena se quiere cambiar.
        password: Nueva contrasena a establecer.
        timeout: Timeout en segundos para la peticion HTTP. Default 30.0.

    Returns:
        Dict con el resultado: {"status": "password updated"}

    Raises:
        ValueError: Si el servidor devuelve 4xx o 5xx (incluyendo 404 cuando
                    el usuario no existe). El mensaje incluye el status code
                    y el campo "error" del body JSON si existe.
        urllib.error.URLError: Si no se puede conectar al servidor.
    """
    url = f"{base_url.rstrip('/')}/api/admin/users/password"
    payload = json.dumps({"username": username, "password": password}).encode("utf-8")
    req = urllib.request.Request(
        url,
        data=payload,
        headers={
            "Content-Type": "application/json",
            "X-Admin-Token": admin_token,
        },
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=timeout) as resp:
            body = resp.read()
            return json.loads(body)
    except urllib.error.HTTPError as exc:
        raw = exc.read()
        try:
            detail = json.loads(raw).get("error", raw.decode("utf-8", errors="replace"))
        except Exception:
            detail = raw.decode("utf-8", errors="replace")
        if exc.code == 404:
            raise ValueError(
                f"popelis_set_password: usuario '{username}' no existe (HTTP 404) — {detail}"
            ) from exc
        raise ValueError(
            f"popelis_set_password: HTTP {exc.code} — {detail}"
        ) from exc
