from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, delete, and_
from models.refresh_token import RefreshToken
from datetime import datetime, timezone
import uuid

class RefreshTokenRepository:
    def __init__(self, db: AsyncSession):
        self.db = db

    async def create(self, user_id: str, token_hash: str, expires_at: datetime, user_agent: str = None, ip_address: str = None) -> RefreshToken:
        token = RefreshToken(
            id=str(uuid.uuid4()),
            user_id=user_id,
            token_hash=token_hash,
            expires_at=expires_at,
            user_agent=user_agent,
            ip_address=ip_address
        )
        self.db.add(token)
        await self.db.commit()
        await self.db.refresh(token)
        return token

    async def get_by_hash(self, token_hash: str) -> RefreshToken | None:
        result = await self.db.execute(select(RefreshToken).where(RefreshToken.token_hash == token_hash))
        return result.scalar_one_or_none()

    async def revoke(self, token_id: str):
        token = await self.db.get(RefreshToken, token_id)
        if token:
            token.revoked_at = datetime.now(timezone.utc)
            await self.db.commit()

    async def revoke_all_for_user(self, user_id: str):
        await self.db.execute(
            delete(RefreshToken).where(
                and_(RefreshToken.user_id == user_id, RefreshToken.revoked_at.is_(None))
            )
        )
        await self.db.commit()
