"""Tenant-scoped repositories for Phase 11.9."""
from uuid import UUID

from sqlalchemy import func, select

from app.models.integrations import (
    ExperienceConsumerConnectorDispatch,
    ExperienceConsumerConnectorRegistration,
    ExperienceNotifyDispatch,
    ExperienceWidgetDefinition,
    ExperienceWidgetInstance,
)
from app.repositories.base import TenantBaseRepository


class _FilteredRepository:
    async def list_filtered(self, tenant_id, *, offset, limit, spec=None):
        base = select(self.model).where(
            self.model.tenant_id == tenant_id, self.model.is_deleted.is_(False)
        )
        count = select(func.count()).select_from(self.model).where(
            self.model.tenant_id == tenant_id, self.model.is_deleted.is_(False)
        )
        if spec:
            base = spec.apply(base)
            count = count.where(*spec.filter_clauses())
        else:
            base = base.order_by(self.model.created_at.desc())
        total = int((await self.session.execute(count)).scalar_one())
        items = (await self.session.execute(base.offset(offset).limit(limit))).scalars().all()
        return items, total


class ConsumerConnectorRegistrationRepository(
    _FilteredRepository, TenantBaseRepository[ExperienceConsumerConnectorRegistration]
):
    model = ExperienceConsumerConnectorRegistration


class ConsumerConnectorDispatchRepository(
    _FilteredRepository, TenantBaseRepository[ExperienceConsumerConnectorDispatch]
):
    model = ExperienceConsumerConnectorDispatch


class WidgetDefinitionRepository(
    _FilteredRepository, TenantBaseRepository[ExperienceWidgetDefinition]
):
    model = ExperienceWidgetDefinition


class WidgetInstanceRepository(_FilteredRepository, TenantBaseRepository[ExperienceWidgetInstance]):
    model = ExperienceWidgetInstance

    async def get_by_embed_ref(self, tenant_id: UUID, embed_ref: str):
        stmt = select(self.model).where(
            self.model.tenant_id == tenant_id,
            self.model.embed_ref == embed_ref,
            self.model.is_deleted.is_(False),
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()


class NotifyDispatchRepository(_FilteredRepository, TenantBaseRepository[ExperienceNotifyDispatch]):
    model = ExperienceNotifyDispatch
