"""
Repository for radiologist per-report commission ledger entries.
"""

from uuid import UUID

from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload

from app.models.referral import RadiologistCommission


class RadiologistCommissionRepository:
    """Data access for the radiologist commission ledger."""

    async def create(self, db: AsyncSession, entry: RadiologistCommission) -> RadiologistCommission:
        """Persist an immutable commission ledger entry."""
        db.add(entry)
        await db.flush()
        await db.refresh(entry)
        return entry

    async def get_by_report_id(self, db: AsyncSession, report_id: UUID) -> RadiologistCommission | None:
        """Fetch existing entry for a report to ensure idempotency."""
        stmt = (
            select(RadiologistCommission)
            .where(RadiologistCommission.report_id == report_id)
            .options(
                selectinload(RadiologistCommission.radiologist),
                selectinload(RadiologistCommission.order),
            )
        )
        res = await db.execute(stmt)
        return res.scalar_one_or_none()

    async def get_by_id(
        self,
        db: AsyncSession,
        entry_id: UUID,
        lab_id: UUID | None = None,
    ) -> RadiologistCommission | None:
        """Fetch commission entry by ID with relationships eager-loaded."""
        stmt = (
            select(RadiologistCommission)
            .where(RadiologistCommission.id == entry_id)
            .options(
                selectinload(RadiologistCommission.radiologist),
                selectinload(RadiologistCommission.order),
            )
        )
        if lab_id:
            stmt = stmt.where(RadiologistCommission.lab_id == lab_id)
        res = await db.execute(stmt)
        return res.scalar_one_or_none()

    async def list_commissions(
        self,
        db: AsyncSession,
        lab_id: UUID,
        radiologist_id: UUID | None = None,
        is_settled: bool | None = None,
        offset: int = 0,
        limit: int = 50,
    ) -> tuple[list[RadiologistCommission], int]:
        """List paginated ledger entries with optional radiologist/status filter."""
        stmt = (
            select(RadiologistCommission)
            .where(RadiologistCommission.lab_id == lab_id)
            .options(
                selectinload(RadiologistCommission.radiologist),
                selectinload(RadiologistCommission.order),
            )
        )
        count_stmt = select(func.count(RadiologistCommission.id)).where(
            RadiologistCommission.lab_id == lab_id
        )

        if radiologist_id:
            stmt = stmt.where(RadiologistCommission.radiologist_id == radiologist_id)
            count_stmt = count_stmt.where(RadiologistCommission.radiologist_id == radiologist_id)

        if is_settled is not None:
            stmt = stmt.where(RadiologistCommission.is_settled == is_settled)
            count_stmt = count_stmt.where(RadiologistCommission.is_settled == is_settled)

        stmt = stmt.order_by(RadiologistCommission.created_at.desc()).offset(offset).limit(limit)

        total_res = await db.execute(count_stmt)
        total = total_res.scalar_one()

        items_res = await db.execute(stmt)
        items = list(items_res.scalars().all())

        return items, total
