import yaml
from wand.image import Image
from wand.drawing import Drawing
from wand.color import Color

def apply_style(draw, shape, styles):
    style_name = shape.get("style")
    style = styles.get(style_name, {}) if style_name else {}

    fill = shape.get("fill", style.get("fill"))
    stroke = shape.get("stroke", style.get("stroke"))
    stroke_width = shape.get("stroke_width", style.get("stroke_width", 1))
    opacity = shape.get("opacity", style.get("opacity", 1.0))

    draw.fill_color = Color(fill) if fill else Color("transparent")
    draw.stroke_color = Color(stroke) if stroke else Color("transparent")
    draw.stroke_width = stroke_width
    draw.fill_opacity = opacity
    draw.stroke_opacity = opacity

def draw_shape(draw, img, shape, styles):
    t = shape["type"]
    draw_clone = Drawing()
    apply_style(draw_clone, shape, styles)

    if t == "rectangle":
        x, y = shape["position"]
        w, h = shape["size"]
        draw_clone.rectangle(left=x, top=y, width=w, height=h)

    elif t == "circle":
        cx, cy = shape["center"]
        r = shape["radius"]
        draw_clone.circle((cx, cy), (cx + r, cy))

    elif t == "ellipse":
        cx, cy = shape["center"]
        rx, ry = shape["radius"]
        draw_clone.ellipse(cx - rx, cy - ry, cx + rx, cy + ry)  # ✅

    elif t == "line":
        sx, sy = shape["start"]
        ex, ey = shape["end"]
        draw_clone.line((sx, sy), (ex, ey))

    elif t == "polygon":
        pts = shape["points"]
        draw_clone.polygon(pts)

    elif t == "polyline":
        pts = shape["points"]
        draw_clone.polyline(pts)

    elif t == "text":
        x, y = shape["position"]
        draw_clone.font_size = shape.get("font_size", 20)
        draw_clone.fill_color = Color(shape.get("fill", "#000000"))
        draw_clone.font = shape.get("font", "Arial")
        draw_clone.text(x, y, shape["content"])

    else:
        print(f"⚠️ Unknown shape: {t}")
        return

    if shape.get("rotate"):
        angle = shape["rotate"]
        with img.clone() as temp_img:
            temp_img.background_color = Color("transparent")
            draw_clone.draw(temp_img)
            temp_img.rotate(angle)
            img.composite(temp_img, 0, 0)
    else:
        draw_clone(img)

def generate_from_yaml(yaml_path, output_file="output.png"):
    with open(yaml_path, "r") as f:
        config = yaml.safe_load(f)

    canvas_cfg = config["canvas"]
    shapes = sorted(config.get("shapes", []), key=lambda x: x.get("z", 0))
    styles = config.get("styles", {})

    img = Image(width=canvas_cfg["width"], height=canvas_cfg["height"],
                background=Color(canvas_cfg["background"]))

    for shape in shapes:
        draw_shape(Drawing(), img, shape, styles)

    img.save(filename=output_file)
    print(f"✅ Image saved as {output_file}")

if __name__ == "__main__":
    generate_from_yaml("demo.yaml")
