# pxy_building_digital_twins/views.py
from django.shortcuts import render
from django.http import JsonResponse
from django.views.decorators.clickjacking import xframe_options_sameorigin
import random, math

# ---------- page views (allow same-origin iframe) ----------
@xframe_options_sameorigin
def viewer(request):
    resp = render(request, "pxy_building_digital_twins/viewer.html")
    resp["Content-Security-Policy"] = "frame-ancestors 'self'"
    return resp

@xframe_options_sameorigin
def wire_viewer(request):
    resp = render(request, "pxy_building_digital_twins/wire.html")
    resp["Content-Security-Policy"] = "frame-ancestors 'self'"
    return resp

@xframe_options_sameorigin
def wire_babylon(request):
    resp = render(request, "pxy_building_digital_twins/wire_babylon.html")
    resp["Content-Security-Policy"] = "frame-ancestors 'self'"
    return resp

# ---------- geometry helpers ----------
def rect_poly(cx, cy, w, h):
    x1, x2 = cx - w/2, cx + w/2
    y1, y2 = cy - h/2, cy + h/2
    return {"type": "Polygon", "coordinates": [[[x1,y1],[x2,y1],[x2,y2],[x1,y2],[x1,y1]]]}

def ept(cx, cy, rx, ry, a):
    return [cx + rx*math.cos(a), cy + ry*math.sin(a)]

def ellipse_ring(cx, cy, rx_out, ry_out, rx_in, ry_in, segments=128):
    outer = [ept(cx, cy, rx_out, ry_out, i/segments*2*math.pi) for i in range(segments)]
    inner = [ept(cx, cy, rx_in,  ry_in,  i/segments*2*math.pi) for i in range(segments-1, -1, -1)]
    return {"type":"Polygon","coordinates":[outer, inner]}

def bins_on_ellipse(cx, cy, rx, ry, count, start_rad=0.0, jitter_r=0.0):
    feats=[]
    kinds = ["recyclable","organic","landfill","special"]
    for i in range(count):
        a = start_rad + (i/count)*2*math.pi + random.uniform(-0.03, 0.03)
        rxf = rx + random.uniform(-jitter_r, jitter_r)
        ryf = ry + random.uniform(-jitter_r, jitter_r)
        x,y = ept(cx, cy, rxf, ryf, a)
        kind = kinds[i % len(kinds)]
        cap  = random.choice([40,60,80])
        feats.append({
            "type":"Feature",
            "geometry":{"type":"Point","coordinates":[x,y]},
            "properties":{"id":f"BIN_{i+1}","kind":kind,"capacity_l":cap}
        })
    return feats

# ---------- API ----------
def api_random_stadium(request):
    seed = request.GET.get("seed")
    if seed is not None:
        try:
            random.seed(int(seed))
        except ValueError:
            random.seed(seed)

    concourse_bins = int(request.GET.get("concourse_bins", random.randint(42,66)))
    dry_toilets    = int(request.GET.get("dry_toilets",    random.randint(4,8)))

    FIELD_W = random.uniform(100, 110)
    FIELD_H = random.uniform(64, 72)

    CONC_RX_IN = random.uniform(62, 68); CONC_RY_IN = random.uniform(56, 64)
    CONC_RX_OUT = CONC_RX_IN + random.uniform(6,10); CONC_RY_OUT = CONC_RY_IN + random.uniform(6,10)

    STANDS_RX_IN = CONC_RX_OUT + random.uniform(3,5); STANDS_RY_IN = CONC_RY_OUT + random.uniform(3,5)
    STANDS_RX_OUT = STANDS_RX_IN + random.uniform(18,26); STANDS_RY_OUT = STANDS_RY_IN + random.uniform(18,26)

    spaces = {"type":"FeatureCollection","features":[]}
    spaces["features"].append({"type":"Feature","geometry": rect_poly(0,0, FIELD_W, FIELD_H),
                               "properties": {"type":"field","name":"Field"}})
    spaces["features"].append({"type":"Feature","geometry": ellipse_ring(0,0, CONC_RX_OUT, CONC_RY_OUT, CONC_RX_IN, CONC_RY_IN, 128),
                               "properties": {"type":"concourse","name":"Main Concourse"}})
    spaces["features"].append({"type":"Feature","geometry": ellipse_ring(0,0, STANDS_RX_OUT, STANDS_RY_OUT, STANDS_RX_IN, STANDS_RY_IN, 160),
                               "properties": {"type":"stands","name":"Stands"}})

    RX_MID = (CONC_RX_IN + CONC_RX_OUT)/2
    RY_MID = (CONC_RY_IN + CONC_RY_OUT)/2
    bins = {"type":"FeatureCollection","features":[]}
    bins["features"].extend(bins_on_ellipse(0,0, RX_MID, RY_MID, concourse_bins, random.uniform(0, math.pi/3), jitter_r=1.5))

    OUT_RX = STANDS_RX_OUT + random.uniform(10,16)
    OUT_RY = STANDS_RY_OUT + random.uniform(10,16)
    for i in range(dry_toilets):
        a = (i/dry_toilets)*2*math.pi + random.uniform(-0.05,0.05)
        x,y = ept(0,0, OUT_RX, OUT_RY, a)
        bins["features"].append({"type":"Feature","geometry":{"type":"Point","coordinates":[x,y]},
                                 "properties":{"id":f"DT_{i+1}","kind":"dry_toilet","capacity_l":0}})

    return JsonResponse({"spaces": spaces, "bins": bins})
