from typing import Optional

from django.db.models import Q

from baserow.contrib.builder.elements.models import Element
from baserow.contrib.builder.object_scopes import BuilderObjectScopeType
from baserow.contrib.builder.pages.object_scopes import BuilderPageObjectScopeType
from baserow.core.object_scopes import (
    ApplicationObjectScopeType,
    WorkspaceObjectScopeType,
)
from baserow.core.registries import ObjectScopeType, object_scope_type_registry


class BuilderElementObjectScopeType(ObjectScopeType):
    type = "builder_element"
    model_class = Element

    def get_parent_scope(self) -> Optional["ObjectScopeType"]:
        return object_scope_type_registry.get("builder_page")

    def get_enhanced_queryset(self):
        return self.get_base_queryset().prefetch_related(
            "page", "page__builder", "page__builder__workspace"
        )

    def get_filter_for_scope_type(self, scope_type, scopes):
        if scope_type.type == WorkspaceObjectScopeType.type:
            return Q(page__builder__workspace__in=[s.id for s in scopes])

        if (
            scope_type.type == BuilderObjectScopeType.type
            or scope_type.type == ApplicationObjectScopeType.type
        ):
            return Q(page__builder__in=[s.id for s in scopes])

        if scope_type.type == BuilderPageObjectScopeType.type:
            return Q(page__in=[s.id for s in scopes])

        if scope_type.type == self.type:
            return Q(id__in=[s.id for s in scopes])

        raise TypeError("The given type is not handled.")
