# from app.config.DB import db_manager
# from datetime import datetime, time

# class DeviceLimitRepository:
#     def __init__(self):
#         self.collection_name = "deviceLimits"

#     def get_collection(self):
#         return db_manager.db[self.collection_name]

#     async def check_and_increment_limit(self, device_id: str) -> bool:
#         """
#         True return karega agar limit ke andar hai (Process allowed).
#         False return karega agar 5 ki limit cross ho chuki hai.
#         """
#         collection = self.get_collection()
#         today_start = datetime.combine(datetime.utcnow().date(), time.min)
        
#         # Check karo kya ye device pehle se DB me hai?
#         device = await collection.find_one({"device_id": device_id})
        
#         if not device:
#             # Pehli baar aaya hai, entry banao aur count 1 set karo
#             await collection.insert_one({
#                 "device_id": device_id,
#                 "free_count": 1,
#                 "last_used_at": datetime.utcnow()
#             })
#             return True
            
#         # Agar purana device hai, check karo kya din badal gaya?
#         if device["last_used_at"] < today_start:
#             # Naya din hai! Count reset karke 1 kar do
#             await collection.update_one(
#                 {"device_id": device_id},
#                 {"$set": {"free_count": 1, "last_used_at": datetime.utcnow()}}
#             )
#             return True
            
#         # Agar same day hai, check karo ki 5 se zyada to nahi ho gaya
#         if device["free_count"] >= 5:
#             return False # Limit reached!
            
#         # Limit ke andar hai, to count +1 badha do
#         await collection.update_one(
#             {"device_id": device_id},
#             {"$inc": {"free_count": 1}, "$set": {"last_used_at": datetime.utcnow()}}
#         )
#         return True



from datetime import datetime, time

from app.config.DB import db_manager


class DeviceLimitRepository:

    def __init__(self):
        self.collection_name = "deviceLimits"

        # Normal free images per day
        self.FREE_LIMIT = 3

    def get_collection(self):
        return db_manager.db[self.collection_name]

    # ============================================================
    # GET DEVICE
    # ============================================================

    async def get_device(self, device_id: str):

        collection = self.get_collection()

        return await collection.find_one(
            {
                "device_id": device_id
            }
        )

    # ============================================================
    # CREATE DEVICE
    # ============================================================

    async def create_device(self, device_id: str):

        collection = self.get_collection()

        now = datetime.utcnow()

        device_data = {
            "device_id": device_id,

            # Normal free image usage
            "free_count": 0,

            # Extra images earned through rewarded ads
            "reward": 0,

            # Number of rewarded ads completed
            "adCount": 0,

            "last_used_at": now,

            "created_at": now,

            "updated_at": now
        }

        await collection.insert_one(device_data)

        return device_data

    # ============================================================
    # RESET DAILY USAGE
    # ============================================================

    async def reset_daily_usage(
        self,
        device_id: str
    ):

        collection = self.get_collection()

        now = datetime.utcnow()

        await collection.update_one(

            {
                "device_id": device_id
            },

            {
                "$set": {
                    "free_count": 0,
                    "reward": 0,
                    "last_used_at": now,
                    "updated_at": now
                }
            }
        )

    # ============================================================
    # CHECK + USE IMAGE
    # ============================================================

    async def check_and_increment_limit(
        self,
        device_id: str
    ) -> dict:

        collection = self.get_collection()

        now = datetime.utcnow()

        today_start = datetime.combine(
            now.date(),
            time.min
        )

        # --------------------------------------------------------
        # Find device
        # --------------------------------------------------------

        device = await collection.find_one(
            {
                "device_id": device_id
            }
        )

        # --------------------------------------------------------
        # New device
        # --------------------------------------------------------

        if not device:

            device_data = {
                "device_id": device_id,

                "free_count": 1,

                "reward": 0,

                "adCount": 0,

                "last_used_at": now,

                "created_at": now,

                "updated_at": now
            }

            await collection.insert_one(
                device_data
            )

            return {
                "allowed": True,
                "source": "free",
                "free_count": 1,
                "reward": 0,
                "adCount": 0,
                "free_limit": self.FREE_LIMIT,
                "remaining_free": self.FREE_LIMIT - 1
            }

        # --------------------------------------------------------
        # Daily reset
        # --------------------------------------------------------

        if device.get("last_used_at") < today_start:

            result = await collection.update_one(

                {
                    "device_id": device_id
                },

                {
                    "$set": {
                        "free_count": 1,
                        "reward": 0,
                        "last_used_at": now,
                        "updated_at": now
                    }
                }
            )

            return {
                "allowed": True,
                "source": "free",
                "free_count": 1,
                "reward": 0,
                "adCount": device.get("adCount", 0),
                "free_limit": self.FREE_LIMIT,
                "remaining_free": self.FREE_LIMIT - 1
            }

        # --------------------------------------------------------
        # Current values
        # --------------------------------------------------------

        free_count = device.get(
            "free_count",
            0
        )

        reward = device.get(
            "reward",
            0
        )

        ad_count = device.get(
            "adCount",
            0
        )

        # --------------------------------------------------------
        # FREE IMAGE AVAILABLE
        # --------------------------------------------------------

        if free_count < self.FREE_LIMIT:

            new_free_count = free_count + 1

            await collection.update_one(

                {
                    "device_id": device_id
                },

                {
                    "$set": {
                        "free_count": new_free_count,
                        "last_used_at": now,
                        "updated_at": now
                    }
                }
            )

            return {
                "allowed": True,
                "source": "free",
                "free_count": new_free_count,
                "reward": reward,
                "adCount": ad_count,
                "free_limit": self.FREE_LIMIT,
                "remaining_free": max(
                    0,
                    self.FREE_LIMIT - new_free_count
                )
            }

        # --------------------------------------------------------
        # REWARD IMAGE AVAILABLE
        # --------------------------------------------------------

        if reward > 0:

            new_reward = reward - 1

            await collection.update_one(

                {
                    "device_id": device_id,
                    "reward": {
                        "$gt": 0
                    }
                },

                {
                    "$inc": {
                        "reward": -1
                    },

                    "$set": {
                        "last_used_at": now,
                        "updated_at": now
                    }
                }
            )

            return {
                "allowed": True,
                "source": "reward",
                "free_count": free_count,
                "reward": new_reward,
                "adCount": ad_count,
                "free_limit": self.FREE_LIMIT,
                "remaining_free": 0
            }

        # --------------------------------------------------------
        # LIMIT REACHED
        # --------------------------------------------------------

        return {
            "allowed": False,
            "source": None,
            "free_count": free_count,
            "reward": reward,
            "adCount": ad_count,
            "free_limit": self.FREE_LIMIT,
            "remaining_free": 0,
            "show_reward_ad": True
        }

    # ============================================================
    # REWARD AFTER AD
    # ============================================================

    async def add_reward(
        self,
        device_id: str
    ) -> dict:

        collection = self.get_collection()

        now = datetime.utcnow()

        device = await collection.find_one(
            {
                "device_id": device_id
            }
        )

        # --------------------------------------------------------
        # Device doesn't exist
        # --------------------------------------------------------

        if not device:

            device_data = {
                "device_id": device_id,

                "free_count": 0,

                "reward": 1,

                "adCount": 1,

                "last_used_at": now,

                "created_at": now,

                "updated_at": now
            }

            await collection.insert_one(
                device_data
            )

            return {
                "success": True,
                "reward": 1,
                "adCount": 1
            }

        # --------------------------------------------------------
        # Add reward
        # --------------------------------------------------------

        await collection.update_one(

            {
                "device_id": device_id
            },

            {
                "$inc": {
                    "reward": 1,
                    "adCount": 1
                },

                "$set": {
                    "updated_at": now
                }
            }
        )

        updated_device = await collection.find_one(
            {
                "device_id": device_id
            }
        )

        return {
            "success": True,

            "reward": updated_device.get(
                "reward",
                0
            ),

            "adCount": updated_device.get(
                "adCount",
                0
            )
        }

    # ============================================================
    # GET USAGE
    # ============================================================

    async def get_usage(
        self,
        device_id: str
    ):

        device = await self.get_device(
            device_id
        )

        # --------------------------------------------------------
        # New device
        # --------------------------------------------------------

        if not device:

            return {
                "device_id": device_id,
                "free_count": 0,
                "reward": 0,
                "adCount": 0,
                "free_limit": self.FREE_LIMIT,
                "remaining_free": self.FREE_LIMIT
            }

        # --------------------------------------------------------
        # Daily reset check
        # --------------------------------------------------------

        now = datetime.utcnow()

        today_start = datetime.combine(
            now.date(),
            time.min
        )

        if device.get("last_used_at") < today_start:

            await self.reset_daily_usage(
                device_id
            )

            return {
                "device_id": device_id,
                "free_count": 0,
                "reward": 0,
                "adCount": device.get(
                    "adCount",
                    0
                ),
                "free_limit": self.FREE_LIMIT,
                "remaining_free": self.FREE_LIMIT
            }

        # --------------------------------------------------------
        # Existing device
        # --------------------------------------------------------

        free_count = device.get(
            "free_count",
            0
        )

        reward = device.get(
            "reward",
            0
        )

        ad_count = device.get(
            "adCount",
            0
        )

        return {
            "device_id": device_id,

            "free_count": free_count,

            "reward": reward,

            "adCount": ad_count,

            "free_limit": self.FREE_LIMIT,

            "remaining_free": max(
                0,
                self.FREE_LIMIT - free_count
            )
        }