# app/api/v1/marketplace.py """Summary description .... This module provides classes and functions for: - .... - .... - .... """ import logging from typing import List, Optional from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, Query from sqlalchemy.orm import Session from app.api.deps import get_current_user from app.core.database import get_db from app.services.marketplace_service import marketplace_service from app.tasks.background_tasks import process_marketplace_import from middleware.decorators import rate_limit from models.api.marketplace import (MarketplaceImportJobResponse, MarketplaceImportRequest) from models.database.user import User router = APIRouter() logger = logging.getLogger(__name__) # Marketplace Import Routes (Protected) @router.post("/marketplace/import-product", response_model=MarketplaceImportJobResponse) @rate_limit(max_requests=10, window_seconds=3600) # Limit marketplace imports async def import_products_from_marketplace( request: MarketplaceImportRequest, background_tasks: BackgroundTasks, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Import products from marketplace CSV with background processing (Protected).""" try: logger.info( f"Starting marketplace import: {request.marketplace} -> {request.shop_code} by user {current_user.username}" ) # Create import job through service import_job = marketplace_service.create_import_job(db, request, current_user) # Process in background background_tasks.add_task( process_marketplace_import, import_job.id, request.url, request.marketplace, request.shop_code, request.batch_size or 1000, ) return MarketplaceImportJobResponse( job_id=import_job.id, status="pending", marketplace=request.marketplace, shop_code=request.shop_code, shop_id=import_job.shop_id, shop_name=import_job.shop_name, message=f"Marketplace import started from {request.marketplace}. Check status with " f"/import-status/{import_job.id}", ) except ValueError as e: raise HTTPException(status_code=404, detail=str(e)) except PermissionError as e: raise HTTPException(status_code=403, detail=str(e)) except Exception as e: logger.error(f"Error starting marketplace import: {str(e)}") raise HTTPException(status_code=500, detail="Internal server error") @router.get( "/marketplace/import-status/{job_id}", response_model=MarketplaceImportJobResponse ) def get_marketplace_import_status( job_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Get status of marketplace import job (Protected).""" try: job = marketplace_service.get_import_job_by_id(db, job_id, current_user) return marketplace_service.convert_to_response_model(job) except ValueError as e: raise HTTPException(status_code=404, detail=str(e)) except PermissionError as e: raise HTTPException(status_code=403, detail=str(e)) except Exception as e: logger.error(f"Error getting import job status {job_id}: {str(e)}") raise HTTPException(status_code=500, detail="Internal server error") @router.get( "/marketplace/import-jobs", response_model=List[MarketplaceImportJobResponse] ) def get_marketplace_import_jobs( marketplace: Optional[str] = Query(None, description="Filter by marketplace"), shop_name: Optional[str] = Query(None, description="Filter by shop name"), skip: int = Query(0, ge=0), limit: int = Query(50, ge=1, le=100), db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Get marketplace import jobs with filtering (Protected).""" try: jobs = marketplace_service.get_import_jobs( db=db, user=current_user, marketplace=marketplace, shop_name=shop_name, skip=skip, limit=limit, ) return [marketplace_service.convert_to_response_model(job) for job in jobs] except Exception as e: logger.error(f"Error getting import jobs: {str(e)}") raise HTTPException(status_code=500, detail="Internal server error") @router.get("/marketplace/marketplace-import-stats") def get_marketplace_import_stats( db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """Get statistics about marketplace import jobs (Protected).""" try: stats = marketplace_service.get_job_stats(db, current_user) return stats except Exception as e: logger.error(f"Error getting import stats: {str(e)}") raise HTTPException(status_code=500, detail="Internal server error") @router.put( "/marketplace/import-jobs/{job_id}/cancel", response_model=MarketplaceImportJobResponse, ) def cancel_marketplace_import_job( job_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Cancel a pending or running marketplace import job (Protected).""" try: job = marketplace_service.cancel_import_job(db, job_id, current_user) return marketplace_service.convert_to_response_model(job) except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except PermissionError as e: raise HTTPException(status_code=403, detail=str(e)) except Exception as e: logger.error(f"Error cancelling import job {job_id}: {str(e)}") raise HTTPException(status_code=500, detail="Internal server error") @router.delete("/marketplace/import-jobs/{job_id}") def delete_marketplace_import_job( job_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): """Delete a completed marketplace import job (Protected).""" try: marketplace_service.delete_import_job(db, job_id, current_user) return {"message": "Marketplace import job deleted successfully"} except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except PermissionError as e: raise HTTPException(status_code=403, detail=str(e)) except Exception as e: logger.error(f"Error deleting import job {job_id}: {str(e)}") raise HTTPException(status_code=500, detail="Internal server error")