"""Redis-backed token store for MFA flows (login-totp, totp-recovery)."""
from __future__ import annotations
import json
from typing import Any, Optional

from redis import asyncio as aioredis


class RedisTokenStore:
    """Store short-lived tokens in Redis (InTalk-style)."""

    PREFIX_LOGIN_TOTP = "login-totp"
    PREFIX_TOTP_RECOVERY = "totp-recovery"
    PREFIX_TOTP_RECOVERY_CODE = "totp-recovery-code"

    def __init__(self, redis: aioredis.Redis):
        self._redis = redis

    def _key(self, prefix: str, token: str) -> str:
        return f"p2hs:{prefix}:{token}"

    async def store_token(
        self,
        prefix: str,
        token: str,
        payload: dict[str, Any],
        ttl_seconds: int,
    ) -> None:
        await self._redis.setex(
            self._key(prefix, token),
            ttl_seconds,
            json.dumps(payload),
        )

    async def get_token(self, prefix: str, token: str) -> Optional[dict[str, Any]]:
        data = await self._redis.get(self._key(prefix, token))
        return json.loads(data) if data else None

    async def pop_token(self, prefix: str, token: str) -> Optional[dict[str, Any]]:
        key = self._key(prefix, token)
        pipe = self._redis.pipeline()
        pipe.get(key)
        pipe.delete(key)
        data, _ = await pipe.execute()
        return json.loads(data) if data else None
