from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from typing import List from app.db.base import get_db from app.models.user import User from app.models.ministry import ( Ministry, MinistryMember, MinistryActivity, MinistryRequest, MinistryRole, ) from app.schemas.ministry import ( MinistryCreate, MinistryUpdate, MinistryResponse, MinistryMemberResponse, MinistryActivityCreate, MinistryActivityResponse, MinistryJoinRequest, MinistryRequestResponse, ) from app.api.auth import get_current_user router = APIRouter() @router.post("/", response_model=MinistryResponse) def create_ministry( ministry: MinistryCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Create a new ministry""" db_ministry = Ministry(**ministry.dict(), leader_id=current_user.id) db.add(db_ministry) db.commit() db.refresh(db_ministry) # Add creator as leader member = MinistryMember( ministry_id=db_ministry.id, user_id=current_user.id, role=MinistryRole.LEADER ) db.add(member) db.commit() db_ministry.leader_name = f"{current_user.first_name} {current_user.last_name}" db_ministry.member_count = 1 db_ministry.is_member = True db_ministry.user_role = MinistryRole.LEADER return db_ministry @router.get("/", response_model=List[MinistryResponse]) def get_ministries( skip: int = 0, limit: int = 100, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Get all ministries""" ministries = ( db.query(Ministry).filter(Ministry.is_active).offset(skip).limit(limit).all() ) for ministry in ministries: ministry.leader_name = ( f"{ministry.leader.first_name} {ministry.leader.last_name}" ) ministry.member_count = ( db.query(MinistryMember) .filter(MinistryMember.ministry_id == ministry.id, MinistryMember.is_active) .count() ) # Check if current user is a member and their role member = ( db.query(MinistryMember) .filter( MinistryMember.ministry_id == ministry.id, MinistryMember.user_id == current_user.id, MinistryMember.is_active, ) .first() ) ministry.is_member = member is not None ministry.user_role = member.role if member else None return ministries @router.get("/my-ministries", response_model=List[MinistryResponse]) def get_my_ministries( db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """Get ministries where current user is a member""" memberships = ( db.query(MinistryMember) .filter(MinistryMember.user_id == current_user.id, MinistryMember.is_active) .all() ) ministries = [] for membership in memberships: ministry = membership.ministry ministry.leader_name = ( f"{ministry.leader.first_name} {ministry.leader.last_name}" ) ministry.member_count = ( db.query(MinistryMember) .filter(MinistryMember.ministry_id == ministry.id, MinistryMember.is_active) .count() ) ministry.is_member = True ministry.user_role = membership.role ministries.append(ministry) return ministries @router.get("/{ministry_id}", response_model=MinistryResponse) def get_ministry( ministry_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Get specific ministry""" ministry = db.query(Ministry).filter(Ministry.id == ministry_id).first() if not ministry: raise HTTPException(status_code=404, detail="Ministry not found") ministry.leader_name = f"{ministry.leader.first_name} {ministry.leader.last_name}" ministry.member_count = ( db.query(MinistryMember) .filter(MinistryMember.ministry_id == ministry.id, MinistryMember.is_active) .count() ) member = ( db.query(MinistryMember) .filter( MinistryMember.ministry_id == ministry.id, MinistryMember.user_id == current_user.id, MinistryMember.is_active, ) .first() ) ministry.is_member = member is not None ministry.user_role = member.role if member else None return ministry @router.put("/{ministry_id}", response_model=MinistryResponse) def update_ministry( ministry_id: int, ministry_update: MinistryUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Update ministry (leaders only)""" ministry = db.query(Ministry).filter(Ministry.id == ministry_id).first() if not ministry: raise HTTPException(status_code=404, detail="Ministry not found") # Check if user is leader or co-leader member = ( db.query(MinistryMember) .filter( MinistryMember.ministry_id == ministry_id, MinistryMember.user_id == current_user.id, MinistryMember.is_active, ) .first() ) if not member or member.role not in [MinistryRole.LEADER, MinistryRole.CO_LEADER]: raise HTTPException(status_code=403, detail="Only leaders can update ministry") for field, value in ministry_update.dict(exclude_unset=True).items(): setattr(ministry, field, value) db.commit() db.refresh(ministry) return ministry @router.post("/{ministry_id}/join", response_model=MinistryRequestResponse) def request_to_join_ministry( ministry_id: int, join_request: MinistryJoinRequest, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Request to join a ministry""" ministry = db.query(Ministry).filter(Ministry.id == ministry_id).first() if not ministry: raise HTTPException(status_code=404, detail="Ministry not found") # Check if already a member existing_member = ( db.query(MinistryMember) .filter( MinistryMember.ministry_id == ministry_id, MinistryMember.user_id == current_user.id, MinistryMember.is_active, ) .first() ) if existing_member: raise HTTPException(status_code=400, detail="Already a member of this ministry") # Check if already has pending request existing_request = ( db.query(MinistryRequest) .filter( MinistryRequest.ministry_id == ministry_id, MinistryRequest.user_id == current_user.id, MinistryRequest.status == "pending", ) .first() ) if existing_request: raise HTTPException(status_code=400, detail="Already have a pending request") request = MinistryRequest( ministry_id=ministry_id, user_id=current_user.id, message=join_request.message ) db.add(request) db.commit() db.refresh(request) request.user_name = f"{current_user.first_name} {current_user.last_name}" request.ministry_name = ministry.name return request @router.get("/{ministry_id}/members", response_model=List[MinistryMemberResponse]) def get_ministry_members( ministry_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Get ministry members""" ministry = db.query(Ministry).filter(Ministry.id == ministry_id).first() if not ministry: raise HTTPException(status_code=404, detail="Ministry not found") members = ( db.query(MinistryMember) .filter(MinistryMember.ministry_id == ministry_id, MinistryMember.is_active) .all() ) for member in members: member.user_name = f"{member.user.first_name} {member.user.last_name}" member.ministry_name = ministry.name return members @router.get("/{ministry_id}/activities", response_model=List[MinistryActivityResponse]) def get_ministry_activities( ministry_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Get ministry activities""" activities = ( db.query(MinistryActivity) .filter(MinistryActivity.ministry_id == ministry_id) .order_by(MinistryActivity.activity_date.desc()) .all() ) for activity in activities: activity.creator_name = ( f"{activity.creator.first_name} {activity.creator.last_name}" ) return activities @router.post("/{ministry_id}/activities", response_model=MinistryActivityResponse) def create_ministry_activity( ministry_id: int, activity: MinistryActivityCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Create ministry activity (members only)""" # Check if user is a member member = ( db.query(MinistryMember) .filter( MinistryMember.ministry_id == ministry_id, MinistryMember.user_id == current_user.id, MinistryMember.is_active, ) .first() ) if not member: raise HTTPException( status_code=403, detail="Only ministry members can create activities" ) db_activity = MinistryActivity( **activity.dict(), ministry_id=ministry_id, created_by=current_user.id ) db.add(db_activity) db.commit() db.refresh(db_activity) db_activity.creator_name = f"{current_user.first_name} {current_user.last_name}" return db_activity