import json
import logging
import uuid
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError
from typing import Optional, Dict, Any

logger = logging.getLogger("payfence")


def authorize(
    api_key: str,
    token: str,
    method: str,
    path: str,
    request_id: Optional[str] = None,
    base_url: str = "https://api.payfence.io",
) -> Dict[str, Any]:
    """Call PayFence authorize endpoint. Returns decision dict."""
    url = f"{base_url.rstrip('/')}/v1/authorize"
    rid = request_id or str(uuid.uuid4())
    payload = json.dumps({
        "token": token,
        "method": method,
        "path": path,
        "requestId": rid,
    }).encode()

    req = Request(url, data=payload, method="POST")
    req.add_header("Content-Type", "application/json")
    req.add_header("Authorization", f"Bearer {api_key}")

    logger.debug("Authorizing: %s %s (requestId=%s)", method, path, rid)

    try:
        with urlopen(req, timeout=10) as resp:
            decision = json.loads(resp.read())
            logger.debug("Allow: %s %s", method, path)
            return decision
    except HTTPError as e:
        decision = json.loads(e.read())
        logger.info("Deny: %s %s — status=%d, reason=%s", method, path, e.code, decision.get("reason"))
        return decision
