"""API keys domain - data access layer."""
from __future__ import annotations

import secrets
from datetime import UTC, datetime
from uuid import UUID

from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from src.core.security.hashing import hash_token
from src.domain.api_keys.models import ApiKey


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

    async def create(
        self,
        workspace_id: UUID,
        name: str,
        permissions: list[str] | None = None,
        created_by: UUID | None = None,
    ) -> tuple[ApiKey, str]:
        raw_key = "p2hs_" + secrets.token_urlsafe(32)
        key_hash = hash_token(raw_key)
        key_prefix = raw_key[:12]

        ak = ApiKey(
            workspace_id=workspace_id,
            name=name,
            key_hash=key_hash,
            key_prefix=key_prefix,
            permissions=permissions,
            created_by=created_by,
        )
        self._db.add(ak)
        await self._db.flush()
        await self._db.refresh(ak)
        return ak, raw_key

    async def list_for_workspace(self, workspace_id: UUID) -> list[ApiKey]:
        result = await self._db.execute(
            select(ApiKey)
            .where(ApiKey.workspace_id == workspace_id)
            .where(ApiKey.revoked_at.is_(None))
            .order_by(ApiKey.created_at.desc())
        )
        return list(result.scalars().all())

    async def revoke(self, key_id: UUID, workspace_id: UUID) -> bool:
        result = await self._db.execute(
            select(ApiKey).where(ApiKey.id == key_id, ApiKey.workspace_id == workspace_id)
            .with_for_update()
        )
        ak = result.scalar_one_or_none()
        if not ak:
            return False
        if ak.revoked_at is None:
            ak.revoked_at = datetime.now(UTC)
            await self._db.flush()
        return True
