from __future__ import annotations from django.shortcuts import render from django.conf import settings from rest_framework.decorators import api_view, throttle_classes from rest_framework.response import Response from rest_framework import status from .services.sim_engine import create_run, get_run from .services.waste_sim import build_waste_cesium_payload CESIUM_ION_FALLBACK = ( "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9." "eyJqdGkiOiJkZmM5ZmE1MS0yNWFlLTQ1YjEtOGZiNy1lMmFlOGYyYTI0MjYiLCJpZCI6Mzc0NDg3LCJpYXQiOjE3Njc0MTAxNzN9." "tFBLet8CEmvfCivzZM5ExfHL752iPQIShw6Pqa49Gkw" ) CESIUM_ION_TOKEN = getattr(settings, "CESIUM_ION_TOKEN", "") or CESIUM_ION_FALLBACK def simulation_mvp(request): return render(request, "pxy_simulations/simulation_mvp.html", {"ion_token": CESIUM_ION_TOKEN}) def _err(code: str, message: str, http_status: int = 400): return Response({"ok": False, "code": code, "message": message}, status=http_status) def simulation_waste_cesium(request, subdivision, vehicle): context = { "subdivision": subdivision, "vehicle": vehicle, "ion_token": CESIUM_ION_TOKEN, } return render(request, "pxy_simulations/waste_cesium.html", context) @api_view(["GET"]) @throttle_classes([]) def simulations_health(request): return Response({"ok": True, "service": "simulations"}) @api_view(["POST"]) @throttle_classes([]) def simulations_new(request): run = create_run(request.data or {}) return Response({"ok": True, "run_id": run.run_id, "state": run.state(include_roads=True)}) @api_view(["POST"]) @throttle_classes([]) def simulations_step(request): payload = request.data or {} run_id = (payload.get("run_id") or "").strip() if not run_id: return _err("missing_run_id", "run_id is required") run = get_run(run_id) if run is None: return _err("not_found", "run not found", http_status=status.HTTP_404_NOT_FOUND) try: steps = int(payload.get("steps", 1)) except (TypeError, ValueError): steps = 1 steps = max(1, min(steps, 200)) run.step(steps=steps) return Response({"ok": True, "run_id": run.run_id, "state": run.state(include_roads=False)}) @api_view(["GET"]) @throttle_classes([]) def simulations_state(request): run_id = (request.query_params.get("run_id") or "").strip() if not run_id: return _err("missing_run_id", "run_id is required") run = get_run(run_id) if run is None: return _err("not_found", "run not found", http_status=status.HTTP_404_NOT_FOUND) return Response({"ok": True, "run_id": run.run_id, "state": run.state(include_roads=False)}) @api_view(["GET"]) @throttle_classes([]) def simulations_waste_cesium_data(request, subdivision, vehicle): try: payload = build_waste_cesium_payload(subdivision, vehicle, request.query_params.dict()) except ValueError as exc: return _err("not_found", str(exc), http_status=status.HTTP_404_NOT_FOUND) except Exception as exc: return _err("error", str(exc), http_status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response({"ok": True, **payload})