from datetime import datetime
import pandas as pd # type: ignore
import json
import os

# Load ODS file
df = pd.read_excel('data.ods', engine='odf')

# Create node list (convert each row to a dictionary)
nodes = []

# Function to clean dictionary values
def clean_dict(d):
    """Remove keys with None values from a dictionary."""
    # Ensure that we are dealing with single values or lists (no arrays)
    cleaned_dict = {}
    for k, v in d.items():
        if isinstance(v, list):  # If the value is a list, check each item for validity
            v = [item for item in v if pd.notna(item) and item is not None]
            if v:  # Only include non-empty lists
                cleaned_dict[k] = v
        elif pd.notna(v) and v is not None:
            cleaned_dict[k] = v
    return cleaned_dict

# Iterate over rows to create nodes
for _, row in df.iterrows():
    # Handle the "image" field to check for multiple images
    image_value = str(row["image"]).strip() if pd.notna(row["image"]) else None
    
    if image_value:
        if ',' in image_value:
            # Split multiple image paths into a list
            images = [image.strip() for image in image_value.split(',')]
        else:
            # Single image, store as a string
            images = image_value
    else:
        images = None  # No images if the field is empty or NaN

    node = {
        "id": str(row["id"]),  # Ensure ID is a string
        "name": row["name"],
        "description": row["description"],
        "category": row["category"],
        "location": {
            "country": row["country"],
            "state": row["state"],
            "city": row["city"],
        },
        "group": row["country"].split()[0],  # Only get the 3 letter code without emoji
        "image": images,  # Store image(s) (single or list)
        "link": row["link"],
    }

    # Clean the node dictionary before appending
    nodes.append(clean_dict(node))

# Create a dictionary to store nodes by location for linking
location_groups = {}

for node in nodes:
    country = node["location"]["country"].split()[0] # Only get the 3 letter code without emoji
    state = node["location"]["state"]
    city = node["location"]["city"]
    node_id = node["id"]

    # Create hierarchical keys for grouping
    country_key = country
    state_key = f"{country}|{state}"
    city_key = f"{country}|{state}|{city}"

    #  Initialize lists if they don't exist
    location_groups.setdefault(country_key, []).append(node_id)
    location_groups.setdefault(state_key, []).append(node_id)
    location_groups.setdefault(city_key, []).append(node_id)

# Generate links based on hierarchical grouping
links = []

def create_links(node_list, strength):
    """Create links between nodes in the same group"""
    for i in range(len(node_list)):
        for j in range(i + 1, len(node_list)):
            links.append({
                "source": node_list[i],
                "target": node_list[j],
                "strength": strength
            })

# Apply links at different levels
for city_nodes in location_groups.values():
    if len(city_nodes) > 1:
        create_links(city_nodes, strength=3) # Strongest links

for state_nodes in location_groups.values():
    if len(state_nodes) > 1:
        create_links(state_nodes, strength=2) # Medium links

for country_nodes in location_groups.values():
    if len(country_nodes) > 1:
        create_links(country_nodes, strength=1) # Weakest links

# Final JSON structure
graph_data = {"nodes": nodes, "links": links}

# Save to JSON
# Format: graph_data_YYYYMMDD_HHMMSS.json
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
output_file = f"graph_data__{timestamp}.json"
with open(output_file, "w") as f:
    json.dump(graph_data, f, indent=4)

# Print success message and run macOS sound command when script finishes
print(f"\n✅ JSON file '{output_file}' generated successfully!")
os.system("afplay /System/Library/Sounds/Glass.aiff")