from fastapi import HTTPException
from app.v1.models.platform.customers import CustomerCreate, CustomerUpdate
from app.v1.libraries.object import str_to_objectid
from datetime import datetime
from bson import ObjectId
from typing import Optional,Dict,Any
from app.v1.services.sequence import get_next_sequence_value_int
from pymongo import ASCENDING, DESCENDING

COLLECTION_NAME = "customers"

async def create_customer_service(customer: CustomerCreate, db):
    data = customer.dict()
    data["created_date"] = datetime.utcnow()
    data["updated_date"] = datetime.utcnow()
    
    data["customer_id"] = get_next_sequence_value_int("customer_id", db)

    result = db[COLLECTION_NAME].insert_one(data)
    data["_id"] = str(result.inserted_id)  # Fix this line
    return data

async def get_customer_service(account_id: str, db):
    print("COming get_customer_service")
    customer = db[COLLECTION_NAME].find_one({"_id": str_to_objectid(account_id)})
    if not customer:
        raise HTTPException(status_code=404, detail="Customer not found")
    customer["account_id"] = str(customer["_id"])
    customer["id"] = str(customer["_id"])
    return customer

async def update_customer_service(account_id: str, update: CustomerUpdate, db):
    update_dict = {k: v for k, v in update.dict(exclude_unset=True).items()}
    update_dict["updated_date"] = datetime.utcnow()
    db[COLLECTION_NAME].update_one({"_id": str_to_objectid(account_id)}, {"$set": update_dict})
    return await get_customer_service(account_id, db)

async def delete_customer_service(account_id: str, db):
    customer = await get_customer_service(account_id, db)
    await db[COLLECTION_NAME].delete_one({"_id": str_to_objectid(account_id)})
    return customer

async def list_customers_service(skip: int, limit: int, db):
    cursor = db[COLLECTION_NAME].find().skip(skip).limit(limit)
    customers = []
    async for cust in cursor:
        cust["account_id"] = str(cust["_id"])
        customers.append(cust)
    total = await db[COLLECTION_NAME].count_documents({})
    return {"total_count": total, "users": customers}

def get_customers_service(
    skip: int,
    limit: int,
    q: Optional[str],
    customer_type: Optional[str],
    account_id: Optional[str],
    from_date: Optional[datetime],
    to_date: Optional[datetime],
    sort_by: Optional[str],
    sort_order: Optional[str],
    db,
    current_user: dict
) -> Dict[str, Any]:

    if current_user.get("roles") not in [1, 2, 100]:
        raise HTTPException(status_code=403, detail="Not permitted to view customers.")


    collection = db[COLLECTION_NAME]
    query = {}

    if q:
        regex_query = {"$regex": q, "$options": "i"}
        query["$or"] = [
            {"first_name": regex_query},
            {"last_name": regex_query},
            {"email": regex_query},
            {"phone": regex_query}
        ]
    if customer_type:
        query["customer_type"] = customer_type
    if account_id:
        query["account_id"] = account_id

    # 🗓️ Add created_date range filter
    if from_date or to_date:
        query["created_date"] = {}
        if from_date:
            query["created_date"]["$gte"] = from_date
        if to_date:
            query["created_date"]["$lte"] = to_date

    allowed_sort_fields = {
        "first_name": "first_name",
        "last_name": "last_name",
        "email": "email",
        "phone": "phone",
        "address": "address.street",  # nested field
        "customer_type": "customer_type",
        "created_date": "created_date"
    }

    sort_field = allowed_sort_fields.get(sort_by, "created_date")
    sort_direction = ASCENDING if sort_order == "asc" else DESCENDING

    cursor = collection.find(query).sort(sort_field, sort_direction).skip(skip).limit(limit)

    customers = []
    for customer in cursor:
        customer["id"] = str(customer["_id"])  # Map to alias
        customer.pop("_id", None)              # Remove the raw ObjectId

        customer["created_date"] = customer.get("created_date", datetime.utcnow()).isoformat()
        customer["updated_date"] = customer.get("updated_date", datetime.utcnow()).isoformat()
        customers.append(customer)

    total_count = collection.count_documents(query)
    return {"total_count": total_count, "users": customers}

