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

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

// Serien + Gewichte
$series = [
    'M2SL'       => ['weight' => 0.25,  'label' => 'US M2 Money Supply',   'region' => 'us'],
    'WALCL'      => ['weight' => 0.25,  'label' => 'Fed Balance Sheet',    'region' => 'us'],
    'TOTBKCR'    => ['weight' => 0.20,  'label' => 'US Bank Credit',       'region' => 'us'],
    'ECBASSETS'  => ['weight' => 0.10,  'label' => 'ECB Balance Sheet',    'region' => 'eu'],
    'JPTOAS'     => ['weight' => 0.10,  'label' => 'BoJ Balance Sheet',    'region' => 'jp'],
    'SOFR30DAYAVG'=>['weight' => -0.05, 'label' => 'SOFR (30d Avg)',       'region' => 'us'],
    'DTWEXBGS'   => ['weight' => -0.05, 'label' => 'US Dollar Index',      'region' => 'us'],
];

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

function yoy_change_percent(array $map, string $ym): ?float {
    // map['YYYY-MM'=>value] -> YoY % für Monat $ym (gegen $ym-12M)
    if (!isset($map[$ym])) return null;
    $prev = date('Y-m', strtotime($ym . '-01 -12 months'));
    if (!isset($map[$prev])) return null;
    $a = $map[$prev]; $b = $map[$ym];
    if ($a == 0.0) return null;
    return (($b / $a) - 1.0) * 100.0;
}

function clamp($x, $lo, $hi) { return max($lo, min($hi, $x)); }

// --- Parameter ---
$months = 240;

// --- Daten laden & in Monats-Maps wandeln ---
$maps = [];               // id => ['YYYY-MM'=>value]
$latest_component_rows = []; // Anzeige letzter Rohwert je Serie

foreach ($series as $id => $meta) {
    try {
        $rows = fetch_fred_series($id, '1980-01-01'); // nutzt globalen $FredApiKey intern
        $map  = to_month_map($rows);
        if (!$map) continue;
        $maps[$id] = $map;

        // letzter gültiger Rohwert zur Anzeige
        $lastVal = null; $lastYm = null;
        end($map);
        while (($k = key($map)) !== null) {
            $v = current($map);
            if ($v !== null) { $lastVal = $v; $lastYm = $k; break; }
            prev($map);
        }
        if ($lastYm !== null) {
            $latest_component_rows[] = [
                'name'  => $meta['label'],
                'value' => round($lastVal, 2),
                'date'  => $lastYm . '-01'
            ];
        }
    } catch (Throwable $e) {
        // Serie überspringen, wenn Abruf fehlschlägt
        continue;
    }
}

// Wenn nichts geladen, früh raus
if (!$maps) {
    echo json_encode(['labels'=>[], 'data'=>[], 'currentScore'=>null, 'error'=>'No FRED data']);
    exit;
}

// --- gemeinsame Monatsachse (vereinigte Monate aller Serien) ---
$allMonths = [];
foreach ($maps as $map) $allMonths = array_merge($allMonths, array_keys($map));
$allMonths = array_values(array_unique($allMonths));
sort($allMonths);
if (count($allMonths) > $months) {
    $allMonths = array_slice($allMonths, -$months);
}

// --- Score-Berechnung: gewichtete Summe der YoY-%-Änderungen (geclamped) ---
$labels = $allMonths;
$values = array_fill(0, count($labels), 0.0);

// Für Region-Subscores: Beitrag des **letzten Monats**
$regionScores = ['us'=>0.0, 'eu'=>0.0, 'jp'=>0.0];
$lastIdx = count($labels) - 1;
$lastMonth = $lastIdx >= 0 ? $labels[$lastIdx] : null;

foreach ($series as $id => $meta) {
    if (!isset($maps[$id])) continue;
    $map = $maps[$id];
    $w   = (float)$meta['weight'];
    $reg = $meta['region'];

    foreach ($labels as $i => $ym) {
        $chg = yoy_change_percent($map, $ym);
        if ($chg === null) continue;
        // Clamping wie bisher (±50 %), negative Gewichte (Dollar/SOFR) wirken restriktiv
        $chg = clamp($chg, -50, 50);
        $values[$i] += $chg * $w;

        // Regionale Beiträge nur für den letzten Monat
        if ($ym === $lastMonth) {
            $regionScores[$reg] += $chg * $w;
        }
    }
}

// Ausgabe-Arrays bauen (chronologisch aufsteigend: älteste -> neueste)
$pairs = [];
foreach ($labels as $i => $ym) {
    $pairs[] = ['label' => $ym, 'value' => round($values[$i], 2)];
}

// NICHT mehr array_reverse – wir bleiben in aufsteigender Reihenfolge
$labels = array_column($pairs, 'label');
$data   = array_column($pairs, 'value');

// letzter (neuester) Wert
$current = count($data) ? $data[count($data)-1] : null;
$avg3    = count($data) >= 3 ? round(array_sum(array_slice($data, -3))/3, 2) : null;
$avgAll  = count($data) ? round(array_sum($data)/count($data), 2) : null;

// Signal
$signal = 'neutral';
if ($current !== null) {
    if ($current >= 10)      $signal = 'ultraexpansiv';
    elseif ($current >= 5)   $signal = 'expansiv';
    elseif ($current <= -10) $signal = 'ultrarestriktiv';
    elseif ($current <= -5)  $signal = 'restriktiv';
}

// Region-Scores runden (aktueller Monats-Beitrag)
$regionOut = [
    'us' => round($regionScores['us'], 2),
    'eu' => round($regionScores['eu'], 2),
    'jp' => round($regionScores['jp'], 2),
];

// Response
echo json_encode([
    'labels'         => $labels,           // YYYY-MM
    'data'           => $data,             // gewichteter Index (YoY-basiert)
    'currentScore'   => $current,
    'average3M'      => $avg3,
    'averageAll'     => $avgAll,
    'signal'         => $signal,
    'latest_values'  => $latest_component_rows,
    'subscores'      => $regionOut
]);
