from fastapi import HTTPException
from bson import ObjectId
from datetime import datetime
from typing import Optional, Dict, Any

from app.v1.models.platform.geofence_rule_mapping import (
    GeofenceRuleMappingCreate, GeofenceRuleMappingUpdate
)
from app.v1.libraries.object import str_to_objectid

COLLECTION_NAME = "geofence_rule_mapping"

async def create_mapping_service(data: GeofenceRuleMappingCreate, db):
    record = data.dict()
    record["created_date"] = datetime.utcnow()
    result = db[COLLECTION_NAME].insert_one(record)
    record["_id"] = str(result.inserted_id)
    return record

async def get_mapping_service(account_id: str, db):
    mapping = db[COLLECTION_NAME].find_one({"_id": str_to_objectid(account_id)})
    if not mapping:
        raise HTTPException(status_code=404, detail="Mapping not found")
    mapping["id"] = str(mapping["_id"])
    return mapping

async def update_mapping_service(account_id: str, update: GeofenceRuleMappingUpdate, db):
    update_dict = {k: v for k, v in update.dict(exclude_unset=True).items()}
    await db[COLLECTION_NAME].update_one({"_id": str_to_objectid(account_id)}, {"$set": update_dict})
    return await get_mapping_service(account_id, db)

async def delete_mapping_service(account_id: str, db):
    mapping = await get_mapping_service(account_id, db)
    await db[COLLECTION_NAME].delete_one({"_id": str_to_objectid(account_id)})
    return mapping

def list_mappings_service(account_id: str, skip: int, limit: int, db):
    query = {"account_id": account_id}
    cursor = db["geofence_rule_mapping"].find(query).skip(skip).limit(limit)
    
    mappings = []
    for doc in cursor:  # <- sync loop
        doc["id"] = str(doc["_id"])
        doc["_id"] = str(doc["_id"]) 
        mappings.append(doc)

    total = db["geofence_rule_mapping"].count_documents(query)  # <- also sync
    return {"total_count": total, "users": mappings}


