from fastapi import APIRouter, HTTPException, status, Depends from typing import List from datetime import datetime from .Model import Subscription from App.Users.Model import User from App.Plans.Model import Plan from .Schema import ( CreateSubscriptionRequest, SubscriptionResponse, BaseResponse, UpdateUsageRequest, SubscriptionListResponse, ) subscription_router = APIRouter(tags=["Subscriptions"]) @subscription_router.post("/subscription/create", response_model=BaseResponse) async def create_subscription(request: CreateSubscriptionRequest): # Check if user exists user = await User.get_or_none(id=request.user_id) if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found" ) # Check if plan exists plan = await Plan.get_or_none(id=request.plan_id) if not plan: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Plan not found" ) # Create new subscription based on plan details expiration_time = datetime.datetime.now() + datetime.timedelta(hours=plan.duration) subscription = await Subscription.create( user=user, plan=plan, duration=plan.duration, download_mb=plan.download_speed * 1024, # Converting Mbps to MB upload_mb=plan.upload_speed * 1024, # Converting Mbps to MB expiration_time=expiration_time, active=True, ) await subscription.save() return BaseResponse( code=200, message="Subscription created successfully", payload={"subscription_id": str(subscription.id)}, ) @subscription_router.get( "/subscription/{subscription_id}", response_model=SubscriptionResponse ) async def get_subscription(subscription_id: str): subscription = await Subscription.get_or_none(id=subscription_id) if not subscription: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Subscription not found" ) remaining_hours = await subscription.time_remaining() return SubscriptionResponse( id=str(subscription.id), user_id=subscription.user_id, plan_id=subscription.plan_id, active=subscription.active, duration=subscription.duration, download_mb=subscription.download_mb, upload_mb=subscription.upload_mb, remaining_hours=remaining_hours, created_time=subscription.created_time, expiration_time=subscription.expiration_time, ) @subscription_router.get( "/subscription/user/{user_id}", response_model=List[SubscriptionResponse] ) async def get_user_subscriptions(user_id: str): user = await User.get_or_none(id=user_id) if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found" ) subscriptions = await Subscription.filter(user_id=user_id) result = [] for subscription in subscriptions: remaining_hours = await subscription.time_remaining() if subscription.active: result.append( SubscriptionResponse( id=str(subscription.id), user_id=subscription.user_id, plan_id=subscription.plan_id, active=subscription.active, duration=subscription.duration, download_mb=subscription.download_mb, upload_mb=subscription.upload_mb, remaining_hours=remaining_hours, created_time=subscription.created_time, expiration_time=subscription.expiration_time, ) ) return result @subscription_router.put( "/subscription/{subscription_id}/update-usage", response_model=BaseResponse ) async def update_usage(subscription_id: str, request: UpdateUsageRequest): subscription = await Subscription.get_or_none(id=subscription_id) if not subscription: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Subscription not found" ) if not await subscription.is_valid(): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Subscription is not active or has expired", ) subscription.download_mb += request.download_mb subscription.upload_mb += request.upload_mb await subscription.save() return BaseResponse( code=200, message="Usage updated successfully", payload={ "total_download_mb": subscription.download_mb, "total_upload_mb": subscription.upload_mb, }, ) @subscription_router.post( "/subscription/{subscription_id}/deactivate", response_model=BaseResponse ) async def deactivate_subscription(subscription_id: str): # Fetch the subscription by ID subscription = await Subscription.get_or_none(id=subscription_id) if not subscription: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Subscription not found" ) # Fetch the associated user user = await subscription.user plan = await subscription.plan if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found for subscription", ) # Deactivate the subscription subscription.active = False await subscription.save() # Deactivate the user associated with this subscription await user.deactivate_user() await user.send_subcription_expired_message(plan=plan) return BaseResponse( code=200, message="Subscription and user deactivated successfully" )