#!/usr/bin/env python3
"""Recálculo público sin dependencias: descargue puntos.csv y observaciones-bcch.csv.
Ejecute: python recalcular.py --datos . > resumen-recalculado.csv
Recompone observados y promedios desde los insumos CSV publicados, sin red.
Los puntos ya incorporan los filtros descritos en la nota. Cambios = última − primera.
"""
import argparse,csv,sys
from pathlib import Path
from collections import defaultdict
from statistics import mean
p=argparse.ArgumentParser(description=__doc__);p.add_argument('--datos',type=Path,default=Path(__file__).resolve().parent);p.add_argument('--presupuestos',action='store_true');a=p.parse_args()
def read(name):return list(csv.DictReader((a.datos/name).open(encoding='utf-8')))
raw=defaultdict(list)
for r in read('observaciones-bcch.csv'):raw[r['variable_id'],int(r['fecha'][:4])].append(float(r['valor']))
observed={}
for (v,y),z in raw.items():
 if y<2022:continue
 if v in ['pib','ipc']:
  prev=raw.get((v,y-1));
  if prev and (v=='pib' or len(z)==len(prev)==12):observed[v,y]=(mean(z)/mean(prev)-1)*100
 elif len(z)>=230:observed[v,y]=mean(z)
if a.presupuestos:
 w=csv.writer(sys.stdout);w.writerow(['anio','variable_id','supuesto','observado','diferencia'])
 for r in read('presupuestos.csv'):
  value=observed[r['variable_id'],int(r['anio'])];gap=float(r['supuesto'])-value
  assert abs(gap-float(r['diferencia']))<1e-10
  w.writerow([r['anio'],r['variable_id'],r['supuesto'],value,gap])
 sys.exit(0)
groups=defaultdict(list)
for r in read('puntos.csv'):
 if int(r['anio'])<=2025:groups[r['variable_id'],int(r['anio'])].append(r)
byvar=defaultdict(list)
for (v,y),z in groups.items():
 z.sort(key=lambda r:r['publicado_mes']);vals=[float(r['valor']) for r in z];ob=observed.get((v,y));byvar[v].append((y,len(z),abs(vals[-1]-vals[0]),mean(abs(b-a) for a,b in zip(vals,vals[1:])),vals[-1]-ob if ob is not None else None))
w=csv.writer(sys.stdout);w.writerow(['variable_id','anios','ediciones_min','ediciones_max','revision_media_absoluta','revision_media_absoluta_pasos','error_final_medio','error_final_absoluto_medio'])
for v,z in sorted(byvar.items()):
 errs=[r[4] for r in z if r[4] is not None];w.writerow([v,';'.join(str(r[0]) for r in sorted(z)),min(r[1] for r in z),max(r[1] for r in z),mean(r[2] for r in z),mean(r[3] for r in z),mean(errs) if errs else '',mean(abs(e) for e in errs) if errs else ''])
