from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.db.session import SessionLocal
from app.schemas.product import (
    ProductCreate,
    ProductOut,
    ProductUpdate,
    ProductVariantCreate,
    ProductVariantOut,
    ProductVariantUpdate,
)
from app.crud.products import (
    get_product,
    get_products,
    create_product,
    update_product,
    delete_product,
    get_variant,
    get_variants_for_product,
    create_variant,
    update_variant,
    delete_variant,
)

router = APIRouter()

# Dependency
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

# Products endpoints
@router.post("/", response_model=ProductOut)
def create_product_endpoint(payload: ProductCreate, db: Session = Depends(get_db)):
    return create_product(db, product_data=payload.model_dump())

@router.get("/", response_model=list[ProductOut])
def list_products(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    return get_products(db, skip=skip, limit=limit)

@router.get("/{product_id}", response_model=ProductOut)
def get_product_endpoint(product_id: int, db: Session = Depends(get_db)):
    p = get_product(db, product_id)
    if not p:
        raise HTTPException(status_code=404, detail="Product not found")
    return p

@router.put("/{product_id}", response_model=ProductOut)
def update_product_endpoint(product_id: int, updates: ProductUpdate, db: Session = Depends(get_db)):
    p = get_product(db, product_id)
    if not p:
        raise HTTPException(status_code=404, detail="Product not found")
    return update_product(db, p, updates.model_dump(exclude_unset=True))

@router.delete("/{product_id}")
def delete_product_endpoint(product_id: int, db: Session = Depends(get_db)):
    p = get_product(db, product_id)
    if not p:
        raise HTTPException(status_code=404, detail="Product not found")
    delete_product(db, p)
    return {"ok": True}

# Variants endpoints
@router.post("/{product_id}/variants", response_model=ProductVariantOut)
def create_variant_endpoint(product_id: int, payload: ProductVariantCreate, db: Session = Depends(get_db)):
    if payload.product_id != product_id:
        raise HTTPException(status_code=400, detail="Product ID mismatch")
    return create_variant(db, variant_data=payload.model_dump())

@router.get("/{product_id}/variants", response_model=list[ProductVariantOut])
def list_variants(product_id: int, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    return get_variants_for_product(db, product_id=product_id, skip=skip, limit=limit)

@router.get("/variants/{variant_id}", response_model=ProductVariantOut)
def get_variant_endpoint(variant_id: int, db: Session = Depends(get_db)):
    v = get_variant(db, variant_id)
    if not v:
        raise HTTPException(status_code=404, detail="Variant not found")
    return v

@router.put("/variants/{variant_id}", response_model=ProductVariantOut)
def update_variant_endpoint(variant_id: int, updates: ProductVariantUpdate, db: Session = Depends(get_db)):
    v = get_variant(db, variant_id)
    if not v:
        raise HTTPException(status_code=404, detail="Variant not found")
    return update_variant(db, v, updates.model_dump(exclude_unset=True))

@router.delete("/variants/{variant_id}")
def delete_variant_endpoint(variant_id: int, db: Session = Depends(get_db)):
    v = get_variant(db, variant_id)
    if not v:
        raise HTTPException(status_code=404, detail="Variant not found")
    delete_variant(db, v)
    return {"ok": True}
