import os, msgpack, math, json

DIR = {"N":(0,-1), "S":(0,1), "E":(1,0), "W":(-1,0), "NE":(1,-1), "SE":(1,1), "SW":(-1,1), "NW":(-1,-1)}

def get_intersection(p1, d1, p2, d2):
    # p1 + t1*d1 = p2 + t2*d2
    # p1x + t1*d1x = p2x + t2*d2x
    # p1y + t1*d1y = p2y + t2*d2y
    det = d1[0]*(-d2[1]) - d1[1]*(-d2[0])
    if det == 0: return None
    dx = p2[0] - p1[0]
    dy = p2[1] - p1[1]
    t1 = (dx*(-d2[1]) - dy*(-d2[0])) / det
    return (p1[0] + t1*d1[0], p1[1] + t1*d1[1])

def get_curve_points(rail):
    p1 = (rail['position1']['x'], rail['position1']['z'])
    p2 = (rail['position2']['x'], rail['position2']['z'])
    if rail.get('shape') == 'STRAIGHT':
        return [{"x":p1[0], "z":p1[1]}, {"x":p2[0], "z":p2[1]}]
    
    a1 = rail.get('angle1')
    a2 = rail.get('angle2')
    d1 = DIR.get(a1, (0,0))
    d2 = DIR.get(a2, (0,0))
    
    C = get_intersection(p1, d1, p2, d2)
    if not C:
        return [{"x":p1[0], "z":p1[1]}, {"x":p2[0], "z":p2[1]}]
        
    pts = []
    STEPS = 10
    for i in range(STEPS + 1):
        t = i / STEPS
        x = (1-t)**2 * p1[0] + 2*(1-t)*t * C[0] + t**2 * p2[0]
        z = (1-t)**2 * p1[1] + 2*(1-t)*t * C[1] + t**2 * p2[1]
        pts.append({"x": x, "z": z})
    return pts

def load_rails():
    path = "/var/lib/pterodactyl/volumes/8637552f-2ce1-4a2c-b74a-9ed953b4d762/world/mtr/minecraft/overworld/rails"
    rails_out = []
    if not os.path.exists(path): return []
    for r, d, f in os.walk(path):
        for file in f:
            if not file.startswith("."):
                with open(os.path.join(r, file), "rb") as f_in:
                    unpacker = msgpack.Unpacker(f_in, raw=False)
                    for data in unpacker:
                        pts = get_curve_points(data)
                        p1 = data['position1']
                        p2 = data['position2']
                        rid = f"{p1['x']}_{p1['y']}_{p1['z']}_{p2['x']}_{p2['y']}_{p2['z']}"
                        rails_out.append({
                            "id": rid,
                            "position1": p1,
                            "position2": p2,
                            "curvePoints": pts
                        })
    return rails_out

if __name__ == "__main__":
    rails = load_rails()
    print(f"Loaded {len(rails)} rails.")
    if rails:
        print(json.dumps(rails[0], indent=2))
