from datetime import datetime, timedelta

from app.modules.user_subscription.user_subscription_repository import (
    UserSubscriptionRepository
)
from app.modules.subscription.subscription_repository import (
    SubscriptionRepository
)
from app.modules.user.user_repository import UserRepository
from app.modules.user_subscription.user_subscription_model import (
    UserSubscriptionModel
)


class UserSubscriptionService:

    def __init__(self):
        self.subscription_repo = UserSubscriptionRepository()
        self.plan_repo = SubscriptionRepository()
        self.user_repo = UserRepository()

    def calculate_end_date(self, duration_days: int):
        """
        Plan duration ke according expiry date calculate karega.
        Example:
        30 days -> Today + 30 Days
        """
        return datetime.utcnow() + timedelta(days=duration_days)

    async def activate_subscription(
        self,
        user_id: str,
        plan_id: str
    ):

        user = await self.user_repo.find_by_id(user_id)

        if not user:
            raise Exception("User not found")


        plan = await self.plan_repo.get_plan_by_id(plan_id)

        if not plan:
            raise Exception("Subscription plan not found")


        active_subscription = await self.subscription_repo.get_active_subscription(
            user_id
        )

        if active_subscription:

            # User already premium hai
            if active_subscription["end_date"] > datetime.utcnow():
                raise Exception(
                    "User already has an active subscription."
                )

            # Expired hai
            await self.subscription_repo.expire_subscription(
                active_subscription["_id"]
            )

        start_date = datetime.utcnow()

        end_date = self.calculate_end_date(
            plan["duration_days"]
        )


        subscription = UserSubscriptionModel(
            user_id=user_id,
            plan_id=plan_id,
            start_date=start_date,
            end_date=end_date
        )


        result = await self.subscription_repo.create_subscription(
            subscription
        )

        return result

    async def get_active_subscription(
        self,
        user_id: str
    ):

        subscription = await self.subscription_repo.get_active_subscription(
            user_id
        )

        if not subscription:
            return None

        
        if subscription["end_date"] <= datetime.utcnow():

            await self.subscription_repo.expire_subscription(
                subscription["_id"]
            )

            return None

        return subscription

    async def is_premium(
        self,
        user_id: str
    ):

        subscription = await self.get_active_subscription(
            user_id
        )

        return subscription is not None
    
    
    async def has_active_subscription(
        self,
        user_id: str
    ): 
        
        subscription = await self.subscription_repo.get_valid_subscription(
            user_id
        )
        
        return subscription is not None