from __future__ import annotations from pathlib import Path from fastapi import APIRouter, Depends, File, Form, HTTPException, Request, UploadFile from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates from bom_assistant.api.store import SessionStore, get_store from bom_assistant.scouting.ingest import build_session from bom_assistant.scouting.orchestrator import apply_filter, confirm_category, confirm_pick, scout_row router = APIRouter() templates = Jinja2Templates(directory=str(Path(__file__).parent / "templates")) @router.get("/", response_class=HTMLResponse) def index(request: Request) -> HTMLResponse: return templates.TemplateResponse(request, "index.html", {}) @router.post("/upload", response_class=HTMLResponse) def upload( request: Request, file: UploadFile = File(...), store: SessionStore = Depends(get_store), ) -> HTMLResponse: content = file.file.read() try: session = build_session(content, file.filename or "upload") except Exception as exc: raise HTTPException(status_code=400, detail=f"failed to parse BOM: {exc}") from exc store.create(session) return templates.TemplateResponse(request, "_rows.html", {"session": session}) @router.get("/session/{session_id}/row/{row_id}/scout", response_class=HTMLResponse) def scout( request: Request, session_id: str, row_id: str, store: SessionStore = Depends(get_store), ) -> HTMLResponse: session = store.get(session_id) row = scout_row(session, row_id) store.save(session) return templates.TemplateResponse(request, "_scout_result.html", {"session_id": session_id, "row": row}) @router.post("/session/{session_id}/row/{row_id}/confirm-category", response_class=HTMLResponse) def confirm_category_route( request: Request, session_id: str, row_id: str, category_id: int = Form(...), category_name: str = Form(...), store: SessionStore = Depends(get_store), ) -> HTMLResponse: session = store.get(session_id) row = confirm_category(session, row_id, category_id, category_name) store.save(session) return templates.TemplateResponse(request, "_filtering.html", {"session_id": session_id, "row": row}) @router.post("/session/{session_id}/row/{row_id}/apply-filter", response_class=HTMLResponse) def apply_filter_route( request: Request, session_id: str, row_id: str, group: str = Form(...), value: str = Form(...), store: SessionStore = Depends(get_store), ) -> HTMLResponse: session = store.get(session_id) row = apply_filter(session, row_id, group, value) store.save(session) return templates.TemplateResponse(request, "_filtering.html", {"session_id": session_id, "row": row}) @router.post("/session/{session_id}/row/{row_id}/confirm", response_class=HTMLResponse) def confirm_route( request: Request, session_id: str, row_id: str, product_code: str = Form(...), store: SessionStore = Depends(get_store), ) -> HTMLResponse: session = store.get(session_id) row = confirm_pick(session, row_id, product_code) store.save(session) return templates.TemplateResponse(request, "_confirmed.html", {"row": row})