
from datetime import datetime
from typing import Optional

from bson import ObjectId

from app.config.DB import db_manager
from app.modules.user.user_model import UserModel


class UserRepository:

    def __init__(self):
        self.collection_name = "users"

    def get_collection(self):
        return db_manager.db[self.collection_name]


    # CREATE USER
    async def create_user(self, user: UserModel):

        collection = self.get_collection()

        user_data = user.model_dump(
            exclude_none=True
        )

        result = await collection.insert_one(
            user_data
        )

        return await collection.find_one(
            {
                "_id": result.inserted_id
            }
        )


    # FIND USER BY PHONE
    async def find_by_phone(
        self,
        country_code: str,
        phone: str
    ) -> Optional[dict]:

        collection = self.get_collection()

        return await collection.find_one(
            {
                "country_code": country_code,
                "phone": phone
            }
        )

   
    # FIND USER BY EMAIL
    async def find_by_email(
        self,
        email: str
    ) -> Optional[dict]:

        collection = self.get_collection()

        return await collection.find_one(
            {
                "email": email
            }
        )

    
    # FIND USER BY GOOGLE ID
    async def find_by_google_id(
        self,
        google_id: str
    ) -> Optional[dict]:

        collection = self.get_collection()

        return await collection.find_one(
            {
                "google_id": google_id
            }
        )


    # FIND USER BY ID
    async def find_by_id(
        self,
        user_id: str
    ) -> Optional[dict]:

        if not ObjectId.is_valid(user_id):
            return None

        collection = self.get_collection()

        return await collection.find_one(
            {
                "_id": ObjectId(user_id)
            }
        )

    # UPDATE USER
    async def update_user(
        self,
        user_id: str,
        update_data: dict
    ):

        if not ObjectId.is_valid(user_id):
            return None

        collection = self.get_collection()

        update_data["updated_at"] = datetime.utcnow()

        await collection.update_one(
            {
                "_id": ObjectId(user_id)
            },
            {
                "$set": update_data
            }
        )

        return await self.find_by_id(user_id)

    # DELETE USER
    async def delete_user(
        self,
        user_id: str
    ) -> bool:

        if not ObjectId.is_valid(user_id):
            return False

        collection = self.get_collection()

        result = await collection.delete_one(
            {
                "_id": ObjectId(user_id)
            }
        )

        return result.deleted_count > 0
    
    
    async def soft_delete_user(
        self,
        user_id: str
    ) -> Optional[dict]:
        
        if not ObjectId.is_valid(user_id):
            return None
        
        collection = self.get_collection()
        
        result = await collection.find_one_and_update(
            {
                "_id": ObjectId(user_id)
            },
            {
                "$set": {
                    "is_active": False,
                    "updated_at": datetime.utcnow()
                }
            },
            return_document=True
        )
        
        return result

        

user_repository = UserRepository()

