# xll_kit/cruds/mixins/filter_mixin.py
from enum import Enum
from typing import Dict, Any


class FilterMode(str, Enum):
    EQ = "eq"
    IN = "in"
    RANGE = "range"
    LIKE = "like"


class FilterMixin:
    """
    提供基础 filter 功能（白名单 + 简单操作符）
    """

    def _allowed_filters(self) -> Dict[str, str]:
        """
        返回可过滤字段：
        {
            "name": "eq",
            "status": "eq",
            "id": "in",
            "created_at": "range",
        }
        """
        return {}

    def apply_filters(self, stmt, filters: Dict[str, Any] = None):
        if not filters:
            return stmt

        allowed = self._allowed_filters()

        for field, value in filters.items():
            if value is None:
                continue
            if field not in allowed:
                continue

            col = getattr(self.model, field, None)
            if col is None:
                continue

            mode = allowed[field]

            # 1️⃣ 等值
            if mode == FilterMode.EQ:
                stmt = stmt.where(col == value)

            # 2️⃣ IN
            elif mode == FilterMode.IN:
                if isinstance(value, (list, tuple, set)):
                    stmt = stmt.where(col.in_(value))

            # 3️⃣ LIKE
            elif mode == FilterMode.LIKE:
                if isinstance(value, str):
                    stmt = stmt.where(col.like(f"%{value}%"))

            # 4️⃣ RANGE
            elif mode == FilterMode.RANGE:
                if isinstance(value, dict):
                    if "min" in value:
                        stmt = stmt.where(col >= value["min"])
                    if "max" in value:
                        stmt = stmt.where(col <= value["max"])
                elif isinstance(value, (list, tuple, set)):
                    if len(value) >= 2:
                        stmt = stmt.where(col.between(value[0], value[1]))
                    elif len(value) == 1:
                        stmt = stmt.where(col >= value[0])

        return stmt
