"""Parse SWPC RSGA daily reports (raw/rsga/*RSGA.txt) into data/rsga.csv.
One row per issue date. Day-1 target date = issue date + 1 (reports issued 2200Z)."""
import re, glob, os, csv, datetime as dt
MON = {m: i+1 for i, m in enumerate('JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC'.split())}
ROOT = os.environ.get('FLARE_ROOT', '/work/flare-forecasts')
def trip(pat, t):
    m = re.search(pat + r'\s+(\d+)/(\d+)/(\d+)', t)
    return [int(x) for x in m.groups()] if m else [None]*3
rows, bad = [], []
for f in sorted(glob.glob(f'{ROOT}/raw/rsga/*RSGA.txt')):
    ymd = os.path.basename(f)[:8]
    issue = dt.date(int(ymd[:4]), int(ymd[4:6]), int(ymd[6:]))
    t = open(f, errors='replace').read().upper()
    r = {'issue_date': issue.isoformat()}
    m = re.search(r'EVENT PROBABILITIES\s+(\d+)\s+([A-Z]{3})', t)
    if m:
        d1 = dt.date(issue.year, MON[m.group(2)], int(m.group(1))) if MON.get(m.group(2)) else None
        if d1 and d1 < issue - dt.timedelta(30): d1 = d1.replace(year=issue.year + 1)
        r['day1'] = d1.isoformat() if d1 else ''
    else:
        r['day1'] = ''
    for k, pat in [('M', r'CLASS M'), ('X', r'CLASS X'), ('P', r'PROTON')]:
        v = trip(pat, t)
        for i in range(3): r[f'{k}{i+1}'] = v[i]
    m = re.search(r'PCAF\s+(\w+)', t); r['pcaf'] = m.group(1) if m else ''
    m = re.search(r'OBSERVED\s+\d+\s+[A-Z]{3}\s+(\d+)\s*\n', t); r['f107_obs'] = int(m.group(1)) if m else None
    m = re.search(r'PREDICTED\s+\d+\s+[A-Z]{3}\s*-\s*\d+\s+[A-Z]{3}\s+(\d+)/(\d+)/(\d+)', t)
    for i in range(3): r[f'f107_p{i+1}'] = int(m.group(i+1)) if m else None
    m = re.search(r'90 DAY MEAN\s+\d+\s+[A-Z]{3}\s+(\d+)', t); r['f107_90d'] = int(m.group(1)) if m else None
    m = re.search(r'OBSERVED AFR/AP\s+\d+\s+[A-Z]{3}\s+(\d+)/\s*(\d+)', t); r['ap_obs_prev'] = int(m.group(2)) if m else None
    m = re.search(r'ESTIMATED AFR/AP\s+\d+\s+[A-Z]{3}\s+(\d+)/\s*(\d+)', t); r['ap_est'] = int(m.group(2)) if m else None
    m = re.search(r'PREDICTED AFR/AP\s+\d+\s+[A-Z]{3}\s*-\s*\d+\s+[A-Z]{3}\s+(\d+)/(\d+)\s*-\s*(\d+)/(\d+)\s*-\s*(\d+)/(\d+)', t)
    for i in range(3): r[f'ap_p{i+1}'] = int(m.group(2*i+2)) if m else None
    parts = re.split(r'B\.\s+HIGH LATITUDES', t.split('MIDDLE LATITUDES', 1)[-1]) if 'MIDDLE LATITUDES' in t else ['', '']
    for lat, sec in (('mid', parts[0]), ('high', parts[1] if len(parts) > 1 else '')):
        for k, pat in (('act', r'ACTIVE'), ('min', r'MINOR STORM'), ('maj', r'MAJOR[- ]SEVERE STORM')):
            v = trip(pat, sec)
            for i in range(3): r[f'{lat}_{k}{i+1}'] = v[i]
    if r['M1'] is None: bad.append(ymd)
    rows.append(r)
os.makedirs(f'{ROOT}/data', exist_ok=True)
with open(f'{ROOT}/data/rsga.csv', 'w', newline='') as fh:
    w = csv.DictWriter(fh, fieldnames=list(rows[0].keys())); w.writeheader(); w.writerows(rows)
print(len(rows), 'reports;', len(bad), 'without M probs:', bad[:20])
