"""Authentication service for API key validation."""

import hashlib
from datetime import datetime, timezone
from uuid import UUID

import structlog
from sqlalchemy import select, update
from sqlalchemy.ext.asyncio import AsyncSession

from src.db.models import ApiKey

logger = structlog.get_logger(__name__)


def hash_api_key(key: str) -> str:
    """Hash an API key using SHA-256.

    Args:
        key: The plaintext API key.

    Returns:
        The SHA-256 hex digest of the key.
    """
    return hashlib.sha256(key.encode("utf-8")).hexdigest()


async def validate_api_key(key: str, session: AsyncSession) -> ApiKey | None:
    """Validate an API key and return the corresponding model.

    Args:
        key: The plaintext API key from the request.
        session: Async database session.

    Returns:
        The ApiKey model if valid and active, None otherwise.
    """
    key_hash = hash_api_key(key)

    result = await session.execute(
        select(ApiKey).where(
            ApiKey.key_hash == key_hash,
            ApiKey.is_active == True,  # noqa: E712
        )
    )

    api_key = result.scalar_one_or_none()

    if api_key:
        logger.debug(
            "api_key_validated",
            api_key_id=str(api_key.id),
            name=api_key.name,
        )
    else:
        logger.debug("api_key_invalid", key_hash_prefix=key_hash[:8])

    return api_key


async def update_last_used(api_key_id: UUID, session: AsyncSession) -> None:
    """Update the last_used_at timestamp for an API key.

    Args:
        api_key_id: The UUID of the API key.
        session: Async database session.
    """
    await session.execute(
        update(ApiKey)
        .where(ApiKey.id == api_key_id)
        .values(last_used_at=datetime.now(timezone.utc))
    )
    await session.commit()

    logger.debug("api_key_last_used_updated", api_key_id=str(api_key_id))
