""""""

# from __future__ import annotations

# import contextlib

# import sqlalchemy as sa

# from abilian.core.models.tag import Tag, entity_tag_tbl
# from abilian.i18n import _

# # from ..search.criterion import BaseCriterion
# from .extension import ENTITY_DEFAULT_NS_ATTR


# class TagCriterion(BaseCriterion):
#     """Filter entities with selected tag(s)."""

#     form_default_value = ""

#     def __init__(self, *args, **kwargs):
#         if len(args) == 0:
#             kwargs.setdefault("name", "tags")

#         if len(args) < 2:
#             kwargs.setdefault("label", _("Tags"))

#         super().__init__(*args, **kwargs)

#     @BaseCriterion.model.setter
#     def model(self, model):
#         BaseCriterion.model.fset(self, model)
#         self.ns = getattr(model, ENTITY_DEFAULT_NS_ATTR)

#     @property
#     def valid_tags(self):
#         join_clause = entity_tag_tbl.join(
#             self.model, self.model.id == entity_tag_tbl.c.entity_id
#         )
#         model_tags = sa.sql.select([entity_tag_tbl.c.tag_id], from_obj=join_clause)
#         return Tag.query.filter(Tag.ns == self.ns, Tag.id.in_(model_tags)).all()

#     def get_request_values(self, request):
#         tag_ids = []

#         for val in request.values.getlist(self.name):
#             with contextlib.suppress(ValueError):
#                 tag_ids.append(int(val))

#         valid_tags = set(self.valid_tags)
#         tags = []
#         for tid in tag_ids:
#             t = Tag.query.get(tid)
#             if t in valid_tags:
#                 tags.append(t)

#         return tags

#     def filter(self, query, module, request, searched_text, *args, **kwargs):
#         tags = self.get_request_values(request)
#         if not tags:
#             return query

#         cond = sa.sql.exists(
#             sa.sql.select(
#                 [1],
#                 sa.sql.and_(
#                     entity_tag_tbl.c.entity_id == self.model.id,
#                     entity_tag_tbl.c.tag_id.in_(t.id for t in tags),
#                 ),
#             )
#         )
#         return query.filter(cond)

#     @property
#     def form_filter_type(self):
#         return "select"

#     @property
#     def form_unset_value(self):
#         return []

#     @property
#     def form_filter_args(self):
#         # expected value: [list of selectable items, is multiple?]
#         return [[(str(t.id), t.label) for t in self.valid_tags], True]
