from __future__ import annotations

import secrets
import time
from dataclasses import dataclass
from threading import RLock
from typing import Optional


DEFAULT_TTL_SECONDS = 60 * 60 * 12  # 12h


@dataclass
class SessionRecord:
    session_id: str
    participant_id: str
    room_id: str
    expires_at: float


class SessionStore:
    def __init__(self, ttl_seconds: int = DEFAULT_TTL_SECONDS):
        self._ttl_seconds = ttl_seconds
        self._records: dict[str, SessionRecord] = {}
        self._lock = RLock()

    def _now(self) -> float:
        return time.time()

    def _purge_expired_locked(self) -> None:
        now = self._now()
        expired = [sid for sid, rec in self._records.items() if rec.expires_at <= now]
        for sid in expired:
            self._records.pop(sid, None)

    def create_or_reuse(
        self,
        room_id: str,
        session_id: Optional[str] = None,
        participant_id: Optional[str] = None,
    ) -> SessionRecord:
        with self._lock:
            self._purge_expired_locked()
            if session_id:
                existing = self._records.get(session_id)
                if existing and existing.room_id == room_id:
                    existing.expires_at = self._now() + self._ttl_seconds
                    self._records[session_id] = existing
                    return existing

            new_session_id = secrets.token_urlsafe(24)
            new_participant_id = participant_id or f"p-{secrets.token_hex(8)}"
            rec = SessionRecord(
                session_id=new_session_id,
                participant_id=new_participant_id,
                room_id=room_id,
                expires_at=self._now() + self._ttl_seconds,
            )
            self._records[new_session_id] = rec
            return rec

    def get(self, session_id: Optional[str]) -> Optional[SessionRecord]:
        if not session_id:
            return None
        with self._lock:
            self._purge_expired_locked()
            rec = self._records.get(session_id)
            if not rec:
                return None
            rec.expires_at = self._now() + self._ttl_seconds
            self._records[session_id] = rec
            return rec


session_store = SessionStore()
