from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from sqlalchemy import func from typing import List from app.db.base import get_db from app.core.deps import get_current_user from app.models.user import User from app.models.list import List as ContactList, ListMember from app.models.contact import Contact from app.schemas.list import ( ListCreate, ListUpdate, ListResponse, ListMemberAdd, ListMemberRemove ) router = APIRouter() @router.post("", response_model=ListResponse, status_code=status.HTTP_201_CREATED) def create_list( list_data: ListCreate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): db_list = ContactList( user_id=current_user.id, name=list_data.name ) db.add(db_list) db.commit() db.refresh(db_list) db_list.member_count = 0 return db_list @router.get("", response_model=List[ListResponse]) def list_lists( current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): lists = db.query(ContactList).filter(ContactList.user_id == current_user.id).all() # Add member counts for lst in lists: count = db.query(func.count(ListMember.id)).filter( ListMember.list_id == lst.id ).scalar() lst.member_count = count or 0 return lists @router.get("/{list_id}", response_model=ListResponse) def get_list( list_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): lst = db.query(ContactList).filter( ContactList.id == list_id, ContactList.user_id == current_user.id ).first() if not lst: raise HTTPException(status_code=404, detail="List not found") count = db.query(func.count(ListMember.id)).filter( ListMember.list_id == lst.id ).scalar() lst.member_count = count or 0 return lst @router.put("/{list_id}", response_model=ListResponse) def update_list( list_id: int, list_update: ListUpdate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): lst = db.query(ContactList).filter( ContactList.id == list_id, ContactList.user_id == current_user.id ).first() if not lst: raise HTTPException(status_code=404, detail="List not found") lst.name = list_update.name db.commit() db.refresh(lst) count = db.query(func.count(ListMember.id)).filter( ListMember.list_id == lst.id ).scalar() lst.member_count = count or 0 return lst @router.delete("/{list_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_list( list_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): lst = db.query(ContactList).filter( ContactList.id == list_id, ContactList.user_id == current_user.id ).first() if not lst: raise HTTPException(status_code=404, detail="List not found") db.delete(lst) db.commit() return None @router.post("/{list_id}/members", status_code=status.HTTP_204_NO_CONTENT) def add_members( list_id: int, members: ListMemberAdd, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): lst = db.query(ContactList).filter( ContactList.id == list_id, ContactList.user_id == current_user.id ).first() if not lst: raise HTTPException(status_code=404, detail="List not found") # Verify all contacts belong to user contacts = db.query(Contact).filter( Contact.id.in_(members.contact_ids), Contact.user_id == current_user.id ).all() if len(contacts) != len(members.contact_ids): raise HTTPException(status_code=400, detail="Some contacts not found") # Add members (skip duplicates) for contact_id in members.contact_ids: existing = db.query(ListMember).filter( ListMember.list_id == list_id, ListMember.contact_id == contact_id ).first() if not existing: member = ListMember(list_id=list_id, contact_id=contact_id) db.add(member) db.commit() return None @router.delete("/{list_id}/members", status_code=status.HTTP_204_NO_CONTENT) def remove_members( list_id: int, members: ListMemberRemove, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): lst = db.query(ContactList).filter( ContactList.id == list_id, ContactList.user_id == current_user.id ).first() if not lst: raise HTTPException(status_code=404, detail="List not found") db.query(ListMember).filter( ListMember.list_id == list_id, ListMember.contact_id.in_(members.contact_ids) ).delete(synchronize_session=False) db.commit() return None @router.get("/{list_id}/contacts", response_model=List[dict]) def get_list_contacts( list_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): lst = db.query(ContactList).filter( ContactList.id == list_id, ContactList.user_id == current_user.id ).first() if not lst: raise HTTPException(status_code=404, detail="List not found") members = db.query(Contact).join(ListMember).filter( ListMember.list_id == list_id ).all() return [ { "id": c.id, "phone_e164": c.phone_e164, "first_name": c.first_name, "last_name": c.last_name, "email": c.email, "opted_in": c.opted_in } for c in members ]