# MongoDB 连接与数据库访问（基类：子类需传入连接参数与集合名）

from typing import Any, Optional

from pymongo import MongoClient
from pymongo.collection import Collection
from pymongo.cursor import Cursor
from pymongo.results import DeleteResult, InsertOneResult, InsertManyResult, UpdateResult


class MongoRepositoryBase:
    """
    MongoDB 集合访问的基类。

    子类继承后，在实例化时必须传入：
    - 数据库连接参数：mongodb_url、db_name，以及可选的 auth_source
    - 集合名称：collection_name

    示例：
        class MyRepo(MongoRepositoryBase):
            def __init__(self):
                super().__init__(
                    mongodb_url="mongodb://localhost:27017",
                    db_name="mydb",
                    collection_name="my_coll",
                    auth_source="admin",  # 可选
                )
    """

    def __init__(
        self,
        *,
        mongodb_url: str,
        db_name: str,
        collection_name: str,
        auth_source: Optional[str] = None,
    ) -> None:
        if not mongodb_url or not str(mongodb_url).strip():
            raise ValueError("mongodb_url 不能为空")
        if not db_name or not str(db_name).strip():
            raise ValueError("db_name 不能为空")
        if not collection_name or not str(collection_name).strip():
            raise ValueError("collection_name 不能为空")
        kwargs: dict[str, Any] = {}
        if auth_source and str(auth_source).strip():
            kwargs["authSource"] = auth_source.strip()
        self._client = MongoClient(mongodb_url.strip(), **kwargs)
        self._db = self._client[db_name.strip()]
        self._coll = self._db[collection_name.strip()]

    @property
    def collection(self) -> Collection:
        """当前集合。"""
        return self._coll

    def find(self, filter: Optional[dict[str, Any]] = None, **kwargs: Any) -> Cursor:
        """查询多条。filter 为 None 时查全部。"""
        return self._coll.find(filter or {}, **kwargs)

    def find_one(
        self, filter: Optional[dict[str, Any]] = None, **kwargs: Any
    ) -> Optional[dict[str, Any]]:
        """查询单条。"""
        return self._coll.find_one(filter or {}, **kwargs)

    def insert_one(self, document: dict[str, Any], **kwargs: Any) -> InsertOneResult:
        """新增一条。"""
        return self._coll.insert_one(document, **kwargs)

    def insert_many(
        self, documents: list[dict[str, Any]], **kwargs: Any
    ) -> InsertManyResult:
        """新增多条。"""
        return self._coll.insert_many(documents, **kwargs)

    def update_one(
        self, filter: dict[str, Any], update: dict[str, Any], **kwargs: Any
    ) -> UpdateResult:
        """修改一条。"""
        return self._coll.update_one(filter, update, **kwargs)

    def update_many(
        self, filter: dict[str, Any], update: dict[str, Any], **kwargs: Any
    ) -> UpdateResult:
        """修改多条。"""
        return self._coll.update_many(filter, update, **kwargs)

    def delete_one(self, filter: dict[str, Any], **kwargs: Any) -> DeleteResult:
        """删除一条。"""
        return self._coll.delete_one(filter, **kwargs)

    def delete_many(self, filter: dict[str, Any], **kwargs: Any) -> DeleteResult:
        """删除多条。"""
        return self._coll.delete_many(filter, **kwargs)

    def aggregate(self, pipeline: list[dict[str, Any]], **kwargs: Any) -> Any:
        """聚合查询。"""
        return self._coll.aggregate(pipeline, **kwargs)
