from fastapi import APIRouter, Depends, HTTPException, Query, status

from app.api.deps import require_session
from app.services.tenant_store import (
    InventorySessionCreatePayload,
    InventorySnapshotCreatePayload,
    InventoryStockWritePayload,
    InventoryWarehouseCreatePayload,
    SessionIdentity,
    get_tenant_store,
)


router = APIRouter()


def _raise_inventory_error(exc: ValueError) -> None:
    detail = str(exc)
    status_code = status.HTTP_403_FORBIDDEN if "non puo accedere" in detail.lower() else status.HTTP_400_BAD_REQUEST
    raise HTTPException(status_code=status_code, detail=detail) from exc


@router.get("/warehouses")
def list_inventory_warehouses(session: SessionIdentity = Depends(require_session)) -> dict[str, object]:
    try:
        return get_tenant_store().list_inventory_warehouses(session)
    except ValueError as exc:
        _raise_inventory_error(exc)


@router.post("/warehouses")
def create_inventory_warehouse(
    payload: InventoryWarehouseCreatePayload,
    session: SessionIdentity = Depends(require_session),
) -> dict[str, object]:
    try:
        return get_tenant_store().create_inventory_warehouse(session, payload)
    except ValueError as exc:
        _raise_inventory_error(exc)


@router.get("/warehouses/{warehouse_id}")
def get_inventory_warehouse_detail(
    warehouse_id: str,
    session: SessionIdentity = Depends(require_session),
) -> dict[str, object]:
    try:
        return get_tenant_store().get_inventory_warehouse_detail(session, warehouse_id)
    except KeyError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=exc.args[0] if exc.args else str(exc)) from exc
    except ValueError as exc:
        _raise_inventory_error(exc)


@router.get("/warehouses/{warehouse_id}/sessions")
def list_inventory_warehouse_sessions(
    warehouse_id: str,
    session: SessionIdentity = Depends(require_session),
) -> dict[str, object]:
    try:
        return get_tenant_store().list_inventory_warehouse_sessions(session, warehouse_id)
    except KeyError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=exc.args[0] if exc.args else str(exc)) from exc
    except ValueError as exc:
        _raise_inventory_error(exc)


@router.get("/warehouses/{warehouse_id}/sessions/{session_id}")
def get_inventory_warehouse_session_detail(
    warehouse_id: str,
    session_id: str,
    session: SessionIdentity = Depends(require_session),
) -> dict[str, object]:
    try:
        return get_tenant_store().get_inventory_warehouse_session_detail(session, warehouse_id, session_id)
    except KeyError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=exc.args[0] if exc.args else str(exc)) from exc
    except ValueError as exc:
        _raise_inventory_error(exc)


@router.post("/warehouses/{warehouse_id}/sessions")
def create_inventory_warehouse_session(
    warehouse_id: str,
    payload: InventorySessionCreatePayload,
    session: SessionIdentity = Depends(require_session),
) -> dict[str, object]:
    try:
        return get_tenant_store().create_inventory_warehouse_session(session, warehouse_id, payload)
    except KeyError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=exc.args[0] if exc.args else str(exc)) from exc
    except ValueError as exc:
        _raise_inventory_error(exc)


@router.get("/warehouses/{warehouse_id}/consumption")
def get_inventory_warehouse_consumption(
    warehouse_id: str,
    start_session_id: str | None = Query(default=None),
    end_session_id: str | None = Query(default=None),
    session: SessionIdentity = Depends(require_session),
) -> dict[str, object]:
    try:
        return get_tenant_store().get_inventory_warehouse_consumption(
            session,
            warehouse_id,
            start_session_id=start_session_id,
            end_session_id=end_session_id,
        )
    except KeyError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=exc.args[0] if exc.args else str(exc)) from exc
    except ValueError as exc:
        _raise_inventory_error(exc)


@router.get("/products/search")
def search_inventory_products(
    q: str | None = Query(default=None),
    limit: int = Query(default=20, ge=1, le=100),
    session: SessionIdentity = Depends(require_session),
) -> dict[str, object]:
    try:
        return get_tenant_store().search_inventory_products(session, query=q, limit=limit)
    except ValueError as exc:
        _raise_inventory_error(exc)


@router.post("/warehouses/{warehouse_id}/stock")
def add_inventory_stock(
    warehouse_id: str,
    payload: InventoryStockWritePayload,
    session: SessionIdentity = Depends(require_session),
) -> dict[str, object]:
    try:
        return get_tenant_store().add_inventory_stock(session, warehouse_id, payload)
    except KeyError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=exc.args[0] if exc.args else str(exc)) from exc
    except ValueError as exc:
        _raise_inventory_error(exc)


@router.get("/snapshots")
def list_inventory_snapshots(session: SessionIdentity = Depends(require_session)) -> dict[str, object]:
    try:
        return get_tenant_store().list_inventory_snapshots(session)
    except ValueError as exc:
        _raise_inventory_error(exc)


@router.post("/snapshots")
def create_inventory_snapshot(
    payload: InventorySnapshotCreatePayload,
    session: SessionIdentity = Depends(require_session),
) -> dict[str, object]:
    try:
        return get_tenant_store().create_inventory_snapshot(session, payload)
    except ValueError as exc:
        _raise_inventory_error(exc)


@router.get("/consumption")
def get_inventory_consumption_overview(
    start_snapshot_id: str | None = Query(default=None),
    end_snapshot_id: str | None = Query(default=None),
    session: SessionIdentity = Depends(require_session),
) -> dict[str, object]:
    try:
        return get_tenant_store().get_inventory_consumption_overview(
            session,
            start_snapshot_id=start_snapshot_id,
            end_snapshot_id=end_snapshot_id,
        )
    except KeyError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=exc.args[0] if exc.args else str(exc)) from exc
    except ValueError as exc:
        _raise_inventory_error(exc)
