"""Original explanatory figures from explicit synthetic teaching inputs."""
from __future__ import annotations
import csv
import importlib.util
import json
from pathlib import Path
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

ROOT=Path(__file__).resolve().parent
OUT=ROOT/'figures'


def read(name):
    with (ROOT/name).open(encoding='utf-8',newline='') as f:return list(csv.DictReader(f))


def save(fig,name):
    fig.savefig(OUT/f'{name}.svg',bbox_inches='tight',metadata={'Date':None})
    fig.savefig(OUT/f'{name}.png',dpi=150,bbox_inches='tight')
    plt.close(fig)


def main():
    OUT.mkdir(exist_ok=True)
    plt.rcParams.update({'font.family':'DejaVu Sans','font.size':11,'axes.spines.top':False,
                        'axes.spines.right':False,'svg.hashsalt':'neurapath-communication'})
    rows=read('bar-comparison.csv');values=[int(r['completed_orders']) for r in rows]
    assert values==[95,100]
    fig,axes=plt.subplots(2,1,figsize=(7,8.5),layout='constrained')
    for ax,start,title in zip(axes,[0,90],['Full baseline: 95 versus 100 orders',
                                        'Misleading teaching example: axis starts at 90']):
        ax.bar(['Period A','Period B'],values,color=['#365e87','#365e87'],width=.5)
        ax.set_ylim(start,112 if start==0 else 103)
        ax.set_ylabel('Completed orders');ax.set_title(title,fontsize=12,loc='left',pad=14)
        ax.bar_label(ax.containers[0],padding=4)
        ax.grid(axis='y',alpha=.2);ax.set_axisbelow(True)
        if start:
            ax.spines['bottom'].set_color('#a23224');ax.spines['bottom'].set_linewidth(2)
            ax.text(.02,.93,'Truncated bars distort the length comparison',transform=ax.transAxes,
                    color='#a23224',fontsize=10,va='top')
    fig.suptitle('Same data, different visual impression\nActual increase: 5 orders (5.26%)',fontsize=13)
    save(fig,'bar-axis-comparison')

    spec=importlib.util.spec_from_file_location('communication_availability',ROOT.parent/'domain-operations/capstone.py')
    capstone=importlib.util.module_from_spec(spec);spec.loader.exec_module(capstone)
    result=capstone.analyze(capstone.read_rows())
    lower,upper=result['all_snapshot_lower_bound']*100,result['all_snapshot_upper_bound']*100
    known=result['known_snapshot_stockout_rate']*100
    assert (lower,upper)==(25,50) and result['coverage']==.75
    fig,ax=plt.subplots(figsize=(8,4.4))
    fig.subplots_adjust(left=.12,right=.96,top=.77,bottom=.28)
    ax.hlines(.55,lower,upper,color='#365e87',lw=7)
    ax.plot([lower,upper],[.55,.55],'|',color='#183e63',markersize=22,markeredgewidth=2)
    ax.plot(known,.15,'o',color='#a14f13',markersize=9)
    ax.axvline(30,color='#303030',ls='--',lw=1)
    ax.text(30,.91,'Fictional threshold: 30%',ha='center',fontsize=10)
    ax.text(25,.69,'25%',ha='center');ax.text(50,.69,'50%',ha='center')
    ax.text(known,.01,'Known-only rate: 33.3% (2 / 6)',ha='center',fontsize=10)
    ax.set(xlim=(0,100),ylim=(-.15,1.05),yticks=[],xlabel='Out-of-stock snapshot share (%)')
    ax.spines['left'].set_visible(False)
    fig.suptitle('Missing states leave the full-grid rate between 25% and 50%',fontsize=12,y=.97)
    fig.text(.12,.84,'8 expected snapshots; 6 known; 2 confirmed out of stock; 2 unknown.',fontsize=10)
    fig.text(.12,.07,'Blue range: missing-state bounds, not a confidence interval.\nOrange point: rate among known snapshots, not an estimate justified for all eight.',fontsize=9)
    save(fig,'availability-bounds')

    series=read('annotated-series.csv')
    assert [r['definition'] for r in series]==['v1','v1','v2','v2']
    assert [r['status'] for r in series]==['final','final','final','provisional']
    values=[int(r['value']) for r in series]
    fig,ax=plt.subplots(figsize=(8,5.2))
    fig.subplots_adjust(left=.12,right=.96,top=.80,bottom=.24)
    ax.plot([0,1],values[:2],'-o',color='#365e87',lw=2)
    ax.plot([2,3],values[2:],'--',color='#365e87',lw=2)
    ax.plot(2,values[2],'o',color='#365e87')
    ax.plot(3,values[3],'o',markerfacecolor='white',markeredgecolor='#365e87',markersize=8,markeredgewidth=2)
    ax.axvline(1.5,color='#777777',ls=':',lw=1.2)
    for i,v in enumerate(values):ax.annotate(str(v),(i,v),xytext=(0,8),textcoords='offset points',ha='center')
    ax.set(xticks=range(4),xticklabels=['Jan','Feb','Mar','Apr'],ylim=(0,160),ylabel='Synthetic metric units',xlim=(-.3,3.3))
    ax.text(.4,35,'Definition v1',ha='center',fontsize=10)
    ax.text(2.5,35,'Definition v2',ha='center',fontsize=10)
    ax.annotate('Definition changes;\nno restated history',(1.5,75),xytext=(.0,.86),
                textcoords='axes fraction',arrowprops={'arrowstyle':'->','color':'#555555'},fontsize=9)
    ax.annotate('Provisional',(3,130),xytext=(2.15,152),arrowprops={'arrowstyle':'->','color':'#555555'},fontsize=9)
    ax.grid(axis='y',alpha=.2);ax.set_axisbelow(True)
    fig.suptitle('Annotate a definition break and provisional observation',fontsize=13,y=.96)
    fig.text(.12,.07,'Original fictional series. No line joins February to March across the definition break.\nOpen April marker and dashed segment identify provisional data; no causal claim is made.',fontsize=9)
    save(fig,'annotated-definition-break')
    metadata={'synthetic':True,'matplotlib':matplotlib.__version__,
              'bar_values':[95,100],'bar_change_percent':(100-95)/95*100,
              'availability_bounds_percent':[lower,upper],'known_snapshot_rate_percent':known,
              'figures':['bar-axis-comparison','availability-bounds','annotated-definition-break'],
              'limits':'Original teaching figures. Axis distortion example is intentionally labeled; bounds are not confidence intervals; fictional series has a definition break.'}
    (OUT/'figure-metadata.json').write_text(json.dumps(metadata,indent=2)+'\n',encoding='utf-8')
    print(json.dumps(metadata,indent=2))


if __name__=='__main__':main()
