"""
Analiza el SVG generado por matplotlib y reporta:
- Todos los stroke-width distintos que aparecen, con sus colores
- Todos los elementos <circle> y su tamaño
- Los 20 paths con mayor stroke-width
- Muestra un fragmento del SVG alrededor de los elementos problemáticos

Uso:
    python analizar_svg.py plano.svg
    python analizar_svg.py plano.svg --color "#ff0000"   (solo rojo)
"""

import argparse
import re
from collections import defaultdict
from xml.etree import ElementTree as ET

# Eliminar namespaces para simplificar el parsing
def quitar_ns(tag):
    return tag.split("}")[-1] if "}" in tag else tag

def parse_style(s):
    d = {}
    for p in s.split(";"):
        p = p.strip()
        if ":" in p:
            k, v = p.split(":", 1)
            d[k.strip()] = v.strip()
    return d

def get_attr(elem, key):
    """Busca atributo tanto en style="..." como atributo directo."""
    style = parse_style(elem.get("style", ""))
    return style.get(key) or elem.get(key)

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("svg_file")
    parser.add_argument("--color", default=None, help="Filtrar por color stroke (ej: #ff0000)")
    args = parser.parse_args()

    with open(args.svg_file, "r", encoding="utf-8") as f:
        contenido = f.read()

    # Parsear
    root = ET.fromstring(contenido)

    print("=" * 70)
    print(f"Archivo: {args.svg_file}")
    print("=" * 70)

    # ── 1. Dimensiones del SVG ────────────────────────────────────────────────
    w = root.get("width", "?")
    h = root.get("height", "?")
    vb = root.get("viewBox", "?")
    print(f"\nDimensiones SVG: width={w} height={h}")
    print(f"viewBox: {vb}")

    # ── 2. Conteo de tipos de elementos ──────────────────────────────────────
    tipo_count = defaultdict(int)
    for elem in root.iter():
        tipo_count[quitar_ns(elem.tag)] += 1
    print("\nTipos de elementos en el SVG:")
    for t, c in sorted(tipo_count.items(), key=lambda x: -x[1]):
        print(f"  <{t}>: {c}")

    # ── 3. Elementos <circle> ─────────────────────────────────────────────────
    circulos = []
    for elem in root.iter():
        if quitar_ns(elem.tag) == "circle":
            r = elem.get("r", "?")
            cx = elem.get("cx", "?")
            cy = elem.get("cy", "?")
            stroke = get_attr(elem, "stroke")
            sw = get_attr(elem, "stroke-width")
            fill = get_attr(elem, "fill")
            circulos.append((r, cx, cy, stroke, sw, fill))

    if circulos:
        print(f"\n⚠ CÍRCULOS ENCONTRADOS: {len(circulos)}")
        print("  (radio, cx, cy, stroke, stroke-width, fill)")
        for c in sorted(circulos, key=lambda x: float(x[0]) if x[0] != "?" else 0, reverse=True)[:20]:
            print(f"  r={c[0]:>10}  cx={c[1]:>10}  cy={c[2]:>10}  "
                  f"stroke={c[3]}  sw={c[4]}  fill={c[5]}")
    else:
        print("\nNo hay elementos <circle> en el SVG.")

    # ── 4. Distribución de stroke-width por color ─────────────────────────────
    sw_por_color = defaultdict(list)
    todos_paths = []

    for elem in root.iter():
        tag = quitar_ns(elem.tag)
        if tag not in ("path", "line", "polyline", "polygon", "rect", "ellipse", "circle"):
            continue
        stroke = get_attr(elem, "stroke")
        sw_str = get_attr(elem, "stroke-width")
        fill   = get_attr(elem, "fill")
        if sw_str:
            try:
                sw_val = float(re.sub(r"[^0-9.\-]", "", sw_str))
            except ValueError:
                sw_val = 0
            if stroke:
                sw_por_color[stroke].append(sw_val)
            todos_paths.append((sw_val, stroke, fill, sw_str, tag))

    print("\nStroke-width por color (min / media / max / count):")
    for color, vals in sorted(sw_por_color.items(), key=lambda x: -max(x[1])):
        if args.color and color != args.color:
            continue
        vmax  = max(vals)
        vmean = sum(vals) / len(vals)
        vmin  = min(vals)
        print(f"  {color or 'none':20s}  min={vmin:.3f}  media={vmean:.3f}  "
              f"max={vmax:.3f}  n={len(vals)}")

    # ── 5. Los 20 paths con mayor stroke-width ────────────────────────────────
    print("\nTop-20 elementos con mayor stroke-width:")
    for sw_val, stroke, fill, sw_str, tag in sorted(todos_paths, key=lambda x: -x[0])[:20]:
        if args.color and stroke != args.color:
            continue
        print(f"  <{tag:10s}> stroke={stroke:20s}  fill={fill:20s}  "
              f"stroke-width={sw_str}")

    # ── 6. Fragmento SVG del primer elemento rojo/gris/cyan problemático ──────
    colores_problema = {"#ff0000", "red", "rgb(255,0,0)",   # rojo carril
                        "#808080", "gray", "grey",            # gris cuneta
                        "#00ffff", "cyan", "rgb(0,255,255)"} # cyan canaleta
    if args.color:
        colores_problema = {args.color}

    print("\nPrimer elemento de color problemático con stroke-width alto:")
    candidatos = [(sw, stroke, fill, tag)
                  for sw, stroke, fill, sw_str, tag in todos_paths
                  if stroke in colores_problema or fill in colores_problema]
    if candidatos:
        candidatos.sort(key=lambda x: -x[0])
        sw, stroke, fill, tag = candidatos[0]
        print(f"  -> <{tag}> stroke={stroke} fill={fill} sw={sw:.4f}")
    else:
        print("  (no encontrado con los colores esperados)")
        print("  Colores de stroke encontrados:", list(sw_por_color.keys())[:15])

if __name__ == "__main__":
    main()
