"""
Token Repository

Handles admin token operations following Single Responsibility Principle.
"""

import logging
from datetime import datetime

from backend.data.admin_models import AdminToken
from backend.data.repositories.base import BaseRepository

logger = logging.getLogger(__name__)


class TokenRepository(BaseRepository[AdminToken]):
    """Repository for admin token management.

    Handles:
    - Token validation (active status, expiration)
    - Token CRUD operations
    - Usage tracking
    """

    def is_valid(self, token: str) -> bool:
        """Check if admin token exists and is active.

        Args:
            token: The token string to validate

        Returns:
            True if token exists, is active, and not expired
        """
        with self._session() as session:
            result = session.get(AdminToken, token)
            if result is None:
                return False
            if not result.is_active:
                return False
            if result.expires_at and result.expires_at < self._now():
                return False
            return True

    def get(self, token: str) -> AdminToken | None:
        """Get admin token details.

        Args:
            token: The token string

        Returns:
            AdminToken if found, None otherwise
        """
        with self._session() as session:
            result = session.get(AdminToken, token)
            if result:
                session.expunge(result)
            return result

    def create(
        self,
        token: str,
        name: str,
        expires_at: datetime | None = None,
    ) -> None:
        """Create or update an admin token.

        If token exists, updates name, expires_at, and reactivates it.
        Otherwise creates a new token.

        Args:
            token: The token string
            name: Display name for the token
            expires_at: Optional expiration datetime
        """
        with self._session() as session:
            existing = session.get(AdminToken, token)
            if existing:
                existing.name = name
                existing.expires_at = expires_at
                existing.is_active = True
                session.add(existing)
            else:
                new_token = AdminToken(
                    token=token,
                    name=name,
                    expires_at=expires_at,
                )
                session.add(new_token)

    def update_usage(self, token: str) -> None:
        """Update admin token last used timestamp.

        Args:
            token: The token string
        """
        with self._session() as session:
            admin_token = session.get(AdminToken, token)
            if admin_token:
                admin_token.last_used_at = self._now()
                session.add(admin_token)

    def deactivate(self, token: str) -> bool:
        """Deactivate an admin token.

        Args:
            token: The token string

        Returns:
            True if token was deactivated, False if not found
        """
        with self._session() as session:
            admin_token = session.get(AdminToken, token)
            if admin_token:
                admin_token.is_active = False
                session.add(admin_token)
                return True
            return False
