from __future__ import annotations

from datetime import datetime, timedelta, timezone
from typing import Any

import jwt
from jwt import PyJWTError

from app.core.settings import get_settings

def utcnow() -> datetime:
    return datetime.now(timezone.utc)

def encode_access_token(payload: dict[str, Any], expires_minutes: int) -> str:
    s = get_settings()
    now = utcnow()
    exp = now + timedelta(minutes=expires_minutes)
    token_payload = {
        **payload,
        "iss": s.JWT_ISSUER,
        "aud": s.JWT_AUDIENCE,
        "iat": int(now.timestamp()),
        "exp": int(exp.timestamp()),
        "typ": "access",
    }
    return jwt.encode(token_payload, s.SECRET_KEY, algorithm="HS256")

def decode_token(token: str) -> dict[str, Any]:
    s = get_settings()
    try:
        data = jwt.decode(
            token,
            s.SECRET_KEY,
            algorithms=["HS256"],
            audience=s.JWT_AUDIENCE,
            issuer=s.JWT_ISSUER,
            options={"require": ["exp", "iat", "iss", "aud"]},
        )
        return data
    except PyJWTError as e:
        raise PermissionError("Invalid token") from e
