import xml.etree.ElementTree as ET
from PIL import Image, ImageDraw, ImageFont
from coords import TOWN_COORDS
import os
import io

name_overrides = {
    ("Maryborough", "IDQ11295.xml"): "Maryborough QLD",
    ("Maryborough", "IDV10753.xml"): "Maryborough VIC"
}

def parse_weather_data(xml_files, coord_set, forecast_index="0"):
    data = []

    for xml_file in xml_files:
        xml_name = os.path.basename(xml_file)
        tree = ET.parse(xml_file)
        root = tree.getroot()

        for area in root.findall(".//area[@type='location']"):
            xml_town = area.attrib.get("description", "Unknown")
            town = name_overrides.get((xml_town, xml_name), xml_town)
            if town not in coord_set:
                continue
            
            forecast = area.find(f"forecast-period[@index='" + forecast_index + "']")
            if forecast is None:
                continue

            precis_elem = forecast.find("text[@type='precis']")
            icon_elem = forecast.find("element[@type='forecast_icon_code']")
            tmax_elem = forecast.find("element[@type='air_temperature_maximum']")
            tmin_elem = forecast.find("element[@type='air_temperature_minimum']")

            data.append({
                "name": town,
                "x": coord_set[town][0],
                "y": coord_set[town][1],
                "icon": icon_elem.text if icon_elem is not None else "",
                "precis": precis_elem.text if precis_elem is not None else "",
                "tmin": tmin_elem.text if forecast_index != "0" and tmin_elem is not None else None,
                "tmax": tmax_elem.text if tmax_elem is not None else ""
            })

    print(f"🧊 Merged forecast: {len(data)} towns for index {forecast_index}")
    return data

def resolve_icon_filename(code, precis):
    p = precis.lower()

    if code == "3":
        if "mostly sunny" in p:
            return "3a.png"
        elif "partly cloudy" in p:
            return "3b.png"
        elif "mostly cloudy" in p:
            return "3c.png"
    return f"{code}.png"

def generate_map(xml_paths, base_image_path, map_id, forecast_index, output_path):
    coord_set = TOWN_COORDS.get(map_id, {})
    weather_data = parse_weather_data(xml_paths, coord_set, forecast_index)
    base = Image.open(base_image_path).convert("RGBA")
    draw = ImageDraw.Draw(base)
    font = ImageFont.truetype("/var/www/html/wgfx/static/fonts/barlow.ttf", 46)
    
    for entry in weather_data:
        tmin_label = f"{entry['tmin']}"
        tmax_label = f"{entry['tmax']}"
        
        try:
            filename = resolve_icon_filename(entry["icon"], entry["precis"])
            icon_path = f"/var/www/html/wgfx/static/icons/{filename}"
            icon_img = Image.open(icon_path).convert("RGBA").resize((70,70))
            icon_offset = 175 if entry["tmin"] else 100
            base.paste(icon_img, (entry["x"] + icon_offset, entry["y"] + 5), icon_img)
            
        except Exception as e:
            print(f"⚠️ Could not load icon {entry['icon']} for {entry['name']}: {e}")

        # Positioning
        label_box_width = 133
        half = label_box_width / 2

        # Draw tmin
        if entry["tmin"]:
            tmin_label = str(entry["tmin"])
            tmin_width = draw.textbbox((0, 0), tmin_label, font=font)[2]
            tmin_x = entry["x"] + half - (tmin_width / 2) - 33
            draw.text((tmin_x + 22, entry["y"] + 8), tmin_label, font=font, fill="#0a0963")

        # Draw tmax
        if entry["tmax"]:
            tmax_label = str(entry["tmax"])
            tmax_width = draw.textbbox((0, 0), tmax_label, font=font)[2]
            tmax_x = entry["x"] + 16 + half - (tmax_width / 2) + 33 if entry["tmin"] else entry["x"] + 33
            draw.text((tmax_x, entry["y"] + 8), tmax_label, font=font, fill="#ff6229")
            
    if output_path is None:
        output_path = "static/e.png"
    base.save(output_path)
    return output_path
