"""Experience foundation repositories."""
from __future__ import annotations

from typing import Sequence
from uuid import UUID

from sqlalchemy import select

from app.models.foundation import (
    ExperienceAuditLog,
    ExperienceConfiguration,
    ExperienceLocaleProfile,
    ExperienceWorkspace,
    ExperiencePermission,
    ExperienceRole,
    ExperienceSetting,
    ExternalProviderConfig,
    RenderEngineRegistration,
)
from app.repositories.base import TenantBaseRepository


class ExperienceWorkspaceRepository(TenantBaseRepository[ExperienceWorkspace]):
    model = ExperienceWorkspace

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


class ExperienceLocaleProfileRepository(TenantBaseRepository[ExperienceLocaleProfile]):
    model = ExperienceLocaleProfile

    async def list_by_organization(
        self, tenant_id: UUID, workspace_id: UUID, *, offset: int = 0, limit: int = 20
    ) -> Sequence[ExperienceLocaleProfile]:
        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 ExperienceRoleRepository(TenantBaseRepository[ExperienceRole]):
    model = ExperienceRole


class ExperiencePermissionRepository(TenantBaseRepository[ExperiencePermission]):
    model = ExperiencePermission


class ExternalProviderConfigRepository(TenantBaseRepository[ExternalProviderConfig]):
    model = ExternalProviderConfig

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


class RenderEngineRegistrationRepository(
    TenantBaseRepository[RenderEngineRegistration]
):
    model = RenderEngineRegistration


class ExperienceConfigurationRepository(TenantBaseRepository[ExperienceConfiguration]):
    model = ExperienceConfiguration


class ExperienceSettingRepository(TenantBaseRepository[ExperienceSetting]):
    model = ExperienceSetting

    async def get_by_key(
        self,
        tenant_id: UUID,
        key: str,
        *,
        workspace_id: UUID | None = None,
        locale_profile_id: UUID | None = None,
    ) -> ExperienceSetting | None:
        clauses = [
            self.model.tenant_id == tenant_id,
            self.model.key == key,
            self.model.is_deleted.is_(False),
        ]
        if workspace_id is None:
            clauses.append(self.model.workspace_id.is_(None))
        else:
            clauses.append(self.model.workspace_id == workspace_id)
        if locale_profile_id is None:
            clauses.append(self.model.locale_profile_id.is_(None))
        else:
            clauses.append(self.model.locale_profile_id == locale_profile_id)
        stmt = select(self.model).where(*clauses)
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()


class ExperienceAuditLogRepository(TenantBaseRepository[ExperienceAuditLog]):
    model = ExperienceAuditLog

    async def list_for_entity(
        self,
        tenant_id: UUID,
        entity_type: str,
        entity_id: UUID,
        *,
        limit: int = 100,
    ) -> Sequence[ExperienceAuditLog]:
        stmt = (
            select(self.model)
            .where(
                self.model.tenant_id == tenant_id,
                self.model.entity_type == entity_type,
                self.model.entity_id == entity_id,
            )
            .order_by(self.model.created_at.desc())
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()
