"""integrations domain — data access layer."""
from __future__ import annotations

from typing import Optional
from uuid import UUID, uuid4

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

from src.domain.integrations.models import ProjectIntegration


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

    async def list_for_project(self, project_id: UUID) -> list[ProjectIntegration]:
        result = await self._db.execute(
            select(ProjectIntegration)
            .where(ProjectIntegration.project_id == project_id)
            .order_by(ProjectIntegration.provider)
        )
        return list(result.scalars().all())

    async def get_by_provider(
        self, project_id: UUID, provider: str
    ) -> Optional[ProjectIntegration]:
        result = await self._db.execute(
            select(ProjectIntegration).where(
                ProjectIntegration.project_id == project_id,
                ProjectIntegration.provider == provider,
            )
        )
        return result.scalar_one_or_none()

    async def upsert(
        self,
        project_id: UUID,
        provider: str,
        **fields,
    ) -> ProjectIntegration:
        row = await self.get_by_provider(project_id, provider)
        if row:
            for k, v in fields.items():
                setattr(row, k, v)
        else:
            row = ProjectIntegration(
                id=uuid4(),
                project_id=project_id,
                provider=provider,
                **fields,
            )
            self._db.add(row)
        await self._db.flush()
        return row

    async def update(self, row: ProjectIntegration, **fields) -> ProjectIntegration:
        for k, v in fields.items():
            setattr(row, k, v)
        await self._db.flush()
        return row
