"""Storage ingest job persistence."""
from __future__ import annotations

from uuid import UUID

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

from src.domain.storage_ingest.models import StorageIngestJob, StorageIngestJobStatus


class StorageIngestJobRepository:
    def __init__(self, db: AsyncSession) -> None:
        self._db = db

    async def create(self, row: StorageIngestJob) -> StorageIngestJob:
        self._db.add(row)
        await self._db.flush()
        return row

    async def get(self, job_id: UUID) -> StorageIngestJob | None:
        return await self._db.get(StorageIngestJob, job_id)

    async def get_for_project(self, job_id: UUID, project_id: UUID) -> StorageIngestJob | None:
        result = await self._db.execute(
            select(StorageIngestJob).where(
                StorageIngestJob.id == job_id,
                StorageIngestJob.project_id == project_id,
            )
        )
        return result.scalar_one_or_none()

    async def save(self, row: StorageIngestJob) -> StorageIngestJob:
        await self._db.flush()
        return row

    async def try_claim_pending(self, job_id: UUID) -> bool:
        """Atomically move pending/failed → running; returns False if another runner claimed it."""
        result = await self._db.execute(
            update(StorageIngestJob)
            .where(
                StorageIngestJob.id == job_id,
                StorageIngestJob.status.in_(
                    (
                        StorageIngestJobStatus.PENDING.value,
                        StorageIngestJobStatus.FAILED.value,
                    )
                ),
            )
            .values(status=StorageIngestJobStatus.RUNNING.value, error=None)
            .returning(StorageIngestJob.id)
        )
        return result.scalar_one_or_none() is not None
