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"
RULES_COLLECTION = "geofence_rules"

async def create_mapping_service(data: GeofenceRuleMappingCreate, db):
    record = data.dict()
    record["created_date"] = datetime.utcnow()

    # ✅ Fetch rule details from geofence_rules collection
    if record.get("geofence_rule_id"):
        rule = db[RULES_COLLECTION].find_one({"_id": ObjectId(record["geofence_rule_id"])})
        if rule:
            # ✅ Copy trigger_events and other relevant fields
            record["trigger_events"] = rule.get("trigger_events")
            record["action"] = rule.get("action")
            record["action_message"] = rule.get("action_message")
            record["alert_message"] = rule.get("alert_message")
            record["conditions"] = rule.get("conditions")

    # ✅ Insert mapping record
    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}


