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.cx.ticket import TicketCreate, TicketUpdate,TicketReplyCreate

COLLECTION_NAME = "ticket"
COLLECTION_NAME_REPLY = "ticket_replies"

def create_ticket_service(ticket: TicketCreate, background_tasks: BackgroundTasks, db):
    tickets_collection = db[COLLECTION_NAME]

    ticket_data = ticket.dict()
    ticket_data["created_date"] = datetime.utcnow()

    inserted = tickets_collection.insert_one(ticket_data)
    ticket_data["id"] = str(inserted.inserted_id)

    return ticket_data


def get_tickets_service(account_id: str, skip: int, limit: int, q: Optional[str], account_view: Optional[int], db, current_user):
    tickets_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

    if q:
        regex_query = {"$regex": q, "$options": "i"}
        query["$or"] = [
            {"subject": regex_query},
            {"questings": regex_query},
            {"description": regex_query}
        ]

    tickets = list(tickets_collection.find(query).skip(skip).limit(limit))
    total_count = tickets_collection.count_documents(query)

    for ticket in tickets:
        ticket["ticket_id"] = str(ticket["_id"])
        ticket.pop("_id", None)
        if "created_date" in ticket and isinstance(ticket["created_date"], datetime):
            ticket["created_date"] = ticket["created_date"].isoformat()

    return {"total_count": total_count, "tickets": tickets}


def read_ticket_service(ticket_id: str, db):
    ticket = db[COLLECTION_NAME].find_one({"_id": str_to_objectid(ticket_id)})
    if ticket:
        ticket["ticket_id"] = str(ticket["_id"])
        ticket.pop("_id", None)
        return ticket
    return None


def update_ticket_service(ticket_id: str, ticket_data: TicketUpdate, db):
    tickets_collection = db[COLLECTION_NAME]
    update_data = {k: v for k, v in ticket_data.dict().items() if v is not None}

    result = tickets_collection.update_one(
        {"_id": str_to_objectid(ticket_id)},
        {"$set": update_data}
    )

    if result.matched_count == 0:
        raise HTTPException(status_code=404, detail="Ticket not found")

    updated = tickets_collection.find_one({"_id": str_to_objectid(ticket_id)})
    updated["id"] = str(updated["_id"])
    updated.pop("_id", None)
    return updated


def delete_ticket_service(ticket_id: str, db):
    tickets_collection = db[COLLECTION_NAME]
    ticket = tickets_collection.find_one({"_id": str_to_objectid(ticket_id)})

    if not ticket:
        raise HTTPException(status_code=404, detail="Ticket not found")

    tickets_collection.delete_one({"_id": str_to_objectid(ticket_id)})
    ticket["id"] = str(ticket["_id"])
    ticket.pop("_id", None)
    return ticket

# Ticket Reply
def create_ticket_reply_service(payload: TicketReplyCreate, 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_ticket_replies_service(ticket_id: str, db):
    collection = db[COLLECTION_NAME]
    query = {"ticket_id": ticket_id}

    replies = list(collection.find(query).sort("created_date", 1))
    total_count = len(replies)

    for reply in replies:
        reply["reply_id"] = str(reply["_id"])
        reply.pop("_id", None)
        if isinstance(reply.get("created_date"), datetime):
            reply["created_date"] = reply["created_date"].isoformat()

    return {"total_count": total_count, "replies": replies}
