"""Journal entry routes""" from fastapi import APIRouter, HTTPException from db import get_database from models import JournalEntryCreate, JournalEntryUpdate from datetime import datetime from typing import List from bson import ObjectId router = APIRouter() @router.post("/{user_id}", response_model=dict) async def create_entry(user_id: str, entry_data: JournalEntryCreate): """Create a new journal entry""" db = get_database() try: entry_doc = { "userId": user_id, "title": entry_data.title, "content": entry_data.content, "mood": entry_data.mood, "tags": entry_data.tags or [], "isPublic": entry_data.isPublic, "createdAt": datetime.utcnow(), "updatedAt": datetime.utcnow() } result = db.entries.insert_one(entry_doc) entry_doc["id"] = str(result.inserted_id) return { "id": entry_doc["id"], "message": "Entry created successfully" } except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/{user_id}") async def get_user_entries(user_id: str, limit: int = 50, skip: int = 0): """Get all entries for a user (paginated, most recent first)""" db = get_database() try: entries = list( db.entries.find( {"userId": user_id} ).sort("createdAt", -1).skip(skip).limit(limit) ) for entry in entries: entry["id"] = str(entry["_id"]) del entry["_id"] total = db.entries.count_documents({"userId": user_id}) return { "entries": entries, "total": total, "skip": skip, "limit": limit } except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/{user_id}/{entry_id}") async def get_entry(user_id: str, entry_id: str): """Get a specific entry""" db = get_database() try: entry = db.entries.find_one({ "_id": ObjectId(entry_id), "userId": user_id }) if not entry: raise HTTPException(status_code=404, detail="Entry not found") entry["id"] = str(entry["_id"]) del entry["_id"] return entry except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.put("/{user_id}/{entry_id}") async def update_entry(user_id: str, entry_id: str, entry_data: JournalEntryUpdate): """Update a journal entry""" db = get_database() try: update_data = entry_data.model_dump(exclude_unset=True) update_data["updatedAt"] = datetime.utcnow() result = db.entries.update_one( { "_id": ObjectId(entry_id), "userId": user_id }, {"$set": update_data} ) if result.matched_count == 0: raise HTTPException(status_code=404, detail="Entry not found") return {"message": "Entry updated successfully"} except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.delete("/{user_id}/{entry_id}") async def delete_entry(user_id: str, entry_id: str): """Delete a journal entry""" db = get_database() try: result = db.entries.delete_one({ "_id": ObjectId(entry_id), "userId": user_id }) if result.deleted_count == 0: raise HTTPException(status_code=404, detail="Entry not found") return {"message": "Entry deleted successfully"} except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/{user_id}/date/{date_str}") async def get_entries_by_date(user_id: str, date_str: str): """Get entries for a specific date (format: YYYY-MM-DD)""" db = get_database() try: from datetime import datetime as dt # Parse date target_date = dt.strptime(date_str, "%Y-%m-%d") next_date = dt.fromtimestamp(target_date.timestamp() + 86400) entries = list( db.entries.find({ "userId": user_id, "createdAt": { "$gte": target_date, "$lt": next_date } }).sort("createdAt", -1) ) for entry in entries: entry["id"] = str(entry["_id"]) del entry["_id"] return {"entries": entries, "date": date_str} except ValueError: raise HTTPException( status_code=400, detail="Invalid date format. Use YYYY-MM-DD") except Exception as e: raise HTTPException(status_code=500, detail=str(e))