"""Draw original Week 10 scenarios from exact, provenance-labeled lab CSVs.

Run from the book directory after the lab smoke script:
    conda run -n research python assets/scripts/build-week10-research-design.py

The transport values are instructor-known scenarios, not realized estimates.
Missing-outcome ranges are identification ranges, not confidence intervals.
"""
from pathlib import Path
import csv
import math
import os
import sys

BOOK = Path(__file__).resolve().parents[2]
REPO = BOOK.parents[1]
LAB = BOOK / 'labs/10-frontier-questions-personnel-data-and-student-research-designs'
PROVENANCE = 'SYNTHETIC_TEACHING_CONSTRUCTION_NOT_PUBLISHED_REPLICATION'
os.environ.setdefault('MPLCONFIGDIR', str(BOOK / '.mpl-cache'))
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
sys.path.insert(0, str(REPO))
from shared.figure_style import COLORS, apply_style, save_figure, style_axis


def read_and_preserve(name, target):
    source = LAB / 'output/diagnose' / name
    destination = BOOK / 'assets/data' / target
    destination.parent.mkdir(parents=True, exist_ok=True)
    destination.write_bytes(source.read_bytes())
    with destination.open(newline='') as stream:
        rows = list(csv.DictReader(stream))
    assert rows and all(row['provenance'] == PROVENANCE for row in rows)
    return rows


def save(fig, stem):
    destination = BOOK / 'assets/figures' / stem
    save_figure(fig, destination.with_suffix('.png'))
    fig.savefig(destination.with_suffix('.pdf'), bbox_inches='tight',
                facecolor='white', metadata={'CreationDate': None, 'ModDate': None})
    plt.close(fig)


def main():
    scenarios = read_and_preserve('transport_scenarios.csv', '10-transport-scenarios.csv')
    ranges = read_and_preserve('worker_followup_bounds.csv', '10-worker-followup-bounds.csv')
    assert [row['scenario'] for row in scenarios] == [
        'source_mix', 'target_stable', 'target_changed_implementation']
    effects = [float(row['effect']) for row in scenarios]
    assert effects == [6, 3.5, .5]
    for row in scenarios:
        p = float(row['high_share'])
        assert math.isclose(float(row['effect']), p * float(row['high_effect'])
                            + (1-p) * float(row['low_effect']), abs_tol=1e-8)

    apply_style()
    fig, ax = plt.subplots(figsize=(10.6, 5.5))
    bars = ax.bar(range(3), effects, width=.55,
                  color=[COLORS[c] for c in ['navy', 'teal', 'rust']])
    ax.bar_label(bars, labels=[f'{value:g}' for value in effects], padding=6, fontsize=13)
    ax.set(title='Same target composition, different implementation',
           ylabel='Effect in invented productivity units', ylim=(0, 7.5),
           xticks=range(3), xticklabels=[
               'Source\nHigh-support share: 2/3\nConditional effects: 8, 2',
               'Stable target\nHigh-support share: 1/4\nConditional effects: 8, 2',
               'Changed implementation\nHigh-support share: 1/4\nConditional effects: 5, −1'])
    style_axis(ax)
    ax.axhline(effects[1], color=COLORS['teal'], linewidth=1, linestyle='--')
    ax.text(2, 3.8, 'Source standardization\nstill predicts 3.5', ha='center',
            color=COLORS['teal'], fontsize=10)
    fig.text(.5, .035, 'Original synthetic scenarios • instructor-known effects • no target outcomes observed',
             ha='center', fontsize=10, color=COLORS['muted'])
    fig.tight_layout(rect=(0, .10, 1, 1))
    save(fig, '10-transport-and-implementation')

    by_object = {row['object']: row for row in ranges}
    assert set(by_object) == {'treated_full_mean', 'control_full_mean', 'treated_minus_control'}
    for name in ['treated_full_mean', 'control_full_mean']:
        row = by_object[name]
        p, mean = float(row['response_rate']), float(row['respondent_mean'])
        assert math.isclose(float(row['lower']), p * mean)
        assert math.isclose(float(row['upper']), p * mean + (1-p) * 100)
    treated, control = by_object['treated_full_mean'], by_object['control_full_mean']
    difference = by_object['treated_minus_control']
    assert float(difference['lower']) == float(treated['lower']) - float(control['upper'])
    assert float(difference['upper']) == float(treated['upper']) - float(control['lower'])
    fig, axes = plt.subplots(1, 2, figsize=(10.6, 5.5), gridspec_kw={'width_ratios': [1.15, 1]})
    for y, row, label, color in [(1, treated, 'Treated', 'teal'), (0, control, 'Control', 'navy')]:
        lo, hi = float(row['lower']), float(row['upper'])
        axes[0].hlines(y, lo, hi, color=COLORS[color], linewidth=5)
        axes[0].plot([lo, hi], [y, y], '|', color=COLORS[color], markersize=15, markeredgewidth=2)
        axes[0].text((lo+hi)/2, y+.2, f'{label}: [{lo:g}, {hi:g}]', ha='center', fontsize=11)
        axes[0].text((lo+hi)/2, y-.25,
                     f"Response {float(row['response_rate']):.0%}; respondent mean {float(row['respondent_mean']):g}",
                     ha='center', fontsize=9)
    axes[0].set(title='Full-population outcome means', xlabel='Outcome on a 0–100 scale',
                xlim=(0, 100), ylim=(-.7, 1.7), yticks=[])
    lo, hi = float(difference['lower']), float(difference['upper'])
    axes[1].hlines(0, lo, hi, color=COLORS['rust'], linewidth=5)
    axes[1].plot([lo, hi], [0, 0], '|', color=COLORS['rust'], markersize=15, markeredgewidth=2)
    axes[1].axvline(0, color=COLORS['muted'], linestyle='--', linewidth=1)
    axes[1].text((lo+hi)/2, .2, f'[{lo:g}, {hi:g}]', ha='center', fontsize=12)
    axes[1].text(0, -.35, 'Either sign remains possible', ha='center', fontsize=10)
    axes[1].set(title='Treated minus control', xlabel='Difference in outcome units',
                xlim=(-40, 40), ylim=(-.7, 1.7), yticks=[])
    for ax in axes:
        style_axis(ax, grid_axis='x')
    fig.text(.5, .095, 'Arbitrary missingness + bounded outcomes • identification ranges, not confidence intervals or Lee bounds',
             ha='center', fontsize=9)
    fig.text(.5, .035, 'Original synthetic example • respondent difference of 10 does not determine the population sign',
             ha='center', fontsize=10, color=COLORS['muted'])
    fig.tight_layout(rect=(0, .15, 1, 1), w_pad=2.5)
    save(fig, '10-missing-outcome-ranges')
    print('PASS: two exact lab CSV inputs; scenario arithmetic and missing-outcome bounds checked; two PNG/PDF pairs saved.')


if __name__ == '__main__':
    main()
