"""FluentQuery 兼容层查询构建器

提供 SQLAlchemy 风格的链式 OOP 查询接口，包装 Django QuerySet。

核心类：
- ``FluentQuery`` — 链式查询构建器，由 ``Model.query`` 返回
- ``Session`` — 简易会话管理（add/commit/rollback）
- ``_CompatFunc`` — 兼容层聚合函数（func.sum / func.count 等）
- ``db`` — 全局数据库操作入口（db.session / db.or_ / db.and_）

典型用法::

    from gvsdsdk.fluent import db, func, FQ

    # 链式查询
    orders = Dingdan.query.filter(zhuangtai=8).order_by('-CreateTime').to_list()

    # 字段表达式
    Dingdan.query.filter(Dingdan.jine > 100, Dingdan.zhuangtai.in_([1,2,3]))

    # 聚合
    Dingdan.query.aggregate(total=Sum('jine'))

    # values / annotate
    Dingdan.query.values('zhuangtai').annotate(cnt=Count('id'))

    # 分页
    Dingdan.query.paginate(page=1, per_page=20)

    # 兼容层聚合函数
    func.sum(Dingdan.jine)
    func.count(Dingdan.id)
    func.year(Dingdan.CreateTime)
"""
from __future__ import annotations

import logging
import threading
from typing import Any, Dict, Generic, Iterator, List, Optional, Sequence, Tuple, Type, TypeVar, Union

from django.db import connection as default_db_connection, models, transaction
from django.db.models import Q, F, Count, Sum, Avg, Min, Max, Subquery, OuterRef, Case, When, Value

logger = logging.getLogger(__name__)

_local = threading.local()

#: 模型类型变量，用于 FluentQuery[_M] 泛型参数
_M = TypeVar('_M', bound=models.Model)


def _get_field_expression_cls():
    """延迟导入 FieldExpression，避免 fluent ↔ model_base 循环依赖。"""
    from gvsdsdk.model_base import FieldExpression
    return FieldExpression


# ---------------------------------------------------------------------------
# 兼容层聚合函数
# ---------------------------------------------------------------------------

class _AggregateExpr:
    """聚合表达式包装，关联模型类和 Django Aggregate 对象。"""

    def __init__(self, model: Optional[Type[models.Model]], aggregate: models.Aggregate) -> None:
        self.model = model
        self.aggregate = aggregate


class _ExtractExpr:
    """日期提取表达式（year/month/day），用于 ``func.year(field) == 2024`` 等。"""

    def __init__(self, field_name: str, lookup_type: str) -> None:
        self.field_name = field_name
        self.lookup_type = lookup_type

    def __eq__(self, other) -> Q:  # type: ignore[override]
        return Q(**{f'{self.field_name}__{self.lookup_type}': other})

    def __and__(self, other) -> Q:
        if isinstance(other, Q):
            return Q(**{f'{self.field_name}__{self.lookup_type}': None}) & other
        return self.__eq__(other)


class _CompatFunc:
    """兼容层聚合函数集合，提供 SQLAlchemy 风格的 ``func.sum()`` / ``func.count()`` 等。

    用法::

        from gvsdsdk.fluent import func

        func.sum(Model.jine)       → Sum('jine')
        func.count(Model.id)       → Count('id')
        func.max(Model.jine)       → Max('jine')
        func.min(Model.jine)       → Min('jine')
        func.avg(Model.jine)       → Avg('jine')
        func.year(Model.riqi)      → _ExtractExpr('riqi', 'year')
        func.month(Model.riqi)     → _ExtractExpr('riqi', 'month')
        func.day(Model.riqi)       → _ExtractExpr('riqi', 'day')
    """

    def sum(self, field_expr) -> Union[_AggregateExpr, Sum]:
        """求和聚合。"""
        name = self._resolve_name(field_expr)
        agg = Sum(name)
        model = getattr(field_expr, 'model_class', None)
        return _AggregateExpr(model, agg) if model else agg

    def count(self, field_expr=None) -> Union[_AggregateExpr, Count]:
        """计数聚合，无参数时等价于 COUNT(*)。"""
        if field_expr is None:
            return Count('*')
        name = self._resolve_name(field_expr)
        agg = Count(name)
        model = getattr(field_expr, 'model_class', None)
        return _AggregateExpr(model, agg) if model else agg

    def max(self, field_expr) -> Union[_AggregateExpr, Max]:
        """最大值聚合。"""
        name = self._resolve_name(field_expr)
        agg = Max(name)
        model = getattr(field_expr, 'model_class', None)
        return _AggregateExpr(model, agg) if model else agg

    def min(self, field_expr) -> Union[_AggregateExpr, Min]:
        """最小值聚合。"""
        name = self._resolve_name(field_expr)
        agg = Min(name)
        model = getattr(field_expr, 'model_class', None)
        return _AggregateExpr(model, agg) if model else agg

    def avg(self, field_expr) -> Union[_AggregateExpr, Avg]:
        """平均值聚合。"""
        name = self._resolve_name(field_expr)
        agg = Avg(name)
        model = getattr(field_expr, 'model_class', None)
        return _AggregateExpr(model, agg) if model else agg

    def year(self, field_expr) -> _ExtractExpr:
        """提取年份，用于 ``func.year(Model.date) == 2024``。"""
        return _ExtractExpr(self._resolve_name(field_expr), 'year')

    def month(self, field_expr) -> _ExtractExpr:
        """提取月份。"""
        return _ExtractExpr(self._resolve_name(field_expr), 'month')

    def day(self, field_expr) -> _ExtractExpr:
        """提取日期。"""
        return _ExtractExpr(self._resolve_name(field_expr), 'day')

    @staticmethod
    def _resolve_name(field_expr) -> str:
        """从 FieldExpression 或字符串解析 Django 字段名。"""
        if hasattr(field_expr, '_django_name'):
            return field_expr._django_name
        if hasattr(field_expr, 'field_name'):
            return field_expr.field_name
        return str(field_expr)


func = _CompatFunc()


# ---------------------------------------------------------------------------
# DELETE 语句构建器
# ---------------------------------------------------------------------------

class _DeleteStmt:
    """DELETE 语句构建器，支持 ``Model.query.filter(...).delete()`` 风格。"""

    def __init__(self, model_class: Type[models.Model], conditions: Optional[Q] = None) -> None:
        self.model_class = model_class
        self.conditions = conditions or Q()

    def where(self, *args: Q, **kwargs: Any) -> _DeleteStmt:
        """添加 WHERE 条件。"""
        new_conditions = Q()
        for a in args:
            if isinstance(a, Q):
                new_conditions &= a
        if kwargs:
            new_conditions &= Q(**kwargs)
        self.conditions = new_conditions
        return self

    def execute(self) -> Tuple[int, Dict[str, int]]:
        """执行删除，返回 (删除数, {表名: 删除数})。"""
        if self.model_class and self.conditions:
            return self.model_class.objects.filter(self.conditions).delete()
        elif self.model_class:
            return self.model_class.objects.all().delete()
        return (0, {})


# ---------------------------------------------------------------------------
# 会话与缓存
# ---------------------------------------------------------------------------

def _get_session() -> Session:
    """获取当前线程的 Session 实例。"""
    if not hasattr(_local, 'db_session'):
        _local.db_session = Session()
    return _local.db_session


def _get_cache() -> Dict:
    """获取当前线程的查询缓存。"""
    if not hasattr(_local, 'query_cache'):
        _local.query_cache = {}
    return _local.query_cache


def _invalidate_cache() -> None:
    """清除当前线程的查询缓存。"""
    if hasattr(_local, 'query_cache'):
        _local.query_cache.clear()


# ---------------------------------------------------------------------------
# 关联字段访问器
# ---------------------------------------------------------------------------

class RelationAccessor:
    """关联字段访问器，支持 ``Model.relation.field`` 跨表字段表达式。

    用法::

        # 自动解析关联字段
        Dingdan.query.filter(Dingdan.shangjia.nicheng == '测试')
    """

    def __init__(self, model_class: Type[models.Model], prefix: str = '') -> None:
        self._model = model_class
        self._prefix = prefix

    def __getattr__(self, name: str):
        if name.startswith('_'):
            return object.__getattribute__(self, name)
        try:
            self._model._meta.get_field(name)
            full_name = f'{self._prefix}__{name}' if self._prefix else name
            return _get_field_expression_cls()(self._model, full_name)
        except Exception:
            for rel in self._model._meta.get_fields(include_hidden=True):
                if hasattr(rel, 'related_model') and rel.related_model:
                    rel_name = ''
                    if hasattr(rel, 'get_accessor_name'):
                        rel_name = rel.get_accessor_name()
                    elif hasattr(rel, 'name'):
                        rel_name = rel.name
                    if rel_name and rel_name == name:
                        full_prefix = f'{self._prefix}__{rel_name}' if self._prefix else rel_name
                        return RelationAccessor(rel.related_model, full_prefix)
            return _get_field_expression_cls()(self._model, name)

    def __repr__(self) -> str:
        return f'RelationAccessor({self._model.__name__}, prefix={self._prefix!r})'


# ---------------------------------------------------------------------------
# Values 结果集
# ---------------------------------------------------------------------------

class _ValuesResult:
    """包装 Django ValuesQuerySet，支持链式调用。

    底层使用 Django ``.values()`` 返回字典，保持与 Django 行为一致。
    额外提供 ``.all()`` 返回字典列表，``.first()`` 返回字典或 None，
    ``.scalar()`` 返回单字段场景的标量值。
    """

    def __init__(self, qs: models.QuerySet, fields: List[str], original_fields: Tuple) -> None:
        self._qs: models.QuerySet = qs
        self._fields: List[str] = fields
        self._original_fields: Tuple = original_fields

    @property
    def query(self) -> Any:
        """暴露底层 Django QuerySet 的 query 属性，支持 Subquery() 等场景。"""
        return self._qs.query

    def filter(self, *args: Any, **kwargs: Any) -> _ValuesResult:
        self._qs = self._qs.filter(*args, **kwargs)
        return self

    def exclude(self, *args: Any, **kwargs: Any) -> _ValuesResult:
        self._qs = self._qs.exclude(*args, **kwargs)
        return self

    def order_by(self, *fields: str) -> _ValuesResult:
        self._qs = self._qs.order_by(*fields)
        return self

    def distinct(self) -> _ValuesResult:
        self._qs = self._qs.distinct()
        return self

    def annotate(self, **kwargs: Any) -> _ValuesResult:
        self._qs = self._qs.annotate(**kwargs)
        return self

    def first(self) -> Optional[Dict[str, Any]]:
        """返回第一条记录（字典）或 None。"""
        return self._qs.first()

    def all(self) -> List[Dict[str, Any]]:
        """返回所有记录的字典列表。"""
        return list(self._qs)

    def scalar(self) -> Any:
        """返回单字段场景的标量值。"""
        row = self._qs.first()
        if row is None:
            return None
        if self._fields:
            return row.get(self._fields[0])
        return row

    def count(self) -> int:
        return self._qs.count()

    def exists(self) -> bool:
        return self._qs.exists()

    def __getitem__(self, key: Union[int, slice]) -> Any:
        if isinstance(key, slice):
            self._qs = self._qs[key]
            return self
        else:
            return self._qs[key]

    def __iter__(self) -> Iterator[Dict[str, Any]]:
        return iter(self._qs)

    def __len__(self) -> int:
        return self.count()

    def __bool__(self) -> bool:
        return self._qs.exists()

    def __repr__(self) -> str:
        return f'_ValuesResult(fields={self._fields}, count={self.count()})'


# ---------------------------------------------------------------------------
# FluentQuery 核心查询构建器
# ---------------------------------------------------------------------------

class FluentQuery(Generic[_M]):
    """QModel 兼容层查询构建器，提供 SQLAlchemy 风格的链式 OOP 查询接口。

    由 ``Model.query`` 返回，支持链式调用::

        # 基础查询
        Dingdan.query.filter(zhuangtai=8).all()

        # 链式过滤
        Dingdan.query.filter(jine__gt=100).order_by('-CreateTime').limit(10)

        # 字段表达式
        Dingdan.query.filter(Dingdan.jine > 100, Dingdan.zhuangtai.in_([1,2,3]))

        # 聚合
        Dingdan.query.aggregate(total=Sum('jine'))

        # values / annotate
        Dingdan.query.values('zhuangtai').annotate(cnt=Count('id'))

        # 分页
        Dingdan.query.paginate(page=1, per_page=20)

    泛型参数 ``_M`` 携带模型类型，使 IDE 能推断链式调用返回的模型实例类型。
    """

    def __init__(self, model_class: Type[_M]) -> None:
        self._model: Type[_M] = model_class
        self._qs: models.QuerySet = model_class.objects.all()
        self._joined_models: List[Type[models.Model]] = []
        self._cache_enabled: bool = True

    @property
    def query(self) -> Any:
        """暴露底层 Django QuerySet 的 query 属性，支持 Subquery() 等场景。"""
        return self._qs.query

    @property
    def model(self) -> Type[_M]:
        """返回关联的模型类。"""
        return self._model

    def _clone(self) -> FluentQuery[_M]:
        """克隆当前查询状态。"""
        q = FluentQuery(self._model)
        q._qs = self._qs
        q._joined_models = list(self._joined_models)
        q._cache_enabled = self._cache_enabled
        return q

    def _cache_key(self, method: str) -> Tuple[Any, str, Any]:
        """生成缓存键。"""
        try:
            query_str = str(self._qs.query)
        except Exception:
            query_str = id(self._qs)
        return (self._model, method, query_str)

    def _remap_q(self, q: Q) -> Q:
        """重映射 Q 对象中的字段名（用于 join 跨表查询）。"""
        new_children: List[Any] = []
        for child in q.children:
            if isinstance(child, Q):
                new_children.append(self._remap_q(child))
            elif isinstance(child, tuple):
                key, val = child
                new_key = self._remap_key(key)
                new_children.append((new_key, val))
            else:
                new_children.append(child)
        if new_children:
            new_q = Q(*new_children)
            new_q.connector = q.connector
            new_q.negated = q.negated
            return new_q
        return q

    def _remap_key(self, key: str) -> str:
        """重映射字段名（用于 join 跨表查询自动添加关联前缀）。"""
        parts = key.split('__')
        field_name = parts[0]
        try:
            self._model._meta.get_field(field_name)
            return key
        except Exception:
            pass
        for joined in self._joined_models:
            try:
                joined._meta.get_field(field_name)
                for rel in self._model._meta.get_fields(include_hidden=True):
                    if hasattr(rel, 'related_model') and rel.related_model == joined:
                        acc = ''
                        if hasattr(rel, 'get_accessor_name'):
                            acc = rel.get_accessor_name()
                        elif hasattr(rel, 'name'):
                            acc = rel.name
                        if acc and acc != '+':
                            return acc + '__' + key
                return joined._meta.model_name + '__' + key
            except Exception:
                pass
        return key

    # ---- 过滤 ----

    def filter(self, *args: Any, **kwargs: Any) -> FluentQuery[_M]:
        """过滤查询，支持 Q 对象和关键字参数；返回新 FluentQuery，不修改原查询。"""
        converted_args: List[Any] = []
        for arg in args:
            if isinstance(arg, Q) and self._joined_models:
                converted_args.append(self._remap_q(arg))
            else:
                converted_args.append(arg)
        q = self._clone()
        q._qs = self._qs.filter(*converted_args, **kwargs)
        return q

    def exclude(self, *args: Any, **kwargs: Any) -> FluentQuery[_M]:
        """排除查询；返回新 FluentQuery，不修改原查询。"""
        converted_args: List[Any] = []
        for arg in args:
            if isinstance(arg, Q) and self._joined_models:
                converted_args.append(self._remap_q(arg))
            else:
                converted_args.append(arg)
        q = self._clone()
        q._qs = self._qs.exclude(*converted_args, **kwargs)
        return q

    # ---- 排序 ----

    def order_by(self, *args: Any) -> FluentQuery[_M]:
        """排序，支持字符串和 FieldExpression；返回新 FluentQuery，不修改原查询。"""
        converted: List[str] = []
        for a in args:
            if isinstance(a, str):
                converted.append(a)
            elif isinstance(a, _get_field_expression_cls()):
                converted.append(str(a))
            else:
                converted.append(str(a))
        q = self._clone()
        q._qs = q._qs.order_by(*converted)
        return q

    # ---- 获取记录 ----

    def first(self) -> Optional[_M]:
        """返回第一条记录或 None。"""
        if self._cache_enabled:
            cache = _get_cache()
            key = self._cache_key('first')
            if key in cache:
                return cache[key]
        obj = self._qs.first()
        if obj is not None:
            _get_session().track(obj)
        if self._cache_enabled:
            _get_cache()[self._cache_key('first')] = obj
        return obj

    def last(self) -> Optional[_M]:
        """返回最后一条记录或 None。"""
        return self._qs.last()

    def get(self, *args: Any, **kwargs: Any) -> _M:
        """获取唯一匹配记录，不存在或多个时抛异常。"""
        if args:
            obj = self._qs.filter(*args).get(**kwargs)
        else:
            obj = self._qs.get(**kwargs)
        _get_session().track(obj)
        return obj

    def all(self) -> FluentQuery[_M]:
        """返回 self 以支持链式调用（与 Django QuerySet.all() 一致）。
        如需获取列表，使用 ``.to_list()`` 或 ``list()``。"""
        self._qs = self._qs.all()
        return self

    def to_list(self) -> List[_M]:
        """执行查询并返回模型实例列表。"""
        if self._cache_enabled:
            cache = _get_cache()
            key = self._cache_key('to_list')
            if key in cache:
                return cache[key]
        results = list(self._qs)
        session = _get_session()
        for obj in results:
            session.track(obj)
        if self._cache_enabled:
            _get_cache()[self._cache_key('to_list')] = results
        return results

    def count(self) -> int:
        """返回匹配记录数。"""
        if self._cache_enabled:
            cache = _get_cache()
            key = self._cache_key('count')
            if key in cache:
                return cache[key]
        result = self._qs.count()
        if self._cache_enabled:
            _get_cache()[self._cache_key('count')] = result
        return result

    def exists(self) -> bool:
        """判断是否存在匹配记录。"""
        return self._qs.exists()

    # ---- 创建/更新/删除 ----

    def create(self, **kwargs: Any) -> _M:
        """创建并保存新记录。"""
        obj = self._model.objects.create(**kwargs)
        _invalidate_cache()
        return obj

    def get_or_create(self, defaults: Optional[Dict[str, Any]] = None,
                      **kwargs: Any) -> Tuple[_M, bool]:
        """查询或创建记录，返回 ``(obj, created)`` 元组。"""
        obj, created = self._model.objects.get_or_create(defaults=defaults, **kwargs)
        if created:
            _invalidate_cache()
        _get_session().track(obj)
        return obj, created

    def update_or_create(self, defaults: Optional[Dict[str, Any]] = None,
                         **kwargs: Any) -> Tuple[_M, bool]:
        """更新或创建记录，返回 ``(obj, created)`` 元组。"""
        obj, created = self._model.objects.update_or_create(defaults=defaults, **kwargs)
        _invalidate_cache()
        _get_session().track(obj)
        return obj, created

    def bulk_create(self, objs: List[_M], batch_size: Optional[int] = None,
                    ignore_conflicts: bool = False) -> List[_M]:
        """批量创建记录。"""
        result = self._model.objects.bulk_create(
            objs, batch_size=batch_size, ignore_conflicts=ignore_conflicts
        )
        _invalidate_cache()
        return result

    def bulk_update(self, objs: List[_M], fields: List[str],
                    batch_size: Optional[int] = None) -> int:
        """批量更新记录，返回受影响行数。"""
        result = self._model.objects.bulk_update(objs, fields, batch_size=batch_size)
        _invalidate_cache()
        return result

    def update(self, **kwargs: Any) -> int:
        """批量更新匹配记录，返回受影响行数。"""
        result = self._qs.update(**kwargs)
        _invalidate_cache()
        return result

    def delete(self) -> Tuple[int, Dict[str, int]]:
        """批量删除匹配记录，返回 ``(删除数, {表名: 删除数})``。"""
        result = self._qs.delete()
        _invalidate_cache()
        return result

    # ---- 查询修饰 ----

    def none(self) -> FluentQuery[_M]:
        """返回空结果集，返回 self 以支持链式调用。"""
        self._qs = self._qs.none()
        return self

    def limit(self, n: int) -> FluentQuery[_M]:
        """限制返回记录数，返回 self 以支持链式调用。"""
        self._qs = self._qs[:n]
        return self

    def offset(self, n: int) -> FluentQuery[_M]:
        """跳过前 n 条记录，返回 self 以支持链式调用。"""
        self._qs = self._qs[n:]
        return self

    def join(self, *args: Type[models.Model]) -> FluentQuery[_M]:
        """关联模型，用于跨表查询自动映射字段，返回 self 以支持链式调用。"""
        for arg in args:
            if isinstance(arg, type) and issubclass(arg, models.Model):
                if arg not in self._joined_models:
                    self._joined_models.append(arg)
        return self

    def select_related(self, *fields: str) -> FluentQuery[_M]:
        """外键关联查询优化，返回 self 以支持链式调用。"""
        self._qs = self._qs.select_related(*fields)
        return self

    def prefetch_related(self, *fields: str) -> FluentQuery[_M]:
        """多对多/反向关联查询优化，返回 self 以支持链式调用。"""
        self._qs = self._qs.prefetch_related(*fields)
        return self

    def only(self, *fields: str) -> FluentQuery[_M]:
        """只加载指定字段，返回 self 以支持链式调用。"""
        self._qs = self._qs.only(*fields)
        return self

    def defer(self, *fields: str) -> FluentQuery[_M]:
        """延迟加载指定字段，返回 self 以支持链式调用。"""
        self._qs = self._qs.defer(*fields)
        return self

    def select_for_update(self, nowait: bool = False, skip_locked: bool = False,
                          of: Tuple = (), no_key: bool = False) -> FluentQuery[_M]:
        """行级锁，返回 self 以支持链式调用。"""
        self._qs = self._qs.select_for_update(
            nowait=nowait, skip_locked=skip_locked, of=of, no_key=no_key
        )
        return self

    def distinct(self) -> FluentQuery[_M]:
        """去重查询，返回 self 以支持链式调用。"""
        self._qs = self._qs.distinct()
        return self

    def using(self, alias: str) -> FluentQuery[_M]:
        """指定数据库别名，返回 self 以支持链式调用。"""
        self._qs = self._qs.using(alias)
        return self

    def no_cache(self) -> FluentQuery[_M]:
        """禁用查询缓存，返回 self 以支持链式调用。"""
        self._cache_enabled = False
        return self

    def params(self, **kwargs: Any) -> FluentQuery[_M]:
        """参数占位（SQLAlchemy 兼容），返回 self 以支持链式调用。"""
        return self

    # ---- 聚合与注解 ----

    def annotate(self, **kwargs: Any) -> FluentQuery[_M]:
        """注解查询，添加聚合/计算字段，返回 self 以支持链式调用。"""
        self._qs = self._qs.annotate(**kwargs)
        return self

    def aggregate(self, *args: Any, **kwargs: Any) -> Dict[str, Any]:
        """聚合查询，返回聚合结果字典。

        兼容 Django QuerySet.aggregate() 的两种调用方式：
            aggregate(Max('field'))            # 位置参数
            aggregate(field__max=Max('field')) # 关键字参数
        """
        return self._qs.aggregate(*args, **kwargs)

    def values(self, *fields: Union[str, _AggregateExpr, models.Expression]) -> _ValuesResult:
        """返回指定字段的字典结果，支持链式调用。"""
        if not fields:
            return _ValuesResult(self._qs.values(), [], fields)

        annotations: Dict[str, models.Aggregate] = {}
        converted: List[str] = []
        for i, f in enumerate(fields):
            if isinstance(f, _AggregateExpr):
                annotations[f'val{i}'] = f.aggregate
                converted.append(f'val{i}')
            elif isinstance(f, (models.Aggregate, models.Expression)):
                annotations[f'val{i}'] = f
                converted.append(f'val{i}')
            elif isinstance(f, str):
                converted.append(f)
            else:
                converted.append(str(f))

        qs = self._qs
        if annotations:
            qs = qs.annotate(**annotations)
        qs = qs.values(*converted)
        return _ValuesResult(qs, converted, fields)

    def with_entities(self, *fields: Union[str, _AggregateExpr, models.Expression]) -> _ValuesResult:
        """values() 的别名，SQLAlchemy 风格。"""
        return self.values(*fields)

    def values_list(self, *fields: str, flat: bool = False) -> Any:
        """返回指定字段的元组列表。"""
        return self._qs.values_list(*fields, flat=flat)

    # ---- 分页 ----

    def paginate(self, page: int = 1, per_page: int = 20,
                 error_out: bool = False) -> Any:
        """分页查询，返回 Page 对象（含 items, total, pages 等属性）。"""
        from django.core.paginator import Paginator, EmptyPage
        if not self._qs.ordered:
            meta = getattr(self._model, '_meta', None)
            if meta and meta.pk:
                self._qs = self._qs.order_by(meta.pk.name)
        paginator = Paginator(self._qs, per_page)
        try:
            page_obj = paginator.page(page)
        except EmptyPage:
            page_obj = paginator.page(1)
        page_obj.total = paginator.count
        page_obj.items = page_obj.object_list
        page_obj.pages = paginator.num_pages
        page_obj.page = page
        page_obj.per_page = per_page
        page_obj.has_next = page_obj.has_next()
        page_obj.has_prev = page_obj.has_previous()
        page_obj.next_num = page_obj.next_page_number() if page_obj.has_next else None
        page_obj.prev_num = page_obj.previous_page_number() if page_obj.has_prev else None
        return page_obj

    # ---- 魔术方法 ----

    def __getitem__(self, key: Union[int, slice]) -> Any:
        """支持切片 ``[start:end]`` 和索引 ``[n]``。切片返回 self，索引返回模型实例。"""
        if isinstance(key, slice):
            self._qs = self._qs[key]
            return self
        else:
            return self._qs[key]

    def __iter__(self) -> Iterator[_M]:
        return iter(self._qs)

    def __len__(self) -> int:
        return self.count()

    def __bool__(self) -> bool:
        return self.exists()

    def __repr__(self) -> str:
        return f'FluentQuery({self._model.__name__})'


# ---------------------------------------------------------------------------
# Session 会话管理
# ---------------------------------------------------------------------------

class Session:
    """简易会话管理器，支持 add/delete/commit/rollback 操作。

    用法::

        session = db.session
        session.add(obj)
        session.commit()
    """

    def __init__(self) -> None:
        self._pending_adds: List[models.Model] = []
        self._pending_deletes: List[models.Model] = []
        self._tracked: set = set()

    def add(self, obj: models.Model) -> None:
        """添加对象到待保存列表。"""
        self._pending_adds.append(obj)

    def delete(self, obj: models.Model) -> None:
        """添加对象到待删除列表。"""
        self._pending_deletes.append(obj)
        self._tracked.discard(obj)

    def track(self, obj: models.Model) -> None:
        """跟踪对象变更（commit 时自动 save）。"""
        if isinstance(obj, models.Model):
            self._tracked.add(obj)

    def commit(self) -> None:
        """提交所有待处理操作（删除 → 新增 → 更新）。"""
        delete_pks = {(obj.__class__, obj.pk) for obj in self._pending_deletes
                      if obj.pk is not None}
        with transaction.atomic():
            for obj in self._pending_deletes:
                obj.delete()
            for obj in self._pending_adds:
                obj.save()
            for obj in self._tracked:
                if obj.pk is not None and (obj.__class__, obj.pk) in delete_pks:
                    continue
                try:
                    obj.save()
                except Exception:
                    logger.debug('Session.commit: skip tracked obj %s', obj, exc_info=True)
        self._pending_adds.clear()
        self._pending_deletes.clear()
        self._tracked.clear()
        _invalidate_cache()

    def rollback(self) -> None:
        """回滚所有待处理操作。"""
        self._pending_adds.clear()
        self._pending_deletes.clear()
        self._tracked.clear()
        _invalidate_cache()

    def query(self, *args) -> Optional[FluentQuery[Any]]:
        """创建查询构建器，支持传入模型类或聚合表达式。"""
        model: Optional[Type[models.Model]] = None
        aggregates: List = []
        for a in args:
            if isinstance(a, type) and issubclass(a, models.Model):
                model = a
            elif isinstance(a, _AggregateExpr):
                if a.model:
                    model = a.model
                aggregates.append(a.aggregate)
            elif isinstance(a, (models.Aggregate, models.Expression)):
                aggregates.append(a)
        if not aggregates and model:
            return FluentQuery(model)
        if aggregates and model:
            fq = FluentQuery(model)
            return fq.values(*args)
        return None

    def flush(self) -> None:
        """flush() 的别名，等同于 commit()。"""
        self.commit()

    def execute(self, stmt) -> None:
        """执行语句（支持 _DeleteStmt 和原始 SQL 字符串）。"""
        if isinstance(stmt, _DeleteStmt):
            stmt.execute()
        elif isinstance(stmt, str):
            connection = default_db_connection
            with connection.cursor() as cursor:
                cursor.execute(stmt)


# ---------------------------------------------------------------------------
# 全局入口
# ---------------------------------------------------------------------------

class DB:
    """全局数据库操作入口。

    用法::

        from gvsdsdk.fluent import db

        session = db.session
        q = db.or_(Model.field == 1, Model.field == 2)
        q = db.and_(Model.field > 0, Model.field < 100)
    """

    @property
    def session(self) -> Session:
        """获取当前线程的 Session 实例。"""
        return _get_session()

    @staticmethod
    def or_(*args: Q) -> Q:
        """逻辑 OR，合并多个 Q 对象。"""
        result: Optional[Q] = None
        for q in args:
            if isinstance(q, Q):
                if result is None:
                    result = q
                else:
                    result |= q
        return result if result is not None else Q()

    @staticmethod
    def and_(*args: Q) -> Q:
        """逻辑 AND，合并多个 Q 对象。"""
        result = Q()
        for q in args:
            if isinstance(q, Q):
                result &= q
        return result


db = DB()


def FQ(model_class: Type[_M]) -> FluentQuery[_M]:
    """FluentQuery 工厂函数，等同于 ``Model.query``。"""
    return FluentQuery(model_class)
