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})
