import uuid from datetime import UTC, datetime from typing import Any from motor.motor_asyncio import AsyncIOMotorDatabase from pymongo import ReturnDocument COLLECTION = "templates" async def ensure_template_indexes(db: AsyncIOMotorDatabase) -> None: await db[COLLECTION].create_index([("owner_id", 1), ("updated_at", -1)]) await db[COLLECTION].create_index([("owner_id", 1), ("category", 1)]) def _serialize(template: dict[str, Any]) -> dict[str, Any]: return { "id": template["_id"], "owner_id": template["owner_id"], "name": template["name"], "description": template.get("description", ""), "category": template.get("category", "General"), "emoji": template.get("emoji", "📄"), "content": template.get("content", {}), "created_at": template["created_at"], "updated_at": template["updated_at"], "members": template.get("members", []), } async def list_templates(db: AsyncIOMotorDatabase, owner_id: int) -> list[dict[str, Any]]: cursor = db[COLLECTION].find( {"$or": [{"owner_id": owner_id}, {"members.user_id": owner_id}]} ).sort([("category", 1), ("updated_at", -1)]) return [_serialize(template) async for template in cursor] async def create_template( db: AsyncIOMotorDatabase, owner_id: int, data: dict[str, Any], ) -> dict[str, Any]: now = datetime.now(UTC) template = { "_id": str(uuid.uuid4()), "owner_id": owner_id, **data, "created_at": now, "updated_at": now, "members": [], } await db[COLLECTION].insert_one(template) return _serialize(template) async def delete_template(db: AsyncIOMotorDatabase, template_id: str, owner_id: int) -> bool: result = await db[COLLECTION].delete_one({"_id": template_id, "owner_id": owner_id}) return result.deleted_count == 1 async def share_template( db: AsyncIOMotorDatabase, template_id: str, owner_id: int, member: dict[str, Any], ) -> dict[str, Any] | None: template = await db[COLLECTION].find_one({"_id": template_id, "owner_id": owner_id}) if template is None: return None members = [item for item in template.get("members", []) if item.get("user_id") != member["user_id"]] members.append(member) result = await db[COLLECTION].find_one_and_update( {"_id": template_id, "owner_id": owner_id}, {"$set": {"members": members, "updated_at": datetime.now(UTC)}}, return_document=ReturnDocument.AFTER, ) return _serialize(result) if result else None