from datetime import datetime
from bson import ObjectId
from typing import Optional
from app.db import database
from app.v1.models.platform.tasks import TaskCreate, TaskUpdate
from pymongo.collection import Collection
from app.v1.services.sequence import get_next_sequence_value_int
from pymongo import ASCENDING, DESCENDING

COLLECTION = "tasks"
WAYPOINT_COLLECTION = "waypoints"

def create_task_service(task: TaskCreate, db: database.MongoDB) -> dict:
    data = task.dict()
    data["created_date"] = datetime.utcnow()

    # Fetch and attach customer info
    if data.get("customer_id"):
        customer = db["customers"].find_one({"_id": ObjectId(data["customer_id"])});
        if customer:
            data["customer_info"] = {
                "first_name": customer.get("first_name"),
                "last_name": customer.get("last_name"),
                "phone": customer.get("phone"),
                "email": customer.get("email"),
                "customer_id": str(customer["_id"]),
            }

    # Fetch and attach workforce info
    if data.get("workforce_id"):
        workforce = db["workforce"].find_one({"_id": ObjectId(data["workforce_id"])});
        if workforce:
            data["workforce_info"] = {
                "first_name": workforce.get("first_name"),
                "last_name": workforce.get("last_name"),
                "mobile_number": workforce.get("mobile_number"),
                "email_id": workforce.get("email_id"),
                "workforce_id": str(workforce["_id"]),
            }

    # Fetch and attach fleet info
    if data.get("fleet_id"):
        fleet = db["fleets"].find_one({"_id": ObjectId(data["fleet_id"])});
        if fleet:
            data["fleet_info"] = {
                "fleet_name": fleet.get("fleet_name"),
                "fleet_id": str(fleet["_id"]),
            }
    data["t_id"] = get_next_sequence_value_int("t_id", db)
    result = db[COLLECTION].insert_one(data)
    data["task_id"] = str(result.inserted_id)

    # Extract and insert waypoints
    waypoints_data = data.get("task_stops", [])
    for wp in waypoints_data:
        waypoint = {
            "task_id": str(result.inserted_id),  # Link each waypoint to the task
            "location": wp["location"],
            "type": wp["type"],
            "sequence": wp["sequence"],
            "timing": wp.get("timing"),
            "created_date": datetime.utcnow()
        }
        db[WAYPOINT_COLLECTION].insert_one(waypoint)

    return data

def get_task_service(task_id: str, db: database.MongoDB) -> Optional[dict]:
    task = db[COLLECTION].find_one({"_id": ObjectId(task_id)})
    if task:
        task["task_id"] = str(task["_id"])
        return task
    return None

def list_tasks_service(
    account_id: str,
    service_id: Optional[str],
    task_mode: Optional[str],
    priority: Optional[str],
    roundtrip: Optional[bool],
    from_date: Optional[str],
    to_date: Optional[str],
    customer_id: Optional[str],
    workforce_id: Optional[str],
    fleet_id: Optional[str],
    status: Optional[str],
    q: Optional[str],
    skip: int,
    limit: int,
    sort_by: Optional[str],
    sort_order: Optional[str],
    db: database.MongoDB
) -> dict:
    query = {"account_id": account_id}

    if service_id:
        query["service_id"] = service_id
    if task_mode:
        query["task_mode"] = task_mode
    if priority:
        query["priority"] = priority
    if roundtrip is not None:
        query["roundtrip"] = roundtrip
    if customer_id:
        query["customer_id"] = customer_id
    if workforce_id:
        query["workforce_id"] = workforce_id
    if fleet_id:
        query["fleet_id"] = fleet_id
    if status:
        query["status"] = status  # ✅ Filter by task status
 
    if q:
        regex_query = {"$regex": q, "$options": "i"}
        query["$or"] = [
            {"service_id": regex_query},
            {"tasks": regex_query},
            {"priority": regex_query},
            {"task_mode": regex_query}
        ]

    # Date filtering
    if from_date or to_date:
        date_query = {}
        if from_date:
            date_query["$gte"] = datetime.strptime(from_date, "%Y-%m-%d")
        if to_date:
            date_query["$lte"] = datetime.strptime(to_date, "%Y-%m-%d")
        query["created_date"] = date_query

    # Sorting logic
    sort_fields = {
        "task_mode": "task_mode",
        "priority": "priority",
        "capacity": "capacity",
        "roundtrip": "roundtrip",
        "created_date": "created_date"
    }
    sort_field = sort_fields.get(sort_by, "created_date")  # default to created_date
    sort_direction = ASCENDING if sort_order == "asc" else DESCENDING

    cursor = db[COLLECTION].find(query).sort(sort_field, sort_direction).skip(skip).limit(limit)

    #cursor = db[COLLECTION].find(query)
    results = []
    for doc in cursor:
        doc["task_id"] = str(doc["_id"])
        results.append(doc)

    return {"total_count": len(results), "users": results}

def update_task_service(task_id: str, update: TaskUpdate, db: database.MongoDB) -> dict:
    updates = {k: v for k, v in update.dict().items() if v is not None}
    db[COLLECTION].update_one({"_id": ObjectId(task_id)}, {"$set": updates})
    return get_task_service(task_id, db)

def delete_task_service(task_id: str, db: database.MongoDB) -> dict:
    task = get_task_service(task_id, db)
    if task:
        db[COLLECTION].delete_one({"_id": ObjectId(task_id)})
    return task

def get_task_summary_service(payload: dict, db: database.MongoDB) -> dict:
    query = {}

    if "customer_id" in payload:
        query["customer_id"] = payload["customer_id"]
    elif "workforce_id" in payload:
        query["workforce_id"] = payload["workforce_id"]
    elif "fleet_id" in payload:
        query["fleet_id"] = payload["fleet_id"]
    else:
        raise ValueError("One of customer_id, workforce_id, or fleet_id is required.")

    collection = db["tasks"]

    total = collection.count_documents(query)

    completed = collection.count_documents({**query, "status": "completed"})
    cancelled = collection.count_documents({**query, "status": "cancelled"})

    return {
        "total_tasks": total,
        "completed_tasks": completed,
        "cancelled_tasks": cancelled
    }

