from datetime import datetime
from pymongo.errors import DuplicateKeyError
from app.db import database
from app.v1.integrations.SMTPmailer import send_email
from app.v1.libraries.object import str_to_objectid
from app.v1.models.platform.pricingrules import PricingRule, PricingRules, PricingRuleStatusUpdate
from app.v1.models.saas.usersmodel import User
from app.v1.services.sequence import get_next_sequence_value,convert_enums, get_next_sequence_value_int

from typing import Optional

COLLECTION_NAME = "pricing_rules"
USER_COLLECTION_NAME = "users"
def create_account_service(account: PricingRule, db: database.MongoDB) -> dict:
    account_data = account.dict()
    account_data["created_date"] = datetime.utcnow()    
    account_data["status"] = 'A'    

    accounts_collection = db[COLLECTION_NAME]  
    account_data["pricing_rules_id"] = get_next_sequence_value_int("pricing_rules_id", db) 
    
    try:        
        result = accounts_collection.insert_one(account_data)
    except DuplicateKeyError as e:     

        if "rule_name" in str(e):
            raise ValueError("Pricing rule already exists.")
        else:
            raise ValueError("Duplicate key error.")
    
    # (Optional) Update the user with the new account_id if needed.
    # For example, you could call an update function here:
    # update_user_account_id(account.user_id, str(result.inserted_id), db)
    
    # Send a welcome email
    # subject = "Your Organization has been created!"
    # body = f"Hello {account.name},\n\nThank you for signing up for our platform. We're excited to have you on board!"
    # send_email(subject, body, account.email)
    
    # Prepare and return the created account data
    #account_data["_id"] = str(result.inserted_id)
    account_data["account_id"] = str(result.inserted_id)
    return account_data

def get_accounts_service(
    skip: int, 
    limit: int, 
    q: str, 
    account_type: str, 
    is_active: bool, 
    db: database.MongoDB, 
    current_user: User
) -> dict:
    collection = db[COLLECTION_NAME]
    
    # Example role check: only users with role 1 (e.g., admin , moderators, sales, accounts) can list accounts
    if current_user.get("roles", 0) != 1 and current_user.get("roles", 0) != 2 :
        raise ValueError("Not permitted to view accounts.")
    
    query = {}
    if q:
        regex_query = {"$regex": q, "$options": "i"}
        query["$or"] = [
            {"account_name": regex_query},
            {"name": regex_query},
            {"country": regex_query},
            {"city": regex_query}
        ]
    
    if account_type:
        query["account_type"] = account_type
    
    if is_active is not None:
        query["is_active"] = is_active
    
    accounts_cursor = collection.find(query).skip(skip).limit(limit)
    accounts_list = []
    for account in accounts_cursor:
        account["id"] = str(account["_id"])
        account["account_id"] = str(account["_id"])
        if "created_date" in account and isinstance(account["created_date"], datetime):
            account["created_date"] = account["created_date"].isoformat()
        accounts_list.append(account)
    
    #print(accounts_list)
    total_count = collection.count_documents(query)
    
    return {"total_count": total_count, "accounts": accounts_list}

def get_account_service(account_id: str, db: database.MongoDB) -> dict:
    collection = db[COLLECTION_NAME]
    account = collection.find_one({"_id": str_to_objectid(account_id)})
    if account:
        account["_id"] = str(account["_id"])
        account["account_id"] = account["_id"]
    return account

def update_account_service(
    account_id: str, 
    account_update: PricingRule, 
    current_user: dict, 
    db: database.MongoDB
) -> dict:
    accounts_collection = db[COLLECTION_NAME]
    users_collection = db[USER_COLLECTION_NAME]
    
    existing_account = accounts_collection.find_one({"_id": str_to_objectid(account_id)})
    if not existing_account:
        raise ValueError("Account not found")
    
    user_document = users_collection.find_one({"_id": current_user["_id"]})
    if not user_document:
        raise ValueError("User not found")
    
    # Check if the current user is authorized to update the account
    if str(user_document.get("account_id")) != account_id:
        raise ValueError("Not authorized to update this account")
    
    account_updates = account_update.dict(exclude={"user_id"})
    account_updates.pop("roles", None)  # Remove roles field if present
    
    # For example, only users with role 3 may update the account
    if user_document.get("roles") == 3:  #Role 3== Account Admin
        accounts_collection.update_one({"_id": str_to_objectid(account_id)}, {"$set": account_updates})
    
    # Optionally update user data in the users collection
    user_update_data = {"name": account_update.name, "mobile": account_update.mobile}
    users_collection.update_one({"_id": current_user["_id"]}, {"$set": user_update_data})
    
    updated_account = accounts_collection.find_one({"_id": str_to_objectid(account_id)})
    if updated_account:
        updated_account["_id"] = str(updated_account["_id"])
        updated_account["account_id"] = updated_account["_id"]
        return updated_account
    else:
        raise ValueError("Account not found after update")

def delete_account_service(account_id: str, db: database.MongoDB) -> dict:
    collection = db[COLLECTION_NAME]
    account = collection.find_one({"_id": str_to_objectid(account_id)})
    if not account:
        raise ValueError("Account not found")
    collection.delete_one({"_id": str_to_objectid(account_id)})
    account["_id"] = str(account["_id"])
    account["account_id"] = account["_id"]
    return account

def get_users_service(account_id: str, skip: int, limit: int, q: Optional[str], status: Optional[str], pricing_type: Optional[str], is_active: Optional[bool], db, current_user) -> dict:
    users_collection = db[COLLECTION_NAME]

    print("queryqueryqueryqueryquery RESUTL RESULT")

    query = {}    
    if account_id == "all" and current_user.get("roles" != "1"):
        raise HTTPException(status_code=403, detail="Not permitted to view all users.")

    if account_id != "all":
        query["account_id"] = account_id
    if q:
        regex_query = {"$regex": q, "$options": "i"}
        query["$or"] = [{"name": regex_query}, {"email": regex_query}, {"mobile": regex_query}]
    if is_active is not None:
        query["is_active"] = is_active

    print("queryqueryqueryqueryquery RESUTL RESULT")
    print(query)

    users = list(users_collection.find(query).skip(skip).limit(limit))



    for user in users:
        user["user_id"] = str(user["_id"])        
        user["id"] = str(user["_id"])        
        for field in ['created_date', 'last_login', 'date_of_birth']:
            if field in user and isinstance(user[field], datetime):
                user[field] = user[field].isoformat()
    total_count = users_collection.count_documents(query)
    print("hey boss 11177777777777777777777")
    print({"total_count": total_count, "users": users})
    return {"total_count": total_count, "users": users}

async def update_pricingrules_service(account_id: str, role_update: PricingRule, db: database.MongoDB) -> dict:
    roles_collection: Collection = db[COLLECTION_NAME]
    update_data = role_update.dict(exclude_unset=True)     

    result = roles_collection.update_one({"_id": str_to_objectid(account_id)}, {"$set": update_data})
    
    if result.matched_count == 0:
        return None
    role = roles_collection.find_one({"_id": str_to_objectid(account_id)})
    
    return role

async def update_record_status(account_id: str, role_update: PricingRuleStatusUpdate, db: database.MongoDB) -> Optional[dict]:
    
    roles_collection: Collection = db[COLLECTION_NAME]

    print("update-statusupdate-statusupdate-statusupdate-statusupdate-status 111199999333333333",COLLECTION_NAME)
    # Check if the document exists before updating
    existing_role = roles_collection.find_one({"_id": str_to_objectid(account_id)})

    # if not existing_role:
    #     raise ValueError("Record not found")
    
    # Extract the 'status' from the update data if provided
    update_data = {}
    if role_update.status:
        update_data["status"] = role_update.status    
    
    # Perform the update operation    
    result = roles_collection.update_one({"_id": str_to_objectid(account_id)}, {"$set": update_data})

    print("update-statusupdate-statusupdate-statusupdate-statusupdate-status 111199999333333333 UPDATED",update_data)
    # If no document was modified, return the existing document
    if result.matched_count == 0:
        return existing_role

    # Fetch the updated document and return
    role = roles_collection.find_one({"_id": str_to_objectid(account_id)})    
    return role