"""Repository مربوط به Tenant و Domain."""
from __future__ import annotations

from typing import Sequence
from uuid import UUID

from sqlalchemy import func, select

from app.models.domain import Domain
from app.models.tenant import Tenant
from app.repositories.base import BaseRepository


class TenantRepository(BaseRepository[Tenant]):
    model = Tenant

    async def get_by_slug(self, slug: str) -> Tenant | None:
        stmt = select(Tenant).where(Tenant.slug == slug)
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()

    async def slug_exists(self, slug: str) -> bool:
        stmt = select(func.count()).select_from(Tenant).where(Tenant.slug == slug)
        result = await self.session.execute(stmt)
        return int(result.scalar_one()) > 0

    async def list_by_owner(
        self, owner_user_id: UUID, *, offset: int = 0, limit: int = 20
    ) -> Sequence[Tenant]:
        stmt = (
            select(Tenant)
            .where(Tenant.owner_user_id == owner_user_id)
            .offset(offset)
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()

    async def count_by_owner(self, owner_user_id: UUID) -> int:
        stmt = (
            select(func.count())
            .select_from(Tenant)
            .where(Tenant.owner_user_id == owner_user_id)
        )
        result = await self.session.execute(stmt)
        return int(result.scalar_one())


class DomainRepository(BaseRepository[Domain]):
    model = Domain

    async def get_by_domain(self, domain: str) -> Domain | None:
        stmt = select(Domain).where(Domain.domain == domain)
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()

    async def list_by_tenant(self, tenant_id: UUID) -> Sequence[Domain]:
        stmt = select(Domain).where(Domain.tenant_id == tenant_id)
        result = await self.session.execute(stmt)
        return result.scalars().all()

    async def domain_exists(self, domain: str) -> bool:
        stmt = select(func.count()).select_from(Domain).where(Domain.domain == domain)
        result = await self.session.execute(stmt)
        return int(result.scalar_one()) > 0
