from datetime import datetime
from bson import ObjectId
from app.v1.models.platform.schedules import ScheduleCreate, ScheduleUpdate,ScheduleWithTasksCreate,ShiftStatusCreate, ShiftStatusUpdate
from app.db import database
from typing import Optional
from pymongo import ASCENDING, DESCENDING
from app.v1.services.sequence import get_next_sequence_value_int
from app.utils.connections import connected_clients
import asyncio

from app.utils.notifications import send_push_notification

SCHEDULES_COLLECTION = "schedules"
WORKFORCE_COLLECTION = "workforce"
FLEETS_COLLECTION = "fleets"
TASKS_COLLECTION = "tasks"
SHIFT_STATUS_COLLECTION = "shift_status"

def create_schedule_service(schedule: ScheduleCreate, db: database.MongoDB) -> dict:
    data = schedule.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["sch_id"] = get_next_sequence_value_int("sch_id", db)

    result = db[SCHEDULES_COLLECTION].insert_one(data)
    data["schedule_id"] = str(result.inserted_id)
    return data

def get_schedule_service(schedule_id: str, db: database.MongoDB) -> dict:
    schedule = db[SCHEDULES_COLLECTION].find_one({"_id": ObjectId(schedule_id)})
    if schedule:
        schedule["schedule_id"] = str(schedule["_id"])
        return schedule
    return None

# def list_schedules_service(account_id: str, db: database.MongoDB) -> dict:
#     query = {"account_id": account_id}
#     cursor = db[SCHEDULES_COLLECTION].find(query)
#     schedules = []
#     for item in cursor:
#         item["schedule_id"] = str(item["_id"])
#         schedules.append(item)
#     return {"total_count": len(schedules), "schedules": schedules}

def update_schedule_service(schedule_id: str, update: ScheduleUpdate, db: database.MongoDB) -> dict:
    updates = {k: v for k, v in update.dict().items() if v is not None}
    db[SCHEDULES_COLLECTION].update_one({"_id": ObjectId(schedule_id)}, {"$set": updates})
    return get_schedule_service(schedule_id, db)

def delete_schedule_service(schedule_id: str, db: database.MongoDB) -> dict:
    schedule = get_schedule_service(schedule_id, db)
    if schedule:
        db[SCHEDULES_COLLECTION].delete_one({"_id": ObjectId(schedule_id)})
    return schedule


def list_schedules_service(
    account_id: str,    
    skip: int = 0,
    limit: int = 10,
    search_query: Optional[str] = None,
    status: Optional[str] = None,
    start_date_from: Optional[str] = None,
    start_date_to: Optional[str] = None,
    customer_id: Optional[str] = None,
    workforce_id: Optional[str] = None,
    trip_type: Optional[int] = None,
    fleet_id: Optional[str] = None,
    sort_by: Optional[str] = "created_date",
    order_by: Optional[int] = 1,
    db=None
):

    query = {"account_id": account_id}

    if search_query:
        query["schedule_name"] = {"$regex": search_query, "$options": "i"}

    if status:
        query["status"] = status

    # Add date range filter
    if start_date_from or start_date_to:
        date_filter = {}
        if start_date_from:
            date_filter["$gte"] = datetime.strptime(start_date_from, "%Y-%m-%d")
        if start_date_to:
            date_filter["$lte"] = datetime.strptime(start_date_to, "%Y-%m-%d")
        query["created_date"] = date_filter

    if customer_id:
        query["customer_id"] = customer_id
    if workforce_id:
        query["workforce_id"] = workforce_id
    if fleet_id:
        query["fleet_id"] = fleet_id

    #sort_order = ASCENDING if order_by == 0 else DESCENDING
    # cursor = db["schedules"].find(query).sort("_id", sort_order).skip(skip).limit(limit)
    # total_count = db["schedules"].count_documents(query)

    # ✅ Apply trip_type filter for travel_status
    if trip_type is not None:
        if trip_type == 0:
            query["travel_status"] = {"$ne": 2}  # not cancelled
        elif trip_type == 1:
            query["$or"] = [
                {"travel_status": 2},
                {"travel_status": 9}
            ]

    # Define allowed fields
    allowed_sort_fields = {
        "schedule_name": "schedule_name",
        "description": "description",
        "start_time": "start_time",
        "end_time": "end_time",
        "created_date": "created_date"
    }

    sort_field = allowed_sort_fields.get(sort_by, "created_date")
    sort_direction = ASCENDING if order_by == 0 else DESCENDING
    print("queryqueryqueryquery")
    print(query)
    cursor = db["schedules"].find(query).sort(sort_field, sort_direction).skip(skip).limit(limit)
    total_count = db["schedules"].count_documents(query)

    results = []
    for doc in cursor:
        doc["schedule_id"] = str(doc["_id"])
        results.append(doc)

    return {"total_count": total_count, "schedules": results}

# def assign_schedule_service(schedule_id: str, account_id: str, workforce_id: str, db: database.MongoDB) -> bool:
#     schedule = db["schedules"].find_one({"_id": ObjectId(schedule_id), "account_id": account_id})
#     workforce = db["workforce"].find_one({"_id": ObjectId(workforce_id), "account_id": account_id})

#     if not schedule or not workforce:
#         return False

#     db[SCHEDULES_COLLECTION].update_one(
#         {"_id": ObjectId(schedule_id)},
#         {"$set": {"workforce_id": workforce_id}}
#     )

#     db[WORKFORCE_COLLECTION].update_one(
#         {"_id": ObjectId(workforce_id)},
#         {"$set": {"schedule_id": schedule_id}}
#     )

#     db[FLEETS_COLLECTION].update_many(
#         {"schedule_id": schedule_id},
#         {"$set": {"workforce_id": workforce_id}}
#     )

#     return True

# def assign_schedule_service(schedule_id: str, account_id: str, workforce_id: str, db: database.MongoDB) -> bool:
#     schedule = db["schedules"].find_one({"_id": ObjectId(schedule_id), "account_id": account_id})
#     workforce = db["workforce"].find_one({"_id": ObjectId(workforce_id), "account_id": account_id})

#     if not schedule or not workforce:
#         return False

#     db[SCHEDULES_COLLECTION].update_one(
#         {"_id": ObjectId(schedule_id)},
#         {"$set": {"workforce_id": workforce_id}}
#     )

#     db[WORKFORCE_COLLECTION].update_one(
#         {"_id": ObjectId(workforce_id)},
#         {"$set": {"schedule_id": schedule_id}}
#     )

#     db[FLEETS_COLLECTION].update_many(
#         {"schedule_id": schedule_id},
#         {"$set": {"workforce_id": workforce_id}}
#     )
#     db[TASKS_COLLECTION].update_many(
#         {"schedule_id": schedule_id},
#         {"$set": {"workforce_id": workforce_id}}
#     )

#     # 🔔 Send socket notification to workforce if connected
#     websocket = connected_clients.get(workforce_id)
#     if websocket:
#         notification = {
#             "type": "schedule_assignment",
#             "message": "A new schedule has been assigned to you.",
#             "schedule_id": schedule_id
#         }

#         try:
#             # Run send in background
#             asyncio.create_task(websocket.send_text(json.dumps(notification)))
#         except Exception as e:
#             print(f"WebSocket send error for workforce {workforce_id}: {e}")

#     return True

# Updating all details schedule and workforce
def assign_schedule_service(schedule_id: str, account_id: str, workforce_id: str, db: database.MongoDB) -> bool:
    schedule = db["schedules"].find_one({"_id": ObjectId(schedule_id), "account_id": account_id})
    workforce = db["workforce"].find_one({"_id": ObjectId(workforce_id), "account_id": account_id})

    if not schedule or not workforce:
        return False

    # Extract workforce info
    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"),
        "gender": workforce.get("gender"),
        "emergency_contact": workforce.get("emergency_contact"),
        "address": workforce.get("address"),
        "blood_group": workforce.get("blood_group"),
        "is_human": workforce.get("is_human"),
        "photo": workforce.get("photo"),
    }

    # 🔎 Find assigned fleet from workforce_vehicle
    workforce_vehicle = db["workforce_vehicle"].find_one(
        {"workforce_id": workforce_id, "status": True}
    )

    fleet_info = None
    if workforce_vehicle and workforce_vehicle.get("vehicle_id"):
        fleet = db[FLEETS_COLLECTION].find_one({"_id": ObjectId(workforce_vehicle["vehicle_id"])})
        if fleet:
            fleet_info = {
                "fleet_name": fleet.get("fleet_name"),
                "vehicle_id": str(fleet.get("_id")),
                "registration_number": fleet.get("registration_number"),
                "color": fleet.get("color"),
                "vehicle_image": fleet.get("vehicle_image"),
                "fuel_type": fleet.get("fuel_type"),
                "vehicle_type": fleet.get("vehicle_type"),
            }

    # Update schedules with workforce_id, workforce_info, and fleet_info
    update_fields = {"workforce_id": workforce_id, "workforce_info": workforce_info}
    if fleet_info:
        update_fields["fleet_info"] = fleet_info

    db[SCHEDULES_COLLECTION].update_one(
        {"_id": ObjectId(schedule_id)},
        {"$set": update_fields}
    )

    # Update workforce with assigned schedule
    db[WORKFORCE_COLLECTION].update_one(
        {"_id": ObjectId(workforce_id)},
        {"$set": {"schedule_id": schedule_id}}
    )

    # Update fleets collection (only workforce_id, keep as before)
    db[FLEETS_COLLECTION].update_many(
        {"schedule_id": schedule_id},
        {"$set": {"workforce_id": workforce_id}}
    )

    # Update tasks with workforce_id, workforce_info, and fleet_info
    task_update_fields = {"workforce_id": workforce_id, "workforce_info": workforce_info}
    if fleet_info:
        task_update_fields["fleet_info"] = fleet_info

    db[TASKS_COLLECTION].update_many(
        {"schedule_id": schedule_id},
        {"$set": task_update_fields}
    )

    # ✅ Send FCM push notification to workforce (if token exists)
    fcm_token = workforce.get("fcm_token")
    if fcm_token:
        send_push_notification(
            token=fcm_token,
            title="New Schedule Assigned",
            body=f"You’ve been assigned a new schedule: {schedule.get('schedule_name')}",
            data={"schedule_id": schedule_id}
        )
    else:
        print(f"⚠️ Workforce {workforce_id} has no FCM token registered.")

    # 🔔 Send socket notification to workforce if connected
    # websocket = connected_clients.get(workforce_id)
    # if websocket:
    #     notification = {
    #         "type": "schedule_assignment",
    #         "message": "A new schedule has been assigned to you.",
    #         "schedule_id": schedule_id
    #     }
    #     try:
    #         asyncio.create_task(websocket.send_text(json.dumps(notification)))
    #     except Exception as e:
    #         print(f"WebSocket send error for workforce {workforce_id}: {e}")

    return True

def search_schedules_select_service(
    account_id: str,
    search_query: Optional[str] = None,
    db=None
):
    query = {"account_id": account_id}

    if search_query:
        query["schedule_name"] = {"$regex": search_query, "$options": "i"}

    cursor = db["schedules"].find(query, {"_id": 1, "schedule_name": 1}).limit(50)

    results = []
    for doc in cursor:
        results.append({
            "schedule_id": str(doc["_id"]),
            "schedule_name": doc["schedule_name"]
        })

    return results

def update_travel_status_service(schedule_id: str, travel_status: int, db: database.MongoDB) -> dict:
    result = db[SCHEDULES_COLLECTION].update_one(
        {"_id": ObjectId(schedule_id)},
        {"$set": {"travel_status": int(travel_status)}}
    )
    if result.matched_count == 0:
        return None
    return get_schedule_service(schedule_id, db)

# def create_schedule_with_tasks_service(payload: ScheduleWithTasksCreate, db: database.MongoDB) -> dict:
#     # 1. Generate schedule name
#     schedule_name = f"movex_{datetime.utcnow().strftime('%Y%m%d_%H%M%S')}"

#     # 2. Create schedule without tasks
#     from . import schedules as schedule_service
#     schedule_data = ScheduleCreate(
#         account_id=payload.account_id,
#         schedule_name=schedule_name,
#         description=payload.description,
#         start_time=payload.start_time,
#         end_time=payload.end_time,
#         task_ids=[]
#     )
#     schedule = schedule_service.create_schedule_service(schedule_data, db)

#     # 3. Create task stops
#     stops_data = payload.task_stops if payload.task_stops else [
#         {
#             "location": "Default Pickup Location",
#             "type": "pickup",
#             "sequence": 1,
#             "timing": None
#         },
#         {
#             "location": "Default Drop Location",
#             "type": "dropoff",
#             "sequence": 2,
#             "timing": None
#         }
#     ]

#     task_ids = []
#     for stop in stops_data:
#         stop_doc = {
#             "schedule_id": schedule["schedule_id"],
#             "account_id": payload.account_id,
#             "location": stop.location,
#             "type": stop.type,
#             "sequence": stop.sequence,
#             "timing": stop.timing,
#             "created_date": datetime.utcnow()
#         }
#         result = db[TASKS_COLLECTION].insert_one(stop_doc)
#         task_ids.append(str(result.inserted_id))

#     # 4. Update schedule with task_ids
#     db[SCHEDULES_COLLECTION].update_one(
#         {"_id": ObjectId(schedule["schedule_id"])},
#         {"$set": {"task_ids": task_ids}}
#     )
#     schedule["task_ids"] = task_ids

#     return schedule

def create_schedule_with_tasks_service_bkp(payload: ScheduleWithTasksCreate, db: database.MongoDB) -> dict: 
    # 1. Generate schedule name
    schedule_name = f"movex_{datetime.utcnow().strftime('%Y%m%d_%H%M%S')}"

    # 2. Create schedule without tasks
    from . import schedules as schedule_service
    schedule_data = ScheduleCreate(
        account_id=payload.account_id,
        schedule_name=schedule_name,
        description=payload.description,
        start_time=payload.start_time,
        end_time=payload.end_time,
        task_ids=[]
    )
    schedule = schedule_service.create_schedule_service(schedule_data, db)

    # 3. Create task stops
    stops_data = payload.task_stops if payload.task_stops else [
        {
            "location": "Default Pickup Location",
            "location_coords": "Default Pickup Coordinates",
            "drop_location_coords": "Default Pickup Coordinates",
            "type": "pickup",
            "sequence": 1,
            "timing": None
        },
        {
            "location": "Default Drop Location",
            "location_coords": "Default Pickup Coordinates",
            "drop_location_coords": "Default Pickup Coordinates",
            "type": "dropoff",
            "sequence": 2,
            "timing": None
        }
    ]

    task_ids = []
    for stop in stops_data:
        stop_doc = {
            "schedule_id": schedule["schedule_id"],
            "account_id": payload.account_id,
            "location": stop.location,
            "location_coords": stop.location_coords,
            "drop_location_coords": stop.drop_location_coords,
            "type": stop.type,
            "sequence": stop.sequence,
            "timing": stop.timing,
            "created_date": datetime.utcnow()
        }

        # ✅ Attach customer details if customer_id is passed
        if getattr(stop, "customer_id", None):
            customer = db["customers"].find_one({"_id": ObjectId(stop.customer_id)})
            if customer:
                stop_doc["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"]),
                }

        result = db[TASKS_COLLECTION].insert_one(stop_doc)
        task_ids.append(str(result.inserted_id))

    # 4. Update schedule with task_ids
    db[SCHEDULES_COLLECTION].update_one(
        {"_id": ObjectId(schedule["schedule_id"])},
        {"$set": {"task_ids": task_ids}}
    )
    schedule["task_ids"] = task_ids

    return schedule

# def create_schedule_with_tasks_service(payload: ScheduleWithTasksCreate, db: database.MongoDB) -> dict:
#     from . import schedules as schedule_service
#     print("47104710471047104710471047104710")
#     # 1. Generate schedule name
#     schedule_name = f"movex_{datetime.utcnow().strftime('%Y%m%d_%H%M%S')}"

#     # 2. Create schedule (without tasks yet)
#     schedule_data = ScheduleCreate(
#         account_id=payload.account_id,
#         schedule_name=schedule_name,
#         description=payload.description,
#         start_time=payload.start_time,
#         end_time=payload.end_time,
#         task_ids=[]
#     )
#     schedule = schedule_service.create_schedule_service(schedule_data, db)

#     # 3. Prepare stops (from payload or defaults)
#     stops_data = payload.task_stops if payload.task_stops else [
#         {
#             "location": "Default Pickup Location",
#             "location_coords": "Default Pickup Coordinates",
#             "drop_location_coords": "Default Pickup Coordinates",
#             "type": "pickup",
#             "sequence": 1,
#             "timing": None
#         },
#         {
#             "location": "Default Drop Location",
#             "location_coords": "Default Pickup Coordinates",
#             "drop_location_coords": "Default Pickup Coordinates",
#             "type": "dropoff",
#             "sequence": 2,
#             "timing": None
#         }
#     ]

#     task_ids = []
#     task_stops = []

#     for stop in stops_data:
#         stop_doc = {
#             "schedule_id": schedule["schedule_id"],
#             "account_id": payload.account_id,
#             "location": stop.location,
#             "location_coords": stop.location_coords,
#             "drop_location_coords": stop.drop_location_coords,
#             "type": stop.type,
#             "sequence": stop.sequence,
#             "timing": stop.timing,
#             "created_date": datetime.utcnow()
#         }

#         # ✅ Attach customer details if available
#         if getattr(stop, "customer_id", None):
#             customer = db["customers"].find_one({"_id": ObjectId(stop.customer_id)})
#             if customer:
#                 stop_doc["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"]),
#                 }

#         # Insert into tasks collection
#         result = db[TASKS_COLLECTION].insert_one(stop_doc)
#         task_ids.append(str(result.inserted_id))

#         # Also add to embedded task_stops array
#         task_stops.append({
#             "location": stop.location,
#             "location_coords": stop.location_coords,
#             "drop_location_coords": stop.drop_location_coords,
#             "type": stop.type,
#             "sequence": stop.sequence,
#             "timing": stop.timing
#         })

#     # 4. Update schedule with task_ids + task_stops
#     db[SCHEDULES_COLLECTION].update_one(
#         {"_id": ObjectId(schedule["schedule_id"])},
#         {"$set": {
#             "task_ids": task_ids,
#             "task_stops": task_stops
#         }}
#     )

#     # Return full schedule with task_stops
#     schedule["task_ids"] = task_ids
#     schedule["task_stops"] = task_stops

#     return schedule

def create_schedule_with_tasks_service(payload: ScheduleWithTasksCreate, db: database.MongoDB) -> dict:
    from . import schedules as schedule_service

    # 1. Generate schedule name
    schedule_name = f"movex_{datetime.utcnow().strftime('%Y%m%d_%H%M%S')}"

    # 2. Create schedule (without tasks yet)
    schedule_data = ScheduleCreate(
        account_id=payload.account_id,
        schedule_name=schedule_name,
        description=payload.description,
        start_time=payload.start_time,
        end_time=payload.end_time,
        task_ids=[],
        addons_name=payload.addons_name
    )
    schedule = schedule_service.create_schedule_service(schedule_data, db)

    # 3. Prepare stops (from payload or defaults)
    stops_data = payload.task_stops or []

    task_ids = []
    task_stops = []

    for stop in stops_data:
        # ✅ Convert Pydantic models to dicts
        stop_doc = {
            "schedule_id": schedule["schedule_id"],
            "account_id": payload.account_id,
            "addons_name": payload.addons_name, 
            "location": stop.location,
            "location_coords": stop.location_coords.dict() if stop.location_coords else None,
            "drop_location": stop.drop_location,
            "drop_location_coords": stop.drop_location_coords.dict() if stop.drop_location_coords else None,
            "type": stop.type,
            "sequence": int(stop.sequence),  # ensure int, payload had "1" as string
            "timing": stop.timing,
            "created_date": datetime.utcnow(),
            "skills": stop.skills if stop.skills else []
        }

        # ✅ Attach customer details if available
        if stop.customer_id:
            customer = db["customers"].find_one({"_id": ObjectId(stop.customer_id)})
            if customer:
                stop_doc["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"]),
                }

        # ✅ Insert into tasks collection
        result = db[TASKS_COLLECTION].insert_one(stop_doc)
        task_ids.append(str(result.inserted_id))

        # ✅ Add to embedded task_stops array (dict, not Pydantic object)
        task_stops.append({
            "location": stop.location,
            "location_coords": stop.location_coords.dict() if stop.location_coords else None,
            "drop_location": stop.drop_location,
            "drop_location_coords": stop.drop_location_coords.dict() if stop.drop_location_coords else None,
            "type": stop.type,
            "sequence": int(stop.sequence),
            "timing": stop.timing,
            "skills": stop.skills if stop.skills else []
        })

    # 4. Update schedule with task_ids + task_stops
    db[SCHEDULES_COLLECTION].update_one(
        {"_id": ObjectId(schedule["schedule_id"])},
        {"$set": {
            "task_ids": task_ids,
            "task_stops": task_stops,
            "addons_name": payload.addons_name,
            "vehicle_model_id": payload.vehicle_model_id,
            "priority_type": payload.priority_type  
        }}
    )

    # Return full schedule with task_stops
    schedule["task_ids"] = task_ids
    schedule["task_stops"] = task_stops
    schedule["addons_name"] = payload.addons_name
    schedule["vehicle_model_id"] = payload.vehicle_model_id
    schedule["priority_type"] = payload.priority_type

    return schedule

def create_shift_status_service(payload: ShiftStatusCreate, db: database.MongoDB) -> dict:
    data = payload.dict()
    data["created_date"] = datetime.utcnow()
    data["updated_date"] = datetime.utcnow()

    result = db[SHIFT_STATUS_COLLECTION].insert_one(data)
    data["id"] = str(result.inserted_id)

    # ✅ Optionally update workforce table to reflect current shift
    db["workforce"].update_one(
        {"_id": ObjectId(payload.workforce_id)},
        {"$set": {"shift_status": payload.shift_status, "updated_date": datetime.utcnow()}}
    )

    return data


def get_shift_status_service(shift_status_id: str, db: database.MongoDB) -> Optional[dict]:
    result = db[SHIFT_STATUS_COLLECTION].find_one({"_id": ObjectId(shift_status_id)})
    if not result:
        return None
    result["id"] = str(result["_id"])
    return result


def list_shift_status_service(account_id: str, schedule_id: str, db: database.MongoDB) -> dict:
    query = {"account_id": account_id, "schedule_id": schedule_id}
    cursor = db[SHIFT_STATUS_COLLECTION].find(query).sort("created_date", -1)
    results = []
    for doc in cursor:
        doc["id"] = str(doc["_id"])
        results.append(doc)

    return {"total_count": len(results), "shift_statuses": results}


def update_shift_status_service(shift_status_id: str, update_data: ShiftStatusUpdate, db: database.MongoDB) -> Optional[dict]:
    updates = {k: v for k, v in update_data.dict().items() if v is not None}
    updates["updated_date"] = datetime.utcnow()

    result = db[SHIFT_STATUS_COLLECTION].update_one(
        {"_id": ObjectId(shift_status_id)},
        {"$set": updates}
    )
    if result.matched_count == 0:
        return None

    updated = db[SHIFT_STATUS_COLLECTION].find_one({"_id": ObjectId(shift_status_id)})
    updated["id"] = str(updated["_id"])
    return updated


def delete_shift_status_service(shift_status_id: str, db: database.MongoDB) -> Optional[dict]:
    item = db[SHIFT_STATUS_COLLECTION].find_one({"_id": ObjectId(shift_status_id)})
    if not item:
        return None
    db[SHIFT_STATUS_COLLECTION].delete_one({"_id": ObjectId(shift_status_id)})
    return {"id": shift_status_id, "message": "Shift status deleted successfully"}