#!/usr/bin/env python3
"""Render frozen storage results with Matplotlib; never repeat the experiment."""
from pathlib import Path
import argparse,json,math,os
os.environ.setdefault('MPLBACKEND','Agg')
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

LABELS={'primary_70_30':'Primary:70% wind /30% solar','sensitivity_50_50':'Sensitivity:50% wind /50% solar','sensitivity_90_10':'Sensitivity:90% wind /10% solar','sensitivity_remove_DST_dates':'Sensitivity:remove both DST-transition source dates','sensitivity_nonnegative_generation':'Sensitivity:nonnegative-generation preprocessing'}
COLORS=['#a15d34','#0072b2','#009e73','#8054a4','#b86e00']
plt.rcParams.update({'font.family':'DejaVu Sans','font.size':10,'axes.spines.top':False,'axes.spines.right':False,'axes.labelcolor':'#252a27','text.color':'#252a27','svg.fonttype':'none','svg.hashsalt':'incoprea-storage-v2','savefig.facecolor':'white'})

def save(fig,path):
    fig.savefig(path.with_suffix('.svg'),metadata={'Date':None,'Creator':'Codex; Matplotlib '+matplotlib.__version__+'; frozen nominal-profile storage results'})
    fig.savefig(path.with_suffix('.png'),dpi=220,metadata={'Software':'Codex using Matplotlib '+matplotlib.__version__})
    plt.close(fig)

def capacity(ax,rows,title):
    years=[r['year'] for r in rows];median=[r['permutation_median_nominal_GWh_equivalent'] for r in rows]
    low=[m-r['permutation_q025_nominal_GWh_equivalent'] for r,m in zip(rows,median)];high=[r['permutation_q975_nominal_GWh_equivalent']-m for r,m in zip(rows,median)]
    ax.errorbar(years,median,yerr=[low,high],fmt='s',markersize=4,capsize=4,color='#0072b2',elinewidth=1.7,label='Permutation median + central 95% reference')
    ax.plot(years,[r['original_nominal_GWh_equivalent'] for r in rows],'o',markersize=5,color='#a15d34',label='Original source-label order')
    ax.set_title(title.replace(':',': ').replace('/30','/ 30').replace('/50','/ 50').replace('/10','/ 10'),loc='left',fontweight='bold')
    ax.set_ylabel('Nominal GWh-equivalent')
    ax.grid(axis='y',color='#dddddd',linewidth=.7);ax.set_axisbelow(True);ax.ticklabel_format(axis='y',style='plain');ax.set_xticks(years);ax.set_xlim(2014.6,2024.4)

def main():
    parser=argparse.ArgumentParser();parser.add_argument('--directory',type=Path,default=Path(__file__).resolve().parent);args=parser.parse_args();directory=args.directory;rows=json.loads((directory/'results/year-scenario-results.json').read_text());figures=directory/'figures';figures.mkdir(exist_ok=True)
    primary=[r for r in rows if r['scenario']=='primary_70_30']
    fig,ax=plt.subplots(figsize=(10,5));capacity(ax,primary,LABELS['primary_70_30']);ax.set_ylim(bottom=0);fig.legend(*ax.get_legend_handles_labels(), loc='upper left', bbox_to_anchor=(.07,.99), ncol=2, frameon=False, fontsize=9)
    fig.text(.09,.025,'Nominal reported-profile accounting model, not physical French capacity.\nCentral 95% reference from 999 within-month day orders is not a confidence interval.',fontsize=9)
    fig.tight_layout(rect=(0,.11,1,.88));save(fig,figures/'capacity-primary')
    fig,axes=plt.subplots(5,1,figsize=(10,15.5),sharex=True,sharey=True)
    for ax,(sid,label) in zip(axes,LABELS.items()):capacity(ax,[r for r in rows if r['scenario']==sid],label)
    maximum=max(max(r['original_nominal_GWh_equivalent'],r['permutation_q975_nominal_GWh_equivalent']) for r in rows)
    axes[0].set_ylim(0,maximum*1.10);fig.legend(*axes[0].get_legend_handles_labels(), loc='upper left', bbox_to_anchor=(.07,.995), ncol=2, frameon=False, fontsize=8);axes[-1].set_xlabel('Source-label year')
    fig.text(.09,.014,'All 50 year/scenario cases; common capacity scale. Conditional reference ranges, not confidence intervals.\nNominal 48-slot/day model; no physical UTC completeness or real-system sizing claim.',fontsize=9)
    fig.tight_layout(rect=(0,.045,1,.97),h_pad=2);save(fig,figures/'capacity-all-scenarios')
    fig,ax=plt.subplots(figsize=(10,6));markers=['o','s','^','D','v']
    for i,(sid,label) in enumerate(LABELS.items()):
        group=[r for r in rows if r['scenario']==sid]
        ax.plot([r['year'] for r in group],[r['original_to_permutation_median_ratio'] for r in group],marker=markers[i],markersize=4,color=COLORS[i],linewidth=1.4,label=label.replace(':',': ').replace('/30','/ 30').replace('/50','/ 50').replace('/10','/ 10'))
    ax.axhline(1,color='#555555',linestyle='--',linewidth=1);ax.set_xticks(range(2015,2025));ax.set_xlim(2014.7,2024.3);ax.set_ylim(.95,1.5);ax.set_ylabel('Original / permutation median capacity');ax.set_xlabel('Source-label year');ax.set_title('All predeclared scenarios, including the 90/10 reversal in 2016',loc='left',fontweight='bold');ax.grid(axis='y',color='#dddddd',linewidth=.7);ax.legend(loc='upper left',frameon=False,fontsize=8)
    fig.text(.09,.02,'Nominal reported-profile model. The reference is conditional on preserved month/day profiles; no physical capacity claim.',fontsize=9);fig.tight_layout(rect=(0,.06,1,1));save(fig,figures/'ratios-all-scenarios')
    controls=json.loads((directory/'results/deterministic-control.json').read_text());fig,ax=plt.subplots(figsize=(8.5,4.6))
    for i,c in enumerate(controls):ax.plot(range(5),c['cumulative_nominal_MWh'],marker=['o','s'][i],color=COLORS[i],linewidth=2,label=f"{c['label']}: capacity {c['capacity_MWh']:g} MWh")
    ax.set_xticks(range(5));ax.set_yticks([0,.5,1]);ax.set_ylim(-.04,1.13);ax.set_xlabel('Half-hour model slots');ax.set_ylabel('Cumulative deficit (model MWh)');ax.set_title('Same residual values, different cumulative excursion',loc='left',fontweight='bold');ax.grid(axis='y',color='#dddddd',linewidth=.7);ax.legend(frameon=False,loc='upper right',fontsize=9)
    fig.text(.11,.02,'Exact toy control: same zero mean, variance 1 and peak 1. Established accounting, not RTE measurements or a new theorem.',fontsize=8.5);fig.tight_layout(rect=(0,.07,1,1));save(fig,figures/'deterministic-control')
    (directory/'figure-rendering.json').write_text(json.dumps({'tool':'Matplotlib','version':matplotlib.__version__,'formats':['SVG','PNG'],'PNG_dpi':220,'source':'frozen result tables; no experiment rerun','figure_bases':['capacity-primary','capacity-all-scenarios','ratios-all-scenarios','deterministic-control']},indent=2)+'\n')
    print('Rendered4scientific figures as SVG+PNG with Matplotlib '+matplotlib.__version__)
if __name__=='__main__':main()
