from fastapi import BackgroundTasks, HTTPException
from bson import ObjectId
from datetime import datetime
from typing import Optional

from app.v1.libraries.object import str_to_objectid
from ...models.saas.activity import ActivityCreate, ActivityUpdate

COLLECTION_NAME = "activity"

def create_activity_service(activity: ActivityCreate, background_tasks: BackgroundTasks, db):
    activity_collection = db[COLLECTION_NAME]

    activity_data = activity.dict()
    activity_data["created_date"] = datetime.utcnow()

    inserted = activity_collection.insert_one(activity_data)
    activity_data["id"] = str(inserted.inserted_id)

    return activity_data


def get_activities_service(account_id: str, skip: int, limit: int, q: Optional[str], db):
    activity_collection = db[COLLECTION_NAME]
    query = {"account_id": account_id}

    if q:
        regex = {"$regex": q, "$options": "i"}
        query["$or"] = [
            {"activity_title": regex},
            {"status": regex},
            {"user_id": regex},
            {"to_id": regex}
        ]

    activities = list(activity_collection.find(query).skip(skip).limit(limit))
    total_count = activity_collection.count_documents(query)

    for activity in activities:
        activity["activity_id"] = str(activity["_id"])
        activity.pop("_id", None)
        if "created_date" in activity and isinstance(activity["created_date"], datetime):
            activity["created_date"] = activity["created_date"].isoformat()

    return {"total_count": total_count, "activities": activities}


def read_activity_service(activity_id: str, db):
    activity = db[COLLECTION_NAME].find_one({"_id": str_to_objectid(activity_id)})
    if activity:
        activity["activity_id"] = str(activity["_id"])
        activity.pop("_id", None)
        return activity
    return None


def update_activity_service(activity_id: str, update: ActivityUpdate, db):
    collection = db[COLLECTION_NAME]
    update_data = {k: v for k, v in update.dict().items() if v is not None}

    result = collection.update_one(
        {"_id": str_to_objectid(activity_id)},
        {"$set": update_data}
    )

    if result.matched_count == 0:
        raise HTTPException(status_code=404, detail="Activity not found")

    updated = collection.find_one({"_id": str_to_objectid(activity_id)})
    updated["id"] = str(updated["_id"])
    updated.pop("_id", None)
    return updated


def delete_activity_service(activity_id: str, db):
    collection = db[COLLECTION_NAME]
    activity = collection.find_one({"_id": str_to_objectid(activity_id)})

    if not activity:
        raise HTTPException(status_code=404, detail="Activity not found")

    collection.delete_one({"_id": str_to_objectid(activity_id)})
    activity["id"] = str(activity["_id"])
    activity.pop("_id", None)
    return activity
