import uuid from typing import List, Optional from fastapi import APIRouter, Depends, status, Query, Request from sqlalchemy.orm import Session from app.config.database import get_db from app.controllers.auth.subscription_plan_controller import SubscriptionPlanController from app.schemas.auth.subscription_plan_schema import ( SubscriptionPlanCreate, SubscriptionPlanUpdate, SubscriptionPlanResponse, SubscriptionPlanDetailResponse, SubscriptionPlanPaginatedResponse ) from app.middleware.auth_middleware import get_current_user, require_access, User from app.services.system.audit_log_service import AuditLogService from app.helper.helpers import get_client_ip router = APIRouter() @router.post("/create", response_model=SubscriptionPlanResponse, status_code=status.HTTP_201_CREATED) def create_plan( request: Request, plan_data: SubscriptionPlanCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), _ = Depends(require_access("superadmin.plan.create")) ): result = SubscriptionPlanController.create_plan(db, plan_data) AuditLogService.log( db=db, module_name="SubscriptionPlans", action_type="CREATE", entity_id=str(result.id), entity_name=result.name, description=f"Plan '{result.name}' created", performed_by_id=str(current_user.id), performed_by_email=current_user.email, ip_address=get_client_ip(request), new_values=plan_data.model_dump(mode='json') ) return result @router.put("/update/{plan_id}", response_model=SubscriptionPlanResponse) def update_plan( request: Request, plan_id: uuid.UUID, plan_data: SubscriptionPlanUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), _ = Depends(require_access("superadmin.plan.update")) ): result = SubscriptionPlanController.update_plan(db, plan_id, plan_data) AuditLogService.log( db=db, module_name="SubscriptionPlans", action_type="UPDATE", entity_id=str(plan_id), entity_name=result.name, description=f"Plan '{result.name}' updated", performed_by_id=str(current_user.id), performed_by_email=current_user.email, ip_address=get_client_ip(request), new_values=plan_data.model_dump(mode='json') ) return result @router.get("/get/{plan_id}", response_model=SubscriptionPlanDetailResponse) def get_plan( plan_id: uuid.UUID, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), _ = Depends(require_access("superadmin.plan.read")) ): plan = SubscriptionPlanController.get_plan(db, plan_id) return SubscriptionPlanDetailResponse( id=plan.id, name=plan.name, description=plan.description, price=float(plan.price) if plan.price is not None else None, duration_days=plan.duration_days, max_users_allowed=plan.max_users_allowed, is_public=plan.is_public, status=plan.status, created_at=plan.created_at, updated_at=plan.updated_at, access_ids=[pa.access_id for pa in plan.plan_accesses], module_access_ids=[pma.module_access_id for pma in plan.plan_module_accesses] ) @router.get("/list", response_model=SubscriptionPlanPaginatedResponse) def list_plans( page: int = Query(1, ge=1), page_size: int = Query(10, ge=1, le=100), search: Optional[str] = Query(None), filter_names: Optional[List[str]] = Query(None), statuses: Optional[List[str]] = Query(None), visibility: Optional[List[bool]] = Query(None, description="Filter by public/private visibility"), sort_by: Optional[str] = Query(None, description="Sort by name, status, visibility, or price"), sort_order: Optional[str] = Query(None, description="Sort order: asc or desc"), db: Session = Depends(get_db), current_user: User = Depends(get_current_user), _ = Depends(require_access("superadmin.plan.read")) ): return SubscriptionPlanController.get_paginated_plans( db, page, page_size, search, filter_names=filter_names, statuses=statuses, visibility=visibility, sort_by=sort_by, sort_order=sort_order, ) @router.get("/all", response_model=List[SubscriptionPlanResponse]) def all_plans( is_public: Optional[bool] = Query(None), status: Optional[str] = Query(None), db: Session = Depends(get_db), current_user: User = Depends(get_current_user), _ = Depends(require_access("superadmin.plan.read")) ): return SubscriptionPlanController.get_all_plans(db, is_public, status) @router.delete("/delete/{plan_id}") def delete_plan( request: Request, plan_id: uuid.UUID, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), _ = Depends(require_access("superadmin.plan.delete")) ): result = SubscriptionPlanController.delete_plan(db, plan_id) AuditLogService.log( db=db, module_name="SubscriptionPlans", action_type="DELETE", entity_id=str(plan_id), entity_name=str(plan_id), description=f"Plan '{plan_id}' deleted", performed_by_id=str(current_user.id), performed_by_email=current_user.email, ip_address=get_client_ip(request) ) return result