"""Sites & page repositories — Phase 11.1."""
from __future__ import annotations

from typing import Sequence
from uuid import UUID

from sqlalchemy import select

from app.models.sites import ExperiencePage, ExperienceSite, ExperienceSiteDomain
from app.repositories.base import TenantBaseRepository


class ExperienceSiteRepository(TenantBaseRepository[ExperienceSite]):
    model = ExperienceSite

    async def get_by_code(
        self, tenant_id: UUID, workspace_id: UUID, code: str
    ) -> ExperienceSite | None:
        stmt = select(self.model).where(
            self.model.tenant_id == tenant_id,
            self.model.workspace_id == workspace_id,
            self.model.code == code,
            self.model.is_deleted.is_(False),
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()

    async def list_by_workspace(
        self, tenant_id: UUID, workspace_id: UUID, *, offset: int = 0, limit: int = 20
    ) -> Sequence[ExperienceSite]:
        stmt = (
            select(self.model)
            .where(
                self.model.tenant_id == tenant_id,
                self.model.workspace_id == workspace_id,
                self.model.is_deleted.is_(False),
            )
            .offset(offset)
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()


class ExperiencePageRepository(TenantBaseRepository[ExperiencePage]):
    model = ExperiencePage

    async def get_by_code(
        self, tenant_id: UUID, site_id: UUID, code: str
    ) -> ExperiencePage | None:
        stmt = select(self.model).where(
            self.model.tenant_id == tenant_id,
            self.model.site_id == site_id,
            self.model.code == code,
            self.model.is_deleted.is_(False),
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()

    async def get_by_slug(
        self, tenant_id: UUID, site_id: UUID, slug: str
    ) -> ExperiencePage | None:
        stmt = select(self.model).where(
            self.model.tenant_id == tenant_id,
            self.model.site_id == site_id,
            self.model.slug == slug,
            self.model.is_deleted.is_(False),
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()

    async def list_by_site(
        self, tenant_id: UUID, site_id: UUID, *, offset: int = 0, limit: int = 20
    ) -> Sequence[ExperiencePage]:
        stmt = (
            select(self.model)
            .where(
                self.model.tenant_id == tenant_id,
                self.model.site_id == site_id,
                self.model.is_deleted.is_(False),
            )
            .offset(offset)
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()


class ExperienceSiteDomainRepository(TenantBaseRepository[ExperienceSiteDomain]):
    model = ExperienceSiteDomain

    async def get_by_host(
        self, tenant_id: UUID, host: str
    ) -> ExperienceSiteDomain | None:
        stmt = select(self.model).where(
            self.model.tenant_id == tenant_id,
            self.model.host == host,
            self.model.is_deleted.is_(False),
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()

    async def list_by_site(
        self, tenant_id: UUID, site_id: UUID, *, offset: int = 0, limit: int = 20
    ) -> Sequence[ExperienceSiteDomain]:
        stmt = (
            select(self.model)
            .where(
                self.model.tenant_id == tenant_id,
                self.model.site_id == site_id,
                self.model.is_deleted.is_(False),
            )
            .offset(offset)
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()
