"""Token issuance and verification helpers for Takumi API keys."""

from __future__ import annotations

import base64
import hashlib
import hmac
import os
from dataclasses import dataclass

from argon2 import PasswordHasher

_PH = PasswordHasher(time_cost=3, memory_cost=64_000, parallelism=2)


@dataclass(frozen=True)
class IssuedKey:
    """Material returned when issuing a new API key."""

    token: str
    kid: str
    preview: str
    key_hash: str
    lookup_hmac: bytes


def _base32_token(length: int) -> str:
    raw = base64.b32encode(os.urandom(length)).decode("ascii")
    return raw.rstrip("=").lower()


def _base62_token(length: int) -> str:
    alphabet = b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    raw = os.urandom(length)
    return "".join(chr(alphabet[b % len(alphabet)]) for b in raw)


def issue_token(pepper: str, key_prefix: str) -> IssuedKey:
    """Generate a new opaque token and derived material for storage."""

    kid = _base32_token(8)[:12]
    secret = _base62_token(32)
    token = f"{key_prefix}_{kid}_{secret}"
    key_hash = _PH.hash(token)
    lookup_hmac = hmac.new(pepper.encode(), token.encode(), hashlib.sha256).digest()
    preview = f"{secret[:4]}…{secret[-4:]}"
    return IssuedKey(
        token=token, kid=kid, preview=preview, key_hash=key_hash, lookup_hmac=lookup_hmac
    )


def verify_token(token: str, stored_hash: str) -> bool:
    """Return True when the token matches the stored Argon2 hash."""

    from argon2.exceptions import VerifyMismatchError

    try:
        return _PH.verify(stored_hash, token)
    except VerifyMismatchError:
        return False


def lookup_digest(token: str, pepper: str) -> bytes:
    """Return the HMAC digest used for fallback token lookups."""

    return hmac.new(pepper.encode(), token.encode(), hashlib.sha256).digest()
