from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from sqlalchemy import desc from datetime import datetime from typing import List, Optional from ..database import get_db from ..models import User from ..models.inquiry import Inquiry, InquiryMessage, InquiryStatus from ..schemas.inquiry import ( InquiryCreate, InquiryResponse, InquiryListResponse, InquiryMessageCreate, InquiryMessageResponse, InquiryWithMessages, AdminInquiryRespond, AdminInquiryUpdateStatus ) from .auth import get_current_user from .notification import create_notification router = APIRouter(prefix="/inquiries", tags=["inquiries"]) # ===================== # User Endpoints # ===================== @router.get("", response_model=List[InquiryResponse]) def get_inquiries( current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Get current user's inquiries (legacy endpoint)""" return db.query(Inquiry).filter(Inquiry.user_id == current_user.id).order_by(desc(Inquiry.created_at)).all() @router.post("", response_model=InquiryResponse) def create_inquiry( inquiry_data: InquiryCreate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Create a new inquiry""" inquiry = Inquiry( user_id=current_user.id, car_id=inquiry_data.car_id, category=inquiry_data.category, subject=inquiry_data.subject or f"{inquiry_data.category} 문의", message=inquiry_data.message, contact_email=inquiry_data.contact_email or current_user.email, contact_phone=inquiry_data.contact_phone or current_user.phone, status=InquiryStatus.PENDING ) db.add(inquiry) db.commit() db.refresh(inquiry) return inquiry @router.get("/my-inquiries", response_model=InquiryListResponse) def get_my_inquiries( page: int = 1, page_size: int = 10, status: Optional[str] = None, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Get current user's inquiries with pagination""" query = db.query(Inquiry).filter(Inquiry.user_id == current_user.id) if status: query = query.filter(Inquiry.status == status) total = query.count() inquiries = query.order_by(desc(Inquiry.created_at)) \ .offset((page - 1) * page_size) \ .limit(page_size) \ .all() return InquiryListResponse( inquiries=[InquiryResponse.model_validate(i) for i in inquiries], total=total ) @router.get("/my-inquiries/{inquiry_id}", response_model=InquiryWithMessages) def get_my_inquiry_detail( inquiry_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Get details of a specific inquiry with messages""" inquiry = db.query(Inquiry).filter( Inquiry.id == inquiry_id, Inquiry.user_id == current_user.id ).first() if not inquiry: raise HTTPException(status_code=404, detail="Inquiry not found") messages = db.query(InquiryMessage).filter( InquiryMessage.inquiry_id == inquiry_id ).order_by(InquiryMessage.created_at).all() return InquiryWithMessages( inquiry=InquiryResponse.model_validate(inquiry), messages=[InquiryMessageResponse.model_validate(m) for m in messages] ) @router.post("/my-inquiries/{inquiry_id}/message", response_model=InquiryMessageResponse) def add_message_to_inquiry( inquiry_id: int, message_data: InquiryMessageCreate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Add a message to an existing inquiry""" inquiry = db.query(Inquiry).filter( Inquiry.id == inquiry_id, Inquiry.user_id == current_user.id ).first() if not inquiry: raise HTTPException(status_code=404, detail="Inquiry not found") if inquiry.status == InquiryStatus.CLOSED: raise HTTPException(status_code=400, detail="Cannot add message to closed inquiry") message = InquiryMessage( inquiry_id=inquiry_id, user_id=current_user.id, message=message_data.message, is_admin=False ) # Update inquiry status if it was resolved if inquiry.status == InquiryStatus.RESOLVED: inquiry.status = InquiryStatus.IN_PROGRESS db.add(message) db.commit() db.refresh(message) return message @router.get("/{inquiry_id}", response_model=InquiryResponse) def get_inquiry( inquiry_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Get inquiry detail (legacy endpoint)""" inquiry = db.query(Inquiry).filter( Inquiry.id == inquiry_id, Inquiry.user_id == current_user.id ).first() if not inquiry: raise HTTPException(status_code=404, detail="Inquiry not found") return inquiry # ===================== # Admin Endpoints # ===================== @router.get("/admin/list", response_model=InquiryListResponse) def admin_get_all_inquiries( page: int = 1, page_size: int = 20, status: Optional[str] = None, category: Optional[str] = None, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """[Admin] Get all inquiries""" if not current_user.is_admin: raise HTTPException(status_code=403, detail="Admin access required") query = db.query(Inquiry) if status: query = query.filter(Inquiry.status == status) if category: query = query.filter(Inquiry.category == category) total = query.count() inquiries = query.order_by(desc(Inquiry.created_at)) \ .offset((page - 1) * page_size) \ .limit(page_size) \ .all() return InquiryListResponse( inquiries=[InquiryResponse.model_validate(i) for i in inquiries], total=total ) @router.get("/admin/{inquiry_id}", response_model=InquiryWithMessages) def admin_get_inquiry_detail( inquiry_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """[Admin] Get inquiry details with messages""" if not current_user.is_admin: raise HTTPException(status_code=403, detail="Admin access required") inquiry = db.query(Inquiry).filter(Inquiry.id == inquiry_id).first() if not inquiry: raise HTTPException(status_code=404, detail="Inquiry not found") messages = db.query(InquiryMessage).filter( InquiryMessage.inquiry_id == inquiry_id ).order_by(InquiryMessage.created_at).all() return InquiryWithMessages( inquiry=InquiryResponse.model_validate(inquiry), messages=[InquiryMessageResponse.model_validate(m) for m in messages] ) @router.post("/admin/{inquiry_id}/respond", response_model=InquiryMessageResponse) def admin_respond_to_inquiry( inquiry_id: int, response_data: AdminInquiryRespond, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """[Admin] Respond to an inquiry""" if not current_user.is_admin: raise HTTPException(status_code=403, detail="Admin access required") inquiry = db.query(Inquiry).filter(Inquiry.id == inquiry_id).first() if not inquiry: raise HTTPException(status_code=404, detail="Inquiry not found") # Create message message = InquiryMessage( inquiry_id=inquiry_id, user_id=current_user.id, message=response_data.message, is_admin=True ) # Update inquiry inquiry.admin_response = response_data.message inquiry.responded_at = datetime.utcnow() inquiry.responded_by = current_user.id if response_data.status: inquiry.status = response_data.status elif inquiry.status == InquiryStatus.PENDING: inquiry.status = InquiryStatus.IN_PROGRESS db.add(message) db.commit() db.refresh(message) # Send notification to user create_notification( db=db, user_id=inquiry.user_id, notification_type="system", title="문의 답변 도착", message=f"'{inquiry.subject}' 문의에 답변이 등록되었습니다.", link="/contact" ) return message @router.put("/admin/{inquiry_id}/status", response_model=InquiryResponse) def admin_update_inquiry_status( inquiry_id: int, status_data: AdminInquiryUpdateStatus, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """[Admin] Update inquiry status""" if not current_user.is_admin: raise HTTPException(status_code=403, detail="Admin access required") inquiry = db.query(Inquiry).filter(Inquiry.id == inquiry_id).first() if not inquiry: raise HTTPException(status_code=404, detail="Inquiry not found") valid_statuses = [InquiryStatus.PENDING, InquiryStatus.IN_PROGRESS, InquiryStatus.RESOLVED, InquiryStatus.CLOSED] if status_data.status not in valid_statuses: raise HTTPException( status_code=400, detail=f"Invalid status. Must be one of: {valid_statuses}" ) inquiry.status = status_data.status db.commit() db.refresh(inquiry) return inquiry @router.get("/admin/stats") def admin_get_inquiry_stats( current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """[Admin] Get inquiry statistics""" if not current_user.is_admin: raise HTTPException(status_code=403, detail="Admin access required") total = db.query(Inquiry).count() pending = db.query(Inquiry).filter(Inquiry.status == InquiryStatus.PENDING).count() in_progress = db.query(Inquiry).filter(Inquiry.status == InquiryStatus.IN_PROGRESS).count() resolved = db.query(Inquiry).filter(Inquiry.status == InquiryStatus.RESOLVED).count() closed = db.query(Inquiry).filter(Inquiry.status == InquiryStatus.CLOSED).count() return { "total": total, "pending": pending, "in_progress": in_progress, "resolved": resolved, "closed": closed }