from pathlib import Path
import csv, html
BASE=Path(__file__).resolve().parent
rows=list(csv.DictReader((BASE/'aeps-etu2-test-data.csv').open(encoding='utf-8')))
POWER=sorted({int(r['discharge_power_W']) for r in rows})
COLORS={'ETU-2':'#25bdd4','TDU':'#d886ef'}
DASH={'ETU-2':'','TDU':' stroke-dasharray="12 8"'}

def svg(width,height,mobile):
    L,R=(118,725) if mobile else (138,1345)
    pw=R-L
    top=285 if mobile else 250
    gap=480 if mobile else 380
    panel_h=355 if mobile else 230
    line= []
    line.append(f'<svg xmlns="http://www.w3.org/2000/svg" width="{width}" height="{height}" viewBox="0 0 {width} {height}" role="img" aria-labelledby="title desc">')
    line.append('<title id="title">Measured AEPS Hall-thruster performance at four power settings</title>')
    line.append('<desc id="desc">NASA laboratory test table values for ETU-2 and the earlier TDU compared at four discharge powers. Three plots show thrust, specific impulse and total efficiency increasing with power. The measured points are linked only as guides. Error bars use uncertainties reported by the source.</desc>')
    line.append('<rect width="100%" height="100%" rx="26" fill="#08172d"/>')
    line.append(f'<text x="48" y="72" fill="#f4f7ff" font-family="Arial,sans-serif" font-size="{38 if mobile else 32}" font-weight="700">NASA AEPS Hall-thruster test</text>')
    line.append(f'<text x="48" y="120" fill="#b9c8e3" font-family="Arial,sans-serif" font-size="{22 if mobile else 21}">Four tested reference conditions · ground vacuum · not flight data</text>')
    legend_y=180 if mobile else 170
    for j,(name,color) in enumerate(COLORS.items()):
        x=75+j*(340 if mobile else 300)
        line.append(f'<line x1="{x}" y1="{legend_y}" x2="{x+66}" y2="{legend_y}" stroke="{color}" stroke-width="7"{DASH[name]}/>')
        if name=='ETU-2': line.append(f'<circle cx="{x+33}" cy="{legend_y}" r="9" fill="{color}"/>')
        else: line.append(f'<rect x="{x+24}" y="{legend_y-9}" width="18" height="18" fill="{color}"/>')
        line.append(f'<text x="{x+80}" y="{legend_y+9}" fill="#f4f7ff" font-family="Arial,sans-serif" font-size="{26 if mobile else 21}">{name}</text>')
    metrics=[('Thrust (mN)','thrust_mN', (350,650),5,'thrust_mN'),('Specific impulse (s)','specific_impulse_s',(1800,3000),0.9,'percent'),('Total efficiency (%)','total_efficiency_percent',(55,72),1.7,'percent')]
    pmin,pmax=min(POWER),max(POWER)
    for idx,(label,key,(lo,hi),unc,unckind) in enumerate(metrics):
        y0=top+idx*gap
        ybot=y0+panel_h
        line.append(f'<rect x="28" y="{y0-50}" width="{width-56}" height="{panel_h+105}" rx="22" fill="#112445" stroke="#364e78" stroke-width="2"/>')
        line.append(f'<text x="{L}" y="{y0-8}" fill="#f4f7ff" font-family="Arial,sans-serif" font-size="{29 if mobile else 24}" font-weight="700">{html.escape(label)}</text>')
        for t in range(5):
            val=lo+(hi-lo)*t/4
            y=ybot-(ybot-y0)*t/4
            line.append(f'<line x1="{L}" y1="{y:.1f}" x2="{R}" y2="{y:.1f}" stroke="#354a6d" stroke-width="1.5"/>')
            fmt=f'{val:.0f}' if key!='total_efficiency_percent' else f'{val:.1f}'
            line.append(f'<text x="{L-15}" y="{y+8:.1f}" text-anchor="end" fill="#c6d4ea" font-family="Arial,sans-serif" font-size="{22 if mobile else 18}">{fmt}</text>')
        for a,b in zip(POWER,POWER[1:]):
            for name,color in COLORS.items():
                r1=next(z for z in rows if int(z['discharge_power_W'])==a and z['thruster_series']==name)
                r2=next(z for z in rows if int(z['discharge_power_W'])==b and z['thruster_series']==name)
                x1=L+(a-pmin)/(pmax-pmin)*pw;x2=L+(b-pmin)/(pmax-pmin)*pw
                v1=float(r1[key]);v2=float(r2[key]);y1=ybot-(v1-lo)/(hi-lo)*(ybot-y0);y2=ybot-(v2-lo)/(hi-lo)*(ybot-y0)
                line.append(f'<line x1="{x1:.1f}" y1="{y1:.1f}" x2="{x2:.1f}" y2="{y2:.1f}" stroke="{color}" stroke-opacity=".8" stroke-width="4"{DASH[name]}/>')
        for power in POWER:
            x=L+(power-pmin)/(pmax-pmin)*pw
            for name,color in COLORS.items():
                r=next(z for z in rows if int(z['discharge_power_W'])==power and z['thruster_series']==name)
                v=float(r[key]); e=unc if unckind=='thrust_mN' else v*unc/100
                y=ybot-(v-lo)/(hi-lo)*(ybot-y0)
                dy=e/(hi-lo)*(ybot-y0)
                line.append(f'<line x1="{x:.1f}" y1="{y-dy:.1f}" x2="{x:.1f}" y2="{y+dy:.1f}" stroke="{color}" stroke-width="3"/>')
                line.append(f'<line x1="{x-8:.1f}" y1="{y-dy:.1f}" x2="{x+8:.1f}" y2="{y-dy:.1f}" stroke="{color}" stroke-width="3"/>')
                line.append(f'<line x1="{x-8:.1f}" y1="{y+dy:.1f}" x2="{x+8:.1f}" y2="{y+dy:.1f}" stroke="{color}" stroke-width="3"/>')
                if name=='ETU-2': line.append(f'<circle cx="{x:.1f}" cy="{y:.1f}" r="{12 if mobile else 8}" fill="{color}" stroke="#08172d" stroke-width="2"/>')
                else: line.append(f'<rect x="{x-(11 if mobile else 7):.1f}" y="{y-(11 if mobile else 7):.1f}" width="{22 if mobile else 14}" height="{22 if mobile else 14}" fill="{color}" stroke="#08172d" stroke-width="2"/>')
        for power in POWER:
            x=L+(power-pmin)/(pmax-pmin)*pw
            line.append(f'<line x1="{x:.1f}" y1="{ybot}" x2="{x:.1f}" y2="{ybot+8}" stroke="#c6d4ea" stroke-width="2"/>')
            line.append(f'<text x="{x:.1f}" y="{ybot+34}" text-anchor="middle" fill="#c6d4ea" font-family="Arial,sans-serif" font-size="{21 if mobile else 17}">{power/1000:.2f}</text>')
        line.append(f'<text x="{(L+R)/2}" y="{ybot+66}" text-anchor="middle" fill="#d2def0" font-family="Arial,sans-serif" font-size="{23 if mobile else 18}">Discharge power (kW)</text>')
    foot=height-(104 if mobile else 52)
    if mobile:
        line.append(f'<text x="36" y="{foot}" fill="#b9c8e3" font-family="Arial,sans-serif" font-size="23">Uncertainty: ±5 mN; Isp ±0.9%; efficiency ±1.7%.</text>')
        line.append(f'<text x="36" y="{foot+34}" fill="#b9c8e3" font-family="Arial,sans-serif" font-size="23">Percentages are relative; y-axes use focused ranges.</text>')
    else:
        line.append(f'<text x="48" y="{foot}" fill="#b9c8e3" font-family="Arial,sans-serif" font-size="18">Error bars: ±5 mN thrust; ±0.9% specific impulse; ±1.7% efficiency (relative). Focused y-axes do not start at zero.</text>')
    line.append('</svg>')
    return '\n'.join(line)+'\n'

(BASE/'aeps-test-results.svg').write_text(svg(1400,1400,False),encoding='utf-8')
(BASE/'aeps-test-results-mobile.svg').write_text(svg(780,1840,True),encoding='utf-8')
print('Generated two SVGs from',len(rows),'tabulated rows.')
