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.communication_email import CommunicationEmailCreate, CommunicationEmailUpdate

COLLECTION_NAME = "communication_email"

def create_communication_email_service(payload: CommunicationEmailCreate, background_tasks: BackgroundTasks, db):
    collection = db[COLLECTION_NAME]
    data = payload.dict()
    data["created_date"] = datetime.utcnow()

    inserted = collection.insert_one(data)
    data["id"] = str(inserted.inserted_id)

    return data


def get_communication_emails_service(account_id: str, skip: int, limit: int, q: Optional[str], account_view: Optional[int], db,current_user):
    collection = db[COLLECTION_NAME]
    query = {}

    # ✅ Only filter by account_id if user is not an admin (role_id != 1)
    if current_user.get("roles") != 1 or account_view == 1:
        query["account_id"] = account_id

    query = {"account_id": account_id}

    if q:
        regex = {"$regex": q, "$options": "i"}
        query["$or"] = [
            {"email_title": regex},
            {"email_to": regex},
            {"email_from": regex},
            {"status": regex}
        ]

    emails = list(collection.find(query).skip(skip).limit(limit))
    total_count = collection.count_documents(query)

    for email in emails:
        email["email_id"] = str(email["_id"])
        email.pop("_id", None)
        if isinstance(email.get("created_date"), datetime):
            email["created_date"] = email["created_date"].isoformat()

    return {"total_count": total_count, "emails": emails}


def read_communication_email_service(email_id: str, db):
    email = db[COLLECTION_NAME].find_one({"_id": str_to_objectid(email_id)})
    if email:
        email["email_id"] = str(email["_id"])
        email.pop("_id", None)
        return email
    return None


def update_communication_email_service(email_id: str, update: CommunicationEmailUpdate, 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(email_id)}, {"$set": update_data})

    if result.matched_count == 0:
        raise HTTPException(status_code=404, detail="Email record not found")

    updated = collection.find_one({"_id": str_to_objectid(email_id)})
    updated["id"] = str(updated["_id"])
    updated.pop("_id", None)
    return updated


def delete_communication_email_service(email_id: str, db):
    collection = db[COLLECTION_NAME]
    email = collection.find_one({"_id": str_to_objectid(email_id)})

    if not email:
        raise HTTPException(status_code=404, detail="Email record not found")

    collection.delete_one({"_id": str_to_objectid(email_id)})
    email["id"] = str(email["_id"])
    email.pop("_id", None)
    return email

def get_email_status_counts(db):
    collection = db["communication_email"]

    pipeline = [
        {"$match": {"status": {"$in": ["success", "failed"]}}},
        {"$group": {
            "_id": "$status",
            "count": {"$sum": 1}
        }}
    ]

    results = collection.aggregate(pipeline)

    counts = {"success": 0, "failed": 0, "total": 0}
    for result in results:
        status = result["_id"]
        count = result["count"]
        if status in counts:
            counts[status] = count
            counts["total"] += count

    return counts

