"""Rebuild the published tables/chart from the saved source; no network calls.

Python 3 + matplotlib. Data: Open-Meteo, CC BY 4.0. Dropory aggregates daily
gridded historical weather. Original response and request are preserved.
"""
import calendar
import csv
import json
from pathlib import Path
from statistics import mean
from datetime import date, timedelta

HERE = Path(__file__).resolve().parent
OUT = HERE if (HERE / 'source.json').exists() else HERE.parent / 'public/research/london-wedding-weather'
source = json.loads((OUT / 'source.json').read_text())
daily = source['daily']
expected = [(date(2016, 1, 1) + timedelta(days=n)).isoformat() for n in range(3653)]
assert daily['time'] == expected, 'Unexpected dates, gaps or duplicated observations'
assert source['daily_units'] == {'time': 'iso8601', 'temperature_2m_max': '°C', 'sunshine_duration': 's', 'precipitation_hours': 'h'}
for key in ['sunshine_duration', 'precipitation_hours', 'temperature_2m_max']:
    assert len(daily[key]) == len(expected) and all(value is not None for value in daily[key]), f'Missing values: {key}'
rows = []
for month in range(1, 13):
    indices = [i for i, value in enumerate(expected) if int(value[5:7]) == month]
    rows.append({'month': calendar.month_name[month], 'days': len(indices),
                 'mean_daily_sunshine_hours': round(mean(daily['sunshine_duration'][i] / 3600 for i in indices), 2),
                 'mean_daily_precipitation_hours': round(mean(daily['precipitation_hours'][i] for i in indices), 2),
                 'mean_daily_maximum_celsius': round(mean(daily['temperature_2m_max'][i] for i in indices), 2)})
with (OUT / 'monthly.csv').open('w', newline='') as handle:
    writer = csv.DictWriter(handle, fieldnames=list(rows[0])); writer.writeheader(); writer.writerows(rows)
with (OUT / 'daily.csv').open('w', newline='') as handle:
    writer = csv.writer(handle)
    writer.writerow(['date', 'sunshine_hours', 'precipitation_hours', 'maximum_celsius'])
    writer.writerows((value, round(daily['sunshine_duration'][i]/3600, 4), daily['precipitation_hours'][i], daily['temperature_2m_max'][i]) for i, value in enumerate(expected))
metadata = {'title': 'London wedding weather: monthly historical comparison, 2016–2025',
            'retrieved': '2026-09-22', 'period': '2016-2025', 'days': len(expected),
            'requestedCoordinates': [51.5074, -0.1278], 'returnedCoordinates': [source['latitude'], source['longitude']],
            'timezone': source['timezone'], 'licence': 'https://creativecommons.org/licenses/by/4.0/',
            'source': 'https://open-meteo.com/',
            'request': 'https://archive-api.open-meteo.com/v1/archive?latitude=51.5074&longitude=-0.1278&start_date=2016-01-01&end_date=2025-12-31&daily=temperature_2m_max,sunshine_duration,precipitation_hours&timezone=Europe%2FLondon',
            'method': 'Arithmetic mean of all daily values within each calendar month across ten years. Sunshine seconds divided by 3600. Leap days included. No missing values. Rounded to two decimals.',
            'months': rows}
(OUT / 'summary.json').write_text(json.dumps(metadata, indent=2) + '\n')
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 5.4), layout='constrained')
fig.set_facecolor('#faf8f1'); ax.set_facecolor('#faf8f1')
ax.bar([r['month'][:3] for r in rows], [r['mean_daily_sunshine_hours'] for r in rows], color='#486551', width=.65)
ax.set_title('London: average daily sunshine by month, 2016–2025', loc='left', pad=20, fontsize=15)
ax.set_ylabel('Sunshine hours per day'); ax.set_ylim(bottom=0)
ax.spines[['top', 'right']].set_visible(False)
fig.text(.02, -.025, 'Source: Open-Meteo (CC BY 4.0). Calculated by Dropory. Historical gridded data; not a forecast.', fontsize=9)
fig.savefig(OUT / 'sunshine.svg', bbox_inches='tight', metadata={'Date': None})
fig.savefig(OUT / 'sunshine.png', dpi=180, bbox_inches='tight')
print(json.dumps(rows))
