import hmac
import hashlib
import time
from fastapi import HTTPException


def verify_slack_signature(
    signing_secret: str | None, headers: dict, body: bytes
) -> None:
    """Verify Slack request signature for security.

    Raises HTTPException(401) when signature is invalid, stale, or missing.
    """
    if not signing_secret:
        # If not configured, reject to avoid unsafe default
        raise HTTPException(401, "Slack signing secret not configured")

    # Slack sends lowercase header names; FastAPI provides case-insensitive dict
    ts = headers.get("x-slack-request-timestamp") or headers.get(
        "X-Slack-Request-Timestamp"
    )
    sig = headers.get("x-slack-signature") or headers.get("X-Slack-Signature")
    if not ts or not sig:
        raise HTTPException(401, "Missing Slack signature")

    try:
        ts_int = int(ts)
    except Exception:
        raise HTTPException(401, "Invalid Slack timestamp")

    # Reject if older than 5 minutes to prevent replay
    if abs(time.time() - ts_int) > 60 * 5:
        raise HTTPException(401, "Stale Slack request")

    base = f"v0:{ts}:{body.decode('utf-8')}".encode()
    expected = (
        "v0="
        + hmac.new((signing_secret or "").encode(), base, hashlib.sha256).hexdigest()
    )
    if not hmac.compare_digest(expected, str(sig)):
        raise HTTPException(401, "Bad Slack signature")
