import random
from .network import compute_mst_fiber_paths, compute_network_summary

GRID_SIZE = 5
SPACING = 15  # Distance between objects


def generate_com_con_city_data(lat, long):
    """
    Generate a digital twin for a real-world city (e.g., Concepción).
    Returns towers, fiber paths, wifi hotspots, and a summary.
    """
    random.seed(f"{lat},{long}")

    center_x = lat 
    center_z = long 

    towers = generate_towers(center_x, center_z)
    fiber_paths = compute_mst_fiber_paths(towers)
    wifi_hotspots = generate_wifi_hotspots(center_x, center_z)
    summary = compute_network_summary(towers, fiber_paths, wifi_hotspots)

    return {
        'towers': towers,
        'fiber_paths': fiber_paths,
        'wifi_hotspots': wifi_hotspots,
        'network_summary': summary,
    }

def generate_towers(center_x, center_z, mode="streets"):
    """
    Generate towers either in a 'grid' or at realistic 'streets' (mocked).
    mode: "grid" | "streets"
    """
    if mode == "streets":
        return generate_street_corner_towers(center_x, center_z)
    else:
        return generate_grid_towers(center_x, center_z)
    

import osmnx as ox

def generate_street_corner_towers(center_x, center_z, min_towers=10):
    """
    Get real intersections from OSM and convert them to local x/z positions
    relative to center_x / center_z (in meters). Fallbacks to mocked layout if needed.
    """
    print("📍 Starting generate_street_corner_towers()")
    print(f"→ center_x: {center_x}, center_z: {center_z}")
    
    point = (center_x, center_z)  
    print(f"→ Using real lat/lon: {point}")

    try:
        for dist in [100, 200, 500, 1000]:
            print(f"🛰️  Trying OSM download at radius: {dist} meters...")
            G = ox.graph_from_point(point, dist=dist, network_type='all')
            G_undirected = G.to_undirected()
            degrees = dict(G_undirected.degree())
            intersections = [n for n, d in degrees.items() if d >= 3]
            print(f"   ✅ Found {len(intersections)} valid intersections.")
            if len(intersections) >= min_towers:
                break
        else:
            raise ValueError("No sufficient intersections found.")

        nodes, _ = ox.graph_to_gdfs(G)
        origin_lon = nodes.loc[intersections]['x'].mean()
        origin_lat = nodes.loc[intersections]['y'].mean()
        print(f"📌 Using origin_lon: {origin_lon:.6f}, origin_lat: {origin_lat:.6f} for local projection")

        def latlon_to_sim(lon, lat):
            dx = (lon - origin_lon) * 111320
            dz = (lat - origin_lat) * 110540
            return center_x + dx, center_z + dz

        towers = []
        for i, node_id in enumerate(intersections):
            row = nodes.loc[node_id]
            x_sim, z_sim = latlon_to_sim(row['x'], row['y'])
            print(f"   🗼 Tower #{i+1} at sim position: x={x_sim:.2f}, z={z_sim:.2f}")
            towers.append(make_tower(x_sim, z_sim, i + 1))

        print(f"✅ Done. Total towers returned: {len(towers)}\n")
        return towers

    except Exception as e:
        print(f"❌ OSM tower generation failed: {e}")
        print("⚠️  Falling back to mocked tower layout.")

        # Return 3x3 fixed grid as fallback
        offsets = [(-30, -30), (-30, 0), (-30, 30),
                   (0, -30), (0, 0), (0, 30),
                   (30, -30), (30, 0), (30, 30)]

        towers = []
        for i, (dx, dz) in enumerate(offsets):
            x = center_x + dx
            z = center_z + dz
            towers.append(make_tower(x, z, i + 1))

        print(f"✅ Fallback returned {len(towers)} towers.\n")
        return towers

    
def generate_grid_towers(center_x, center_z):
    """Generates a 5×5 grid of towers around the city center."""
    towers = []
    for i in range(GRID_SIZE):
        for j in range(GRID_SIZE):
            x = center_x + (i - GRID_SIZE // 2) * SPACING
            z = center_z + (j - GRID_SIZE // 2) * SPACING
            towers.append({
                'id': len(towers) + 1,
                'status': 'Active' if random.random() > 0.2 else 'Inactive',
                'position_x': x,
                'position_y': 0,
                'position_z': z,
                'height': random.randint(40, 60),
                'range': random.randint(500, 1000),
                'color': '#ff4500'
            })
    return towers


def generate_wifi_hotspots(center_x, center_z):
    """Places 10 Wi-Fi hotspots randomly around the city center."""
    hotspots = []
    bound = SPACING * GRID_SIZE / 2
    for i in range(10):
        x = center_x + random.uniform(-bound, bound)
        z = center_z + random.uniform(-bound, bound)
        hotspots.append({
            'id': i + 1,
            'position_x': x,
            'position_y': 1.5,
            'position_z': z,
            'status': 'Online' if random.random() > 0.2 else 'Offline',
            'radius': random.randint(1, 3),
            'color': '#32cd32'
        })
    return hotspots

def make_tower(x, z, id):
    return {
        'id': id,
        'status': 'Active',
        'position_x': x,
        'position_y': 0,
        'position_z': z,
        'height': 50,
        'range': 1000,
        'color': '#ff4500'
    }

