"""Reader-local figures from the actual saved-row comparison, never shipped data.

Run inside the standalone scientific extraction after fit_real_photometry.py.
The script uses the same ordinary requirements and does not acquire anything.
MIT; Copyright (c) 2026 Sandbox Physics contributors.
"""
import argparse
import hashlib
import json
from pathlib import Path

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np

parser = argparse.ArgumentParser()
parser.add_argument('--results', type=Path, required=True)
parser.add_argument('--output', type=Path, required=True)
arguments = parser.parse_args()
source = arguments.results / 'conditional-comparison.json'
payload = source.read_bytes()
comparison = json.loads(payload)
scenario_name = 'clean-SPIRE-extended-approximation-beta2-diagonal'
scenario = next(row for row in comparison['results'] if row['scenarioName'] == scenario_name)
assert len(scenario['selectedBands']) == 3 and scenario['fixedBeta'] == 2
grid_source = arguments.results / (scenario_name + '.npz')
with np.load(grid_source) as grid:
    temperatures = grid['temperatureGridKelvin']
    squared_distance = grid['twoTemperatureSquaredDistance']
assert squared_distance.shape == (len(temperatures), len(temperatures))
arguments.output.mkdir(parents=True, exist_ok=True)

observations = scenario['selectedBands']
wavelength = np.array([row['wavelengthMicrometres'] for row in observations])
flux = np.array([row['fluxJy'] for row in observations])
errors = np.array([row['quotedErrorJy'] for row in observations])
assert np.all(flux > 0) and np.all(errors > 0)
figure, axes = plt.subplots(1, 2, figsize=(11, 4.7), layout='constrained')
axes[0].errorbar(wavelength, flux, yerr=errors, fmt='o', color='#23394d', label='Same saved native SPIRE row')
axes[0].plot(wavelength, scenario['singleTemperature']['predictedPipelineJy'], 's--', color='#cf6b23', label='Conditional one-temperature fit')
axes[0].plot(wavelength, scenario['twoTemperatureGrid']['predictedPipelineJy'], 'x:', color='#287d85', label='Positive two-temperature grid candidate')
axes[0].set(xlabel='Nominal wavelength (micrometre)', ylabel='Pipeline-convention flux density (Jy)', title='Band-integrated predictions; no interpolated data')
axes[0].legend(fontsize=8)
minimum = np.min(squared_distance)
display = np.ma.masked_invalid(np.where(np.isfinite(squared_distance), np.minimum(squared_distance - minimum, 10), np.nan))
image = axes[1].pcolormesh(temperatures, temperatures, display.T, shading='auto', cmap='viridis_r', vmin=0, vmax=10, rasterized=True)
axes[1].contour(temperatures, temperatures, display.T, levels=[1], colors=['#f48446'], linewidths=.8)
axes[1].set(xlabel='Cold observer-frame colour parameter (K)', ylabel='Hot observer-frame colour parameter (K)', title='Grid distance difference; not a confidence region')
axes[1].set_facecolor('#e7edf0')
axes[1].text(.97, .035, 'Gray: no strictly positive grid candidate\nZero-amplitude boundary is compared separately', transform=axes[1].transAxes, ha='right', va='bottom', fontsize=7, color='#31485b')
figure.colorbar(image, ax=axes[1], label='Squared whitened distance above grid minimum (capped at 10)')
figure.suptitle('NGC4254: beta=2, declared extended-beam approximation, quoted-error diagonal', fontsize=10)
target = arguments.output / 'same-row-colour-comparison.png'
figure.savefig(target, dpi=170)
plt.close(figure)
receipt = {
    'status': 'PASS actual local saved-row plots',
    'sourceComparisonSHA256': hashlib.sha256(payload).hexdigest(),
    'sourceGridSHA256': hashlib.sha256(grid_source.read_bytes()).hexdigest(),
    'scenarioName': scenario_name,
    'sourceName': scenario['sourceName'],
    'sourceNativeSHA256': scenario['sourceSHA256'],
    'figure': str(target), 'figureSHA256': hashlib.sha256(target.read_bytes()).hexdigest(),
    'interpretation': 'Conditional distance, not real posterior or calibrated errors. Observer-frame colour parameters and Jy normalization only. Native source and derived figure remain reader-local; no source table is embedded in this script.',
}
(arguments.output / 'plot-receipt.json').write_text(json.dumps(receipt, indent=2) + '\n')
print(json.dumps(receipt, indent=2))
