from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.db.database import get_db
from app.services.service_manager import ServiceManager
from app.contexts.inventory_item import InventoryItemContextFactory
from app.schemas.transaction import PurchaseTransactionCreate, SaleTransactionCreate, TransactionResponse
from typing import List
router = APIRouter(prefix="/inventory")

service_manager = ServiceManager()

# Sealed Routes
@router.get("/sealed/boxes")
async def get_sealed_boxes(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db)
):
    sealed_box_service = service_manager.get_service("sealed_box")
    raw_boxes = sealed_box_service.get_all(db, skip=skip, limit=limit)
    boxes = []
    for box in raw_boxes:
        inventory_item = InventoryItemContextFactory(db).get_context(box.inventory_item)
        boxes.append(inventory_item)
    return boxes

@router.get("/sealed/boxes/{sealed_box_id}")
async def get_sealed_box(
    sealed_box_id: int,
    db: Session = Depends(get_db)
):
    sealed_box_service = service_manager.get_service("sealed_box")
    sealed_box = sealed_box_service.get(db, sealed_box_id)
    return InventoryItemContextFactory(db).get_context(sealed_box.inventory_item)

@router.post("/sealed/boxes")
async def create_sealed_box(
    product_id: int,
    cost_basis: float,
    case_id: int = None,
    db: Session = Depends(get_db)
):
    try:
        sealed_box_service = service_manager.get_service("sealed_box")
        sealed_box = await sealed_box_service.create_sealed_box(db, product_id, cost_basis, case_id)
        return InventoryItemContextFactory(db).get_context(sealed_box.inventory_item)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@router.post("/sealed/boxes/{sealed_box_id}/open")
async def open_sealed_box(
    sealed_box_id: int,
    manabox_file_upload_ids: List[int],
    db: Session = Depends(get_db)
):
    try:
        inventory_service = service_manager.get_service("inventory")
        sealed_box_service = service_manager.get_service("sealed_box")
        file_service = service_manager.get_service("file")
        sealed_box = sealed_box_service.get(db, sealed_box_id)
        manabox_file_uploads = []
        for manabox_file_upload_id in manabox_file_upload_ids:
            manabox_file_upload = file_service.get_file(db, manabox_file_upload_id)
            manabox_file_uploads.append(manabox_file_upload)
        success = await inventory_service.process_manabox_import_staging(db, manabox_file_uploads, sealed_box)
        if not success:
            raise HTTPException(status_code=400, detail="Failed to process Manabox import staging")
        return {"message": "Manabox import staging processed successfully"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@router.get("/sealed/cases")
async def get_sealed_cases(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db)
):
    sealed_case_service = service_manager.get_service("sealed_case")
    raw_cases = sealed_case_service.get_all(db, skip=skip, limit=limit)
    cases = []
    for case in raw_cases:
        inventory_item = InventoryItemContextFactory(db).get_context(case.inventory_item)
        cases.append(inventory_item)
    return cases

@router.get("/sealed/cases/{sealed_case_id}")
async def get_sealed_case(
    sealed_case_id: int,
    db: Session = Depends(get_db)
):
    sealed_case_service = service_manager.get_service("sealed_case")
    sealed_case = sealed_case_service.get(db, sealed_case_id)
    return InventoryItemContextFactory(db).get_context(sealed_case.inventory_item)

@router.post("/sealed/cases")
async def create_sealed_case(
    product_id: int,
    cost_basis: float,
    num_boxes: int,
    db: Session = Depends(get_db)
):
    try:
        sealed_case_service = service_manager.get_service("sealed_case")
        sealed_case = await sealed_case_service.create_sealed_case(db, product_id, cost_basis, num_boxes)
        return InventoryItemContextFactory(db).get_context(sealed_case.inventory_item)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@router.post("/sealed/cases/{sealed_case_id}/open")
async def open_sealed_case(
    sealed_case_id: int,
    db: Session = Depends(get_db)
):
    try:
        sealed_case_service = service_manager.get_service("sealed_case")
        sealed_case = sealed_case_service.get(db, sealed_case_id)
        await sealed_case_service.open_sealed_case(db, sealed_case)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

# Transaction Routes
@router.post("/transactions/purchase")
async def create_purchase_transaction(
    transaction_data: PurchaseTransactionCreate,
    db: Session = Depends(get_db)
):
    inventory_service = service_manager.get_service("inventory")
    transaction = await inventory_service.create_purchase_transaction(db, transaction_data)
    return transaction

@router.post("/transactions/sale")
async def create_sale_transaction(
    transaction_data: SaleTransactionCreate,
    db: Session = Depends(get_db)
):
    inventory_service = service_manager.get_service("inventory")
    transaction = await inventory_service.create_sale_transaction(db, transaction_data)
    return transaction

@router.post("/customers")
async def create_customer(
    customer_name: str,
    db: Session = Depends(get_db)
):
    inventory_service = service_manager.get_service("inventory")
    customer = await inventory_service.create_customer(db, customer_name)
    return customer

@router.post("/vendors")
async def create_vendor(
    vendor_name: str,
    db: Session = Depends(get_db)
):
    inventory_service = service_manager.get_service("inventory")
    vendor = await inventory_service.create_vendor(db, vendor_name)
    return vendor

@router.post("/marketplaces")
async def create_marketplace(
    marketplace_name: str,
    db: Session = Depends(get_db)
):
    inventory_service = service_manager.get_service("inventory")
    marketplace = await inventory_service.create_marketplace(db, marketplace_name)
    return marketplace