import hashlib
import hmac
import secrets
import time
import os
from typing import Optional

from fastapi import Header, HTTPException

_SESSION_SECRET: str = os.getenv("SESSION_SECRET") or secrets.token_hex(32)
_TOKEN_TTL_SECONDS: int = 86_400  # 24 hours


def create_token(username: str) -> str:
    timestamp = str(int(time.time()))
    payload = f"{username}|{timestamp}"
    mac = hmac.new(_SESSION_SECRET.encode(), payload.encode(), hashlib.sha256)
    return f"{payload}|{mac.hexdigest()}"


def verify_token(token: str) -> Optional[str]:
    """Returns username if token is valid and unexpired, else None."""
    try:
        parts = token.split("|")
        if len(parts) != 3:
            return None
        username, timestamp_str, signature = parts
        payload = f"{username}|{timestamp_str}"
        expected = hmac.new(_SESSION_SECRET.encode(), payload.encode(), hashlib.sha256).hexdigest()
        if not hmac.compare_digest(signature, expected):
            return None
        if int(time.time()) - int(timestamp_str) > _TOKEN_TTL_SECONDS:
            return None
        return username
    except Exception:
        return None


def require_auth(authorization: Optional[str] = Header(None)) -> str:
    if not authorization or not authorization.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Authentication required")
    username = verify_token(authorization[7:])
    if username is None:
        raise HTTPException(status_code=401, detail="Invalid or expired token")
    return username
