"""
Roster AI — API HTTP (FastAPI) autour du solveur OR-Tools CP-SAT.

Endpoints :
  GET  /health        → liveness
  POST /solve         → résout un horaire (payload = voir README/sample_request.json)

Pensé pour tourner à côté du hub (targo-hub l'appelle), pas exposé publiquement.
"""
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from typing import Any
import os

from solver import solve_roster
from route_solver import solve_route

app = FastAPI(title="Roster AI Solver", version="0.2.0")

API_TOKEN = os.environ.get("ROSTER_SOLVER_TOKEN", "")


class SolveRequest(BaseModel):
    horizon: dict
    shift_templates: list
    technicians: list
    coverage: list = []
    weights: dict | None = None
    max_seconds: float | None = None


class RouteRequest(BaseModel):
    jobs: list
    vehicles: list
    matrix: list | None = None
    speed_kmh: float | None = None
    default_service_min: int | None = None
    rank_weight: float | None = None
    drop_penalty: int | None = None
    max_seconds: float | None = None


@app.get("/health")
def health():
    return {"ok": True, "service": "roster-solver"}


@app.post("/solve")
def solve(req: SolveRequest):
    try:
        result = solve_roster(req.model_dump())
        return result
    except Exception as e:  # noqa: BLE001 — renvoyer l'erreur proprement au hub
        return JSONResponse(status_code=400, content={"status": "ERROR", "message": str(e)})


@app.post("/route")
def route(req: RouteRequest):
    """Optimisation de TOURNÉES (VRPTW + compétences + temps sur place). Voir route_solver.solve_route."""
    try:
        return solve_route(req.model_dump())
    except Exception as e:  # noqa: BLE001
        return JSONResponse(status_code=400, content={"status": "ERROR", "message": str(e)})
