from typing import List, Optional from fastapi import APIRouter, Depends, HTTPException, Query, BackgroundTasks from sqlalchemy.orm import Session from app.core.database import get_db from app.api.deps import get_current_user from app.tasks.background_tasks import process_marketplace_import from middleware.decorators import rate_limit from models.api_models import (MarketplaceImportJobResponse, MarketplaceImportRequest, StockResponse, StockSummaryResponse, StockCreate, StockAdd, StockUpdate) from models.database_models import User, MarketplaceImportJob, Shop from app.services.stock_service import stock_service import logging router = APIRouter() logger = logging.getLogger(__name__) # Stock Management Routes (Protected) @router.post("/stock", response_model=StockResponse) def set_stock( stock: StockCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """Set exact stock quantity for a GTIN at a specific location (replaces existing quantity)""" try: result = stock_service.set_stock(db, stock) return result except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: logger.error(f"Error setting stock: {str(e)}") raise HTTPException(status_code=500, detail="Internal server error") @router.post("/stock/add", response_model=StockResponse) def add_stock( stock: StockAdd, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """Add quantity to existing stock for a GTIN at a specific location (adds to existing quantity)""" try: result = stock_service.add_stock(db, stock) return result except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: logger.error(f"Error adding stock: {str(e)}") raise HTTPException(status_code=500, detail="Internal server error") @router.post("/stock/remove", response_model=StockResponse) def remove_stock( stock: StockAdd, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """Remove quantity from existing stock for a GTIN at a specific location""" try: result = stock_service.remove_stock(db, stock) return result except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: logger.error(f"Error removing stock: {str(e)}") raise HTTPException(status_code=500, detail="Internal server error") @router.get("/stock/{gtin}", response_model=StockSummaryResponse) def get_stock_by_gtin( gtin: str, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """Get all stock locations and total quantity for a specific GTIN""" try: result = stock_service.get_stock_by_gtin(db, gtin) return result except ValueError as e: raise HTTPException(status_code=404, detail=str(e)) except Exception as e: logger.error(f"Error getting stock for GTIN {gtin}: {str(e)}") raise HTTPException(status_code=500, detail="Internal server error") @router.get("/stock/{gtin}/total") def get_total_stock( gtin: str, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """Get total quantity in stock for a specific GTIN""" try: result = stock_service.get_total_stock(db, gtin) return result except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: logger.error(f"Error getting total stock for GTIN {gtin}: {str(e)}") raise HTTPException(status_code=500, detail="Internal server error") @router.get("/stock", response_model=List[StockResponse]) def get_all_stock( skip: int = Query(0, ge=0), limit: int = Query(100, ge=1, le=1000), location: Optional[str] = Query(None, description="Filter by location"), gtin: Optional[str] = Query(None, description="Filter by GTIN"), db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """Get all stock entries with optional filtering""" try: result = stock_service.get_all_stock( db=db, skip=skip, limit=limit, location=location, gtin=gtin ) return result except Exception as e: logger.error(f"Error getting all stock: {str(e)}") raise HTTPException(status_code=500, detail="Internal server error") @router.put("/stock/{stock_id}", response_model=StockResponse) def update_stock( stock_id: int, stock_update: StockUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """Update stock quantity for a specific stock entry""" try: result = stock_service.update_stock(db, stock_id, stock_update) return result except ValueError as e: raise HTTPException(status_code=404, detail=str(e)) except Exception as e: logger.error(f"Error updating stock {stock_id}: {str(e)}") raise HTTPException(status_code=500, detail="Internal server error") @router.delete("/stock/{stock_id}") def delete_stock( stock_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """Delete a stock entry""" try: stock_service.delete_stock(db, stock_id) return {"message": "Stock entry deleted successfully"} except ValueError as e: raise HTTPException(status_code=404, detail=str(e)) except Exception as e: logger.error(f"Error deleting stock {stock_id}: {str(e)}") raise HTTPException(status_code=500, detail="Internal server error")