from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Request, BackgroundTasks from fastapi.responses import StreamingResponse from sqlalchemy.orm import Session from typing import Dict, Any, List from db.database import get_db from services.upload import UploadService from services.box import BoxService from services.tcgplayer import TCGPlayerService from services.data import DataService from services.file import FileService from services.product import ProductService from schemas.file import FileMetadata, FileUploadResponse, GetPreparedFilesResponse, FileDeleteResponse from schemas.box import CreateBoxResponse, CreateBoxRequestData from dependencies import get_data_service, get_upload_service, get_tcgplayer_service, get_box_service, get_file_metadata, get_file_service, get_product_service import logging logger = logging.getLogger(__name__) router = APIRouter(prefix="/api", tags=["cards"]) # FILE @router.post("/file/uploadManabox", response_model=FileUploadResponse) async def upload_file( background_tasks: BackgroundTasks, file: UploadFile = File(...), file_service: FileService = Depends(get_file_service), product_service: ProductService = Depends(get_product_service), metadata: FileMetadata = Depends(get_file_metadata)) -> FileUploadResponse: try: content = await file.read() metadata.service = 'product' result = file_service.upload_file(content, file.filename, metadata) background_tasks.add_task(product_service.bg_process_manabox_file, result.id) return result except Exception as e: logger.error(f"File upload failed: {str(e)}") raise HTTPException(status_code=400, detail=str(e)) @router.get("/file/getPreparedFiles", response_model=GetPreparedFilesResponse) async def get_prepared_files(file_service: FileService = Depends(get_file_service)) -> GetPreparedFilesResponse: try: response = file_service.get_prepared_files() return response except Exception as e: logger.error(f"Get prepared files failed: {str(e)}") raise HTTPException(status_code=400, detail=str(e)) @router.post("/file/deleteFile", response_model=FileDeleteResponse) async def delete_file(file_id: str, file_service: FileService = Depends(get_file_service)) -> FileDeleteResponse: try: response = file_service.delete_file(file_id) return response except Exception as e: logger.error(f"Delete file failed: {str(e)}") raise HTTPException(status_code=400, detail=str(e)) @router.post("/box/createBox", response_model=CreateBoxResponse) async def create_box(file_ids: list[str], create_box_data: CreateBoxRequestData, box_service: BoxService = Depends(get_box_service)) -> CreateBoxResponse: try: create_box_data = create_box_data.dict() response = box_service.create_box(create_box_data, file_ids) return response except Exception as e: logger.error(f"Create box failed: {str(e)}") raise HTTPException(status_code=400, detail=str(e)) ## all old below @router.post("/upload/manabox", response_model=dict) async def upload_manabox( background_tasks: BackgroundTasks, upload_service: UploadService = Depends(get_upload_service), data_service: DataService = Depends(get_data_service), file: UploadFile = File(...) ) -> dict: """ Upload endpoint for Manabox CSV files """ try: logger.info(f"file received: {file.filename}") # Read the file content content = await file.read() filename = file.filename file_size = len(content) file_size_kb = file_size / 1024 if not content: logger.error("Empty file content") raise HTTPException(status_code=400, detail="Empty file content") # You might want to validate it's a CSV file if not file.filename.endswith('.csv'): logger.error("File must be a CSV") raise HTTPException(status_code=400, detail="File must be a CSV") result = upload_service.process_manabox_upload(content, filename, file_size_kb) background_tasks.add_task(data_service.bg_set_manabox_tcg_relationship, upload_id=result[1]) return result[0] except Exception as e: logger.error(f"Manabox upload failed: {str(e)}") raise HTTPException(status_code=400, detail=str(e)) @router.post("/createBox", response_model=dict) async def create_box( upload_id: str, box_service: BoxService = Depends(get_box_service) ) -> dict: try: result = box_service.convert_upload_to_boxes(upload_id) except Exception as e: logger.error(f"Box creation failed: {str(e)}") raise HTTPException(status_code=400, detail=str(e)) return result @router.post("/deleteBox", response_model=dict) async def delete_box( box_id: str, box_service: BoxService = Depends(get_box_service) ) -> dict: try: result = box_service.delete_box(box_id) except Exception as e: logger.error(f"Box deletion failed: {str(e)}") raise HTTPException(status_code=400, detail=str(e)) return result @router.post("/tcgplayer/add/box/{box_id}", response_model=dict) async def add_box(box_id: str = None, tcgplayer_service: TCGPlayerService = Depends(get_tcgplayer_service)): try: csv_content = tcgplayer_service.add_to_tcgplayer(box_id) return StreamingResponse( iter([csv_content]), media_type="text/csv", headers={"Content-Disposition": "attachment; filename=add_to_tcgplayer.csv"} ) except Exception as e: logger.error(f"Box add failed: {str(e)}") raise HTTPException(status_code=400, detail=str(e)) @router.post("/tcgplayer/update/box/{box_id}", response_model=dict) async def update_box(box_id: int = None): """asdf""" pass @router.post("/tcgplayer/updateInventory", response_model=dict) async def update_inventory( background_tasks: BackgroundTasks, tcgplayer_service: TCGPlayerService = Depends(get_tcgplayer_service), data_service: DataService = Depends(get_data_service)): try: result = tcgplayer_service.update_inventory('live') export_id = result['export_id'] background_tasks.add_task(data_service.bg_set_tcg_inventory_product_relationship, export_id) return result except Exception as e: logger.error(f"Inventory update failed: {str(e)}") raise HTTPException(status_code=400, detail=str(e)) @router.post("/tcgplayer/updatePricing", response_model=dict) async def update_inventory( tcgplayer_service: TCGPlayerService = Depends(get_tcgplayer_service), group_ids: Dict = None): try: result = tcgplayer_service.update_pricing(group_ids) return result except Exception as e: logger.error(f"Pricing update failed: {str(e)}") raise HTTPException(status_code=400, detail=str(e)) @router.post("/tcgplayer/updatePricingAll", response_model=dict) async def update_inventory(tcgplayer_service: TCGPlayerService = Depends(get_tcgplayer_service)): try: result = tcgplayer_service.update_pricing_all() return result except Exception as e: logger.error(f"Pricing update failed: {str(e)}") raise HTTPException(status_code=400, detail=str(e)) @router.get("/tcgplayer/createLiveInventoryPricingUpdateFile") async def create_inventory_import( tcgplayer_service: TCGPlayerService = Depends(get_tcgplayer_service) ): try: csv_content = tcgplayer_service.get_live_inventory_pricing_update_csv() return StreamingResponse( iter([csv_content]), media_type="text/csv", headers={"Content-Disposition": "attachment; filename=inventory_pricing_update.csv"} ) except Exception as e: logger.error(f"Inventory import creation failed: {str(e)}") raise HTTPException(status_code=400, detail=str(e))