from fastapi import HTTPException
from datetime import datetime
from bson import ObjectId
from typing import Optional, Dict, Any
from app.v1.libraries.object import str_to_objectid
from app.v1.models.platform.geofences import GeofenceCreate, GeofenceUpdate
from pymongo import ASCENDING, DESCENDING

COLLECTION_NAME = "geofences"

# async def create_geofence_service(geofence: GeofenceCreate, db):
#     data = geofence.dict()
#     data["created_date"] = datetime.utcnow()
#     result = db[COLLECTION_NAME].insert_one(data)
#     data["id"] = str(result.inserted_id)
#     return data

async def create_geofence_service(geofence: GeofenceCreate, db):
    data = geofence.dict()
    data["created_date"] = datetime.utcnow()

    # Add GeoJSON loc field for MongoDB geospatial
    if data["shape"] == "polygon" and data.get("coordinates"):
        coords = data["coordinates"]
        # Ensure polygon is closed (first == last)
        if coords[0] != coords[-1]:
            coords.append(coords[0])
        data["loc"] = {
            "type": "Polygon",
            "coordinates": [coords]
        }

    result = db["geofences"].insert_one(data)
    data["id"] = str(result.inserted_id)
    return data

async def get_geofence_service(account_id: str, db):
    geofence = db[COLLECTION_NAME].find_one({"_id": str_to_objectid(account_id)})
    if not geofence:
        raise HTTPException(status_code=404, detail="Geofence not found")
    geofence["id"] = str(geofence["_id"])
    return geofence

async def update_geofence_service(account_id: str, update: GeofenceUpdate, 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_geofence_service(account_id, db)

async def delete_geofence_service(account_id: str, db):
    geofence = await get_geofence_service(account_id, db)
    await db[COLLECTION_NAME].delete_one({"_id": str_to_objectid(account_id)})
    return geofence

async def list_geofences_service(skip: int, limit: int, q: Optional[str], shape: Optional[str], db):
    filter_query = {}

    if q:
        regex_query = {"$regex": q, "$options": "i"}
        filter_query["$or"] = [
            {"name": regex_query}
        ]

    if shape:
        filter_query["shape"] = shape

    cursor = db[COLLECTION_NAME].find(filter_query).skip(skip).limit(limit)

    geofences = []
    for item in cursor:
        item["id"] = str(item["_id"])
        geofences.append(item)

    total = db[COLLECTION_NAME].count_documents(filter_query)
    return {"total_count": total, "users": geofences}


