<?php
header('Content-Type: application/json');

require_once __DIR__ . '/../../engine/engine.php';
require_once __DIR__ . '/../../engine/api-handling/api_helpers.php';
require_once __DIR__ . '/../../engine/api-handling/fred_fetch.php'; // fetch_fred_series()

/**
 * Ziel: FCI-nahe Aggregation via z-Scores der Levels (monatlich).
 * Sign: höher = restriktiver (schlechter), niedriger = lockerer (besser).
 * SP500 wird invertiert (weil höher = lockerer).
 */

// --- Konfiguration ---
$SERIES = [
  // id            label                         sign
  ['DGS10',        'US 10Y Treasury',            +1],
  ['BAMLH0A0HYM2', 'US High Yield OAS (pp)',     +1],
  ['DTWEXBGS',     'Broad Dollar Index',         +1],
  ['SP500',        'S&P 500 (level, inverted)',  -1], // invertiert
  ['DCOILWTICO',   'WTI Crude Oil',              +1],
];

// Startdatum für Historie (genug lang für stabile z-Scores)
$HIST_START = '1990-01-01';

// --- Helpers ---
function to_month_map(array $obs): array {
  // ['date'=>'YYYY-MM-DD','value'=>float|null] -> ['YYYY-MM'=>float]
  $m = [];
  foreach ($obs as $r) {
	if (!isset($r['date'])) continue;
	$v = $r['value'] ?? null;
	if ($v === null || !is_numeric($v)) continue;
	$ym = substr($r['date'], 0, 7);
	$m[$ym] = (float)$v; // letzter Wert im Monat gewinnt
  }
  ksort($m);
  return $m;
}

function zscore_map(array $map, int $sign = +1): array {
  // z-Score über gesamte Historie, optional invertiert (sign = -1)
  $vals = array_values(array_filter($map, fn($x) => $x !== null && is_finite($x)));
  if (count($vals) < 2) {
	// zu wenig Daten -> alles null
	$out = [];
	foreach ($map as $k => $_) $out[$k] = null;
	return $out;
  }
  $mean = array_sum($vals) / count($vals);
  $var = 0.0;
  foreach ($vals as $v) $var += ($v - $mean) * ($v - $mean);
  $std = sqrt($var / (count($vals) - 1));
  if ($std == 0) $std = 1;
  $out = [];
  foreach ($map as $k => $v) {
	$out[$k] = ($v === null) ? null : $sign * (($v - $mean) / $std);
  }
  return $out;
}

// --- Daten laden ---
$maps = [];          // id => ['YYYY-MM'=>level]
$zmaps = [];         // id => ['YYYY-MM'=>z]
$labelsAll = [];     // alle Monate (vereinigt)
$meta = [];          // id => ['label'=>..., 'sign'=>...]

foreach ($SERIES as [$id, $label, $sign]) {
  try {
	$rows = fetch_fred_series($id, $HIST_START);
	$map  = to_month_map($rows);
	if (!$map) continue;
	$maps[$id] = $map;
	$zmaps[$id] = zscore_map($map, $sign);
	$meta[$id] = ['label' => $label, 'sign' => $sign];
	$labelsAll = array_merge($labelsAll, array_keys($map));
  } catch (Throwable $e) {
	// Serie auslassen
	continue;
  }
}

if (!$maps) {
  echo json_encode(['error' => 'Keine FRED-Daten geladen.']);
  exit;
}

// gemeinsame Monatsachse
$labelsAll = array_values(array_unique($labelsAll));
sort($labelsAll);

// Composite: Mittel der verfügbaren z-Scores je Monat
$composite = [];
$components_today = []; // aktueller Monatswert je Serie (z)
foreach ($labelsAll as $ym) {
  $bucket = [];
  foreach ($zmaps as $id => $zmap) {
	$z = $zmap[$ym] ?? null;
	if ($z !== null && is_finite($z)) $bucket[] = $z;
  }
  $composite[$ym] = count($bucket) ? array_sum($bucket) / count($bucket) : null;
}

// Output-Arrays
$labels = array_keys($composite);
$values = array_values($composite);

// SMA(3) zur Glättung (optional)
$sma3 = [];
for ($i = 0; $i < count($values); $i++) {
  if ($i < 2 || $values[$i] === null || $values[$i-1] === null || $values[$i-2] === null) { $sma3[] = null; continue; }
  $sma3[] = round(($values[$i] + $values[$i-1] + $values[$i-2]) / 3, 3);
}

// aktueller Monat
$latestMonth = end($labels);
$current = end($values);
$avg3 = (count($values) >= 3 && $values[count($values)-1] !== null && $values[count($values)-2] !== null && $values[count($values)-3] !== null)
  ? round(($values[count($values)-1] + $values[count($values)-2] + $values[count($values)-3]) / 3, 3)
  : ($current !== null ? round($current, 3) : null);
$avgAll = null;
$valsFinite = array_values(array_filter($values, fn($x)=>$x!==null && is_finite($x)));
if ($valsFinite) $avgAll = round(array_sum($valsFinite)/count($valsFinite), 3);

// Komponenten „heute“
foreach ($zmaps as $id => $zmap) {
  $components_today[] = [
	'name'  => $meta[$id]['label'],
	'value' => isset($zmap[$latestMonth]) ? round($zmap[$latestMonth], 3) : null,
	'date'  => $latestMonth,
	'sign'  => $meta[$id]['sign']
  ];
}

// simple Klassifizierung (z-Score-Logik)
function classify($v) {
  if ($v === null) return 'neutral';
  if ($v >= +1.0)  return 'restriktiv';
  if ($v >= +0.5)  return 'leicht restriktiv';
  if ($v <= -1.0)  return 'expansiv';
  if ($v <= -0.5)  return 'leicht expansiv';
  return 'neutral';
}
$signal = classify($current);

// Response
echo json_encode([
  'labels'        => $labels,                       // YYYY-MM
  'data'          => array_map(fn($v)=> $v===null?null:round($v,3), $values), // FCI-naher z-Score-Composite
  'avg3Data'      => $sma3,
  'currentScore'  => $current===null?null:round($current,3),
  'average3M'     => $avg3,
  'averageAll'    => $avgAll,
  'signal'        => $signal,
  'latest_values' => $components_today,             // z je Serie (letzter Monat)
  'components'    => array_map(function($id) use ($meta){ return ['id'=>$id,'label'=>$meta[$id]['label'],'sign'=>$meta[$id]['sign']]; }, array_keys($meta))
]);
