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"),
            "location_coords": wp.get("location_coords"),
            "drop_location_coords": wp.get("drop_location_coords"),
            "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],
    schedule_id: 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 schedule_id:
        query["schedule_id"] = schedule_id  # ✅ Filter by schedule
 
    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}

    results = []
    for doc in cursor:
        # Ensure all required fields exist
        task = {
            "task_id": str(doc["_id"]),
            "account_id": doc.get("account_id"),
            "schedule_id": doc.get("schedule_id"),
            "service_id": doc.get("service_id", ""),   # default if missing
            "customer_id": doc.get("customer_id") or doc.get("customer_info", {}).get("customer_id"),
            "scheduled_start": doc.get("scheduled_start"),
            "scheduled_end": doc.get("scheduled_end"),
            "actual_start": doc.get("actual_start"),
            "actual_end": doc.get("actual_end"),
            "status": doc.get("status", "pending"),    # default value
            "task_mode": doc.get("task_mode", "scheduled"),
            "priority": doc.get("priority", "normal"),
            "roundtrip": doc.get("roundtrip", False),
            "capacity": doc.get("capacity", 0),
            "time_spent": doc.get("time_spent"),
            "distance_travelled": doc.get("distance_travelled"),
            "cost": doc.get("cost"),
            "task_stops": doc.get("task_stops", []),
            "t_id": doc.get("t_id"),
            "created_date": doc.get("created_date"),
            "customer_info": doc.get("customer_info"),
            "workforce_info": doc.get("workforce_info"),
            "fleet_info": doc.get("fleet_info"),
            "variables": doc.get("variables", {}),
            "addons": doc.get("addons", {}),
            "checklist": doc.get("checklist", {}),
            "location": doc.get("location", ""),
            "location_coords": doc.get("location_coords") or None,
            "drop_location": doc.get("drop_location", ""),
            "drop_location_coords": doc.get("drop_location_coords") or None,
            "timing": doc.get("timing", ""),
            "type": doc.get("type", ""),
            "sequence": doc.get("sequence", "")
        }
        results.append(task)

    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
    }

# def update_task_status_service(task_id: str, task_status: int, db: database.MongoDB) -> dict:
#     result = db[COLLECTION].update_one(
#         {"_id": ObjectId(task_id)},
#         {"$set": {"task_status": int(task_status)}}
#     )
#     if result.matched_count == 0:
#         return None
#     return get_task_service(task_id, db)

def update_task_status_service(task_id: str, task_status: int, db: database.MongoDB) -> dict:
    result = db[COLLECTION].update_one(
        {"_id": ObjectId(task_id)},
        {"$set": {"task_status": int(task_status)}}
    )
    if result.matched_count == 0:
        return None
    return get_task_service(task_id, db)   # returns full Task
