<?php
$symbol = $GLOBALS['tab_symbol'] ?? '';
$asof = $GLOBALS['tab_asof'] ?? null;
$useHistorical = !empty($asof);
$target_pe = $GLOBALS['tab_target_pe'] ?? null;

require_once __DIR__ . '/../../engine/bewertungsmethoden/bewertung_fundamental.php';
require_once __DIR__ . '/../../engine/translation/translate_helper.php';
require_once __DIR__ . '/../../engine/api-handling/fmp_client.php';

try {
	if (empty($symbol)) {
		throw new \RuntimeException('Symbol fehlt.');
	}
	if (!function_exists('fmp_multi')) {
		throw new \RuntimeException('fmp_multi() nicht verfügbar – bitte fmp_client.php einbinden.');
	}

	$resp = fmp_multi([
		'profile' => ['key' => 'profile', 'vars' => ['symbol' => $symbol]],
	], 10);

	$profile = $resp['profile'][0] ?? [];

	if (empty($profile)) {
		?>
		<div class="alert alert-warning text-center mt-3">
			Für <strong><?= htmlspecialchars($symbol) ?></strong> konnten keine Daten geladen werden.
		</div>
		<?php
		exit;
	}

	$company     = $profile['companyName'] ?? 'Unbekannt';
	$symbolDisp  = $profile['symbol'] ?? $symbol;
	$branche     = $profile['industry'] ?? 'Branche unbekannt';
	$price       = isset($profile['price']) && is_numeric($profile['price']) ? (float)$profile['price'] : 0.0;

} catch (\Throwable $ex) {
	error_log('[tab_fundamental] FMP Fetch Error: ' . $ex->getMessage());
	?>
	<div class="alert alert-danger text-center mt-3">
		Fehler beim Laden der Fundamentaldaten (<?= htmlspecialchars($ex->getMessage()) ?>).
	</div>
	<?php
	exit;
}

// Safe helper
function s($v): string {
	return htmlspecialchars((string)($v ?? ''), ENT_QUOTES, 'UTF-8');
}


if (!function_exists('get_latest_entry')) {
	function get_latest_entry(array $entries): array {
		// Single-Objekt zulassen
		if (is_array($entries) && isset($entries['date'])) {
			return $entries;
		}
		// Nur valide Zeilen mit 'date'
		$rows = array_values(array_filter($entries, static function ($e) {
			return is_array($e) && isset($e['date']);
		}));
		if (!$rows) return [];
		usort($rows, static function ($a, $b) {
			return strtotime($b['date'] ?? '') <=> strtotime($a['date'] ?? '');
		});
		return $rows[0];
	}
}

if (!function_exists('get_entry_for_date')) {
	function get_entry_for_date(array $entries, ?string $asof): array {
		// Normalisieren (Single-Objekt -> Liste)
		if (is_array($entries) && isset($entries['date'])) {
			$entries = [$entries];
		}
		if (!$asof) return get_latest_entry($entries);
		$asofTs = strtotime($asof);
		$best = null;
		foreach ($entries as $e) {
			if (!is_array($e) || !isset($e['date'])) continue;
			$ts = strtotime($e['date']);
			if ($ts <= $asofTs && (!$best || $ts > strtotime($best['date']))) {
				$best = $e;
			}
		}
		return $best ?: get_latest_entry($entries);
	}
}

/** === Multi-Fetch ===
 *  profile
 *  key_metrics  (limit=1)
 *  ratios_ttm
 *  financial_growth  (Komplette Reihe – asof-Auswahl später)
 *  quote (nur als Preis-Fallback; im selben Call für 1-RTT)
 */
$multi = fmp_multi([
	'profile' => [
		'key'  => 'profile',
		'vars' => ['symbol' => $symbol],
	],
	'metrics' => [
		'key'   => 'key_metrics',
		'vars'  => ['symbol' => $symbol],
		'query' => $useHistorical ? ['limit' => 120] : ['limit' => 1],
	],
	'ratios' => $useHistorical ? [
		'key'   => 'ratios',
		'vars'  => ['symbol' => $symbol],
		'query' => ['period' => 'quarter', 'limit' => 40],
	] : [
		'key'   => 'ratios_ttm',
		'vars'  => ['symbol' => $symbol],
	],
	'growth' => [
		'key'  => 'financial_growth',
		'vars' => ['symbol' => $symbol],
	],
	'quote' => [
		'key'  => 'quote',
		'vars' => ['symbol' => $symbol],
	],
]);

/** --- robustes Auspacken (FMP liefert oft Arrays mit Single-Objekt) --- */
$profileArr = $multi['profile'] ?? [];
$metricsArr = $multi['metrics'] ?? [];
$ratiosArr  = $multi['ratios']  ?? [];
$growthArr  = $multi['growth']  ?? [];
$quoteArr   = $multi['quote']   ?? [];

$profile = is_array($profileArr) && isset($profileArr[0]) ? $profileArr[0] : (is_array($profileArr) ? $profileArr : []);
$metrics = is_array($metricsArr) && isset($metricsArr[0]) ? $metricsArr[0] : (is_array($metricsArr) ? $metricsArr : []);
$ratios  = is_array($ratiosArr)  && isset($ratiosArr[0])  ? $ratiosArr[0]  : (is_array($ratiosArr)  ? $ratiosArr  : []);
$growth  = is_array($growthArr)  ? get_entry_for_date($growthArr, $asof) : [];
	
$effectiveDateRaw = $metrics['date'] ?? ($ratios['date'] ?? ($growth['date'] ?? null));
$effectiveDate = !empty($effectiveDateRaw) ? date('d.m.Y', strtotime($effectiveDateRaw)) : null;
$asofSelected = !empty($asof) ? date('d.m.Y', strtotime($asof)) : null;

/** --- Rohstruktur exakt wie früher (damit $data['raw'] kompatibel bleibt) --- */
$response = [
	'profile' 		=> $profile ? [$profile] : [],
	'metrics' 		=> [$metrics],
	'ratios'  		=> [$ratios],
	'growth'  		=> is_array($growthArr) ? $growthArr : [],
	'effectiveDate' => $useHistorical ? ($effectiveDate ?? null) : null,
];

/** --- $data exakt wie prepare_evaluation_data('fundamental_basic') früher --- */
if (!$profile) {
	$data = null;
} else {
	$data = [
		'symbol'   			=> $symbol,
		'company'  			=> $profile['companyName'] ?? '',
		'price'    			=> $profile['price'] ?? ($quote0['price'] ?? null),
		'sector'   			=> $profile['sector'] ?? '',
		'industry' 			=> $profile['industry'] ?? '',
		'exchange' 			=> $profile['exchangeShortName'] ?? '',
		'volAvg'   			=> $profile['volAvg'] ?? null,
		'beta'     			=> $profile['beta'] ?? null,
		'asofSelected'  	=> $asofSelected,
		'effectiveDate' 	=> $effectiveDate,

		// Bewertungskennzahlen (TTM + metrics wie früher)
		'marketCap'                => $ratios['marketCapTTM'] ?? null,
		'peRatio'                  => $ratios['priceEarningsRatioTTM'] ?? null,
		'pbRatio'                  => $ratios['priceToBookRatioTTM'] ?? null,
		'priceToSalesRatio'        => $ratios['priceToSalesRatioTTM'] ?? null,
		'evToEbitda'               => $ratios['enterpriseValueMultipleTTM'] ?? null,
		'earningsYield'            => $metrics['earningsYield'] ?? null,
		'pegRatio'                 => $ratios['pegRatioTTM'] ?? null,

		// Rentabilität
		'roe'                      => $ratios['returnOnEquityTTM'] ?? null,
		'roa'                      => $ratios['returnOnAssetsTTM'] ?? null,
		'roic'                     => $ratios['returnOnCapitalEmployedTTM'] ?? null,
		'grossMargin'              => $ratios['grossProfitMarginTTM'] ?? null,
		'netMargin'                => $ratios['netProfitMarginTTM'] ?? null,

		// Bilanzqualität
		'incomeQuality'            => $metrics['incomeQuality'] ?? null,
		'currentRatio'             => $ratios['currentRatioTTM'] ?? null,
		'debtToEquity'             => $ratios['debtEquityRatioTTM'] ?? null,
		'intangiblesToTotalAssets' => $metrics['intangiblesToTotalAssets'] ?? null,
		'netDebtToEBITDA'          => $metrics['netDebtToEBITDA'] ?? null,
		'workingCapital'           => $metrics['workingCapital'] ?? null,

		// Cashflow-Betrachtung
		'fcf'                      => $ratios['freeCashFlowPerShareTTM'] ?? null,
		'freeCashFlowYield'        => $metrics['freeCashFlowYield'] ?? null,
		'operatingCashFlowPerShare'=> $ratios['operatingCashFlowPerShareTTM'] ?? null,
		'capexPerShare'            => $metrics['capexPerShare'] ?? null,
		'capexToOperatingCashFlow' => $metrics['capexToOperatingCashFlow'] ?? null,

		// Wachstumsperspektive
		'dividendPerShare'         => $ratios['dividendPerShareTTM'] ?? null,
		'payoutRatio'              => $ratios['payoutRatioTTM'] ?? null,
		'dividendYield'            => $ratios['dividendYieldTTM'] ?? null,
		'epsGrowth'                => $growth['epsgrowth'] ?? null,
		'revenueGrowth'            => $growth['revenueGrowth'] ?? null,
		'bookValueperShareGrowth'  => $growth['bookValueperShareGrowth'] ?? null,
		'freeCashFlowGrowth'       => $growth['freeCashFlowGrowth'] ?? null,
		'dividendsperShareGrowth'  => $growth['dividendsperShareGrowth'] ?? null,

		'date' => $ratios['date'] ?? ($metrics['date'] ?? ($growth['date'] ?? null)),
		'raw'  => $response,
	];

	// Numerisch normalisieren (damit evaluate() die Werte sicher zählt)
	foreach ([
		'peRatio','priceToSalesRatio','pbRatio','evToEbitda','pegRatio',
		'roe','roa','roic','grossMargin','netMargin',
		'currentRatio','debtToEquity','payoutRatio',
		'freeCashFlowYield','operatingCashFlowPerShare','capexPerShare','capexToOperatingCashFlow',
		'dividendYield','epsGrowth','revenueGrowth','bookValueperShareGrowth','freeCashFlowGrowth','dividendsperShareGrowth'
	] as $k) {
		if (isset($data[$k]) && is_numeric($data[$k])) $data[$k] = (float)$data[$k];
		elseif (isset($data[$k]) && !is_numeric($data[$k])) $data[$k] = null;
	}
}

// Institutionelle Bewertungen
$addon = fmp_multi([
  'financial_scores' => ['key'=>'financial_scores','vars'=>['symbol'=>$symbol]],
  'owner_earnings'   => ['key'=>'owner_earnings','vars'=>['symbol'=>$symbol]],
  'enterprise_values'=> ['key'=>'enterprise_values','vars'=>['symbol'=>$symbol],'query'=>['limit'=>1]],
  // Wachstum granular (optional – nur wenn du wirklich nutzt)
  // 'income_statement_growth' => ['key'=>'income_statement_growth','vars'=>['symbol'=>$symbol]],
  // 'balance_sheet_growth'    => ['key'=>'balance_sheet_growth','vars'=>['symbol'=>$symbol]],
  // 'cashflow_growth'         => ['key'=>'cashflow_growth','vars'=>['symbol'=>$symbol]],
  // Segmentierung (optional)
  // 'revenue_product_segmentation' => ['key'=>'revenue_product_segmentation','vars'=>['symbol'=>$symbol]],
  // 'revenue_geo_segmentation'     => ['key'=>'revenue_geo_segmentation','vars'=>['symbol'=>$symbol]],
]);

$scoresArr = $addon['financial_scores'] ?? [];
$scores    = is_array($scoresArr) && isset($scoresArr[0]) ? $scoresArr[0] : (is_array($scoresArr)?$scoresArr:[]);

$ownerArr  = $addon['owner_earnings'] ?? [];
$owner     = is_array($ownerArr) && isset($ownerArr[0]) ? $ownerArr[0] : (is_array($ownerArr)?$ownerArr:[]);

$evArr     = $addon['enterprise_values'] ?? [];
$evRow     = is_array($evArr) && isset($evArr[0]) ? $evArr[0] : (is_array($evArr)?$evArr:[]);

$data['inst'] = [
  'altmanZ'      => $scores['altmanZScore']   ?? null,
  'piotroskiF'   => $scores['piotroskiScore'] ?? null,
  'ownerEPS'     => $owner['ownerEarningsPerShare'] ?? null,
  'enterpriseValue' => $evRow['enterpriseValue'] ?? null,
];

$data['raw']['financial_scores']   = $scoresArr;
$data['raw']['owner_earnings']     = $ownerArr;
$data['raw']['enterprise_values']  = $evArr;

// --- Owner Earnings je Aktie ---
$ownerEPS = null;

$ocf_ps   = $data['operatingCashFlowPerShare'] ?? null;
$capex_ps = $data['capexPerShare'] ?? null;

if (is_numeric($ocf_ps) && is_numeric($capex_ps)) {
	$ownerEPS = (float)$ocf_ps - (float)$capex_ps;
} else {
	$m0 = $data['raw']['metrics'][0] ?? [];
	$ocf_ps_m   = $m0['operatingCashFlowPerShare'] ?? null;
	$capex_ps_m = $m0['capexPerShare'] ?? null;
	if (is_numeric($ocf_ps_m) && is_numeric($capex_ps_m)) {
		$ownerEPS = (float)$ocf_ps_m - (float)$capex_ps_m;
	} else {
		$ocf_total   = $m0['operatingCashFlow'] ?? null;
		$capex_total = $m0['capitalExpenditure'] ?? null;
		$shares      = $data['raw']['profile'][0]['sharesOutstanding'] ?? null;
		if (is_numeric($ocf_total) && is_numeric($capex_total) && is_numeric($shares) && $shares > 0) {
			$ownerEPS = ((float)$ocf_total - (float)$capex_total) / (float)$shares;
		}
	}
}

if (!isset($data['inst']) || !is_array($data['inst'])) {
	$data['inst'] = ['altmanZ'=>null,'piotroskiF'=>null,'ownerEPS'=>null];
}
$data['inst']['ownerEPS'] = is_numeric($ownerEPS) ? round($ownerEPS, 4) : null;

// Bewertungskriterien
$CRITERIA_RULES = [
	'eps' => fn($x) => $x > 0,
	'peRatio' => fn($x) => $x > 5 && $x < 40,
	'revenuePerShare' => fn($x) => $x > 5,
	'roe' => fn($x) => $x > 0.1,
	'roa' => fn($x) => $x > 0.05,
	'roic' => fn($x) => $x > 0.1,
	'netProfitMargin' => fn($x) => $x > 0.1,
	'freeCashFlowYield' => fn($x) => $x > 0.03,
	'operatingCashFlowPerShare' => fn($x) => $x > 3,
	'capexToOperatingCashFlow' => fn($x) => $x < 0.3,
	'currentRatio' => fn($x) => $x > 1.2,
	'earningsYield' => fn($x) => $x > 0.04,
	'priceToSalesRatio' => fn($x) => $x < 10,
	'beta' => fn($x) => $x < 1.2,
	'pbRatio' => fn($x) => $x < 10,
	'interestCoverage' => fn($x) => $x >= 3,
	'workingCapital' => fn($x) => $x > 0,
	'intangiblesToTotalAssets' => fn($x) => $x < 0.3,
	'netDebtToEBITDA' => fn($x) => $x < 2.5,
	'payoutRatio' => fn($x) => $x < 0.6,
	'debtToEquity' => fn($x) => $x >= 0 && $x < 3,
	'evToEbitda' => fn($x) => $x > 4 && $x < 15,
	'pegRatio' => fn($x) => $x > 0 && $x < 1.5,
	'grossMargin' => fn($x) => $x > 0.3,
	'revenueGrowth' => fn($x) => $x > 0.05,
	'freeCashFlowGrowth' => fn($x) => $x > 0.05,
	'bookValueperShareGrowth' => fn($x) => $x > 0.01,
	'dividendsperShareGrowth' => fn($x) => $x > 0.01,
];

// Vordefinierte Branchen-Durchschnitts‑KGVs
$SECTOR_DEFAULT_PE = [
	'Technology' => 25,
	'Healthcare' => 18,
	'Financial Services' => 12,
	'Industrials' => 15,
	'Utilities' => 13,
	'Energy' => 10,
	'Consumer Defensive' => 16,
	'Consumer Cyclical' => 18,
	'Communication Services' => 17,
	'Real Estate' => 14,
	'Basic Materials' => 13
];

// Zusätzliche institutionelle Kriterien
$CRITERIA_RULES_INST = [
  'altmanZ'    => function($v){ return is_numeric($v) ? ($v >= 3.0) : null; },
  'piotroskiF' => function($v){ return is_numeric($v) ? ($v >= 7) : null; },
  'ownerEPS'   => function($v){ return is_numeric($v) ? ($v > 0) : null; }, 
  // 'evToEbitda' => function($v){ return is_numeric($v) ? ($v > 0 && $v <= 12) : null; },
];

// Gewichtung der Add-on-Sektion (z. B. 20 % des Gesamtscores)
$GROUPS_INST = [
  'Institutionell' => [
	'keys'      => ['altmanZ','piotroskiF','ownerEPS'],
	'weight'    => 0.20,
	'minCount'  => 1,
  ],
];

/* --- Scoring (ausgelagert) ---------------------------------------------- */
if ($data && is_array($data)) {
	// 1) Minimal-Prep: fehlende Felder aus raw/ratios/growth auffüllen
	$m0 = $data['raw']['metrics'][0] ?? [];
	$r0 = $data['raw']['ratios'][0]  ?? ($data['raw']['ratios'] ?? []); // falls TTM single row
	$g0 = $data['raw']['growth']     ?? [];

	// Basisfelder (nur setzen, wenn noch nicht vorhanden)
	$data['pe']                      = $data['pe']                      ?? ($m0['peRatio'] ?? ($r0['priceEarningsRatioTTM'] ?? null));
	$data['epsGrowth']               = $data['epsGrowth']               ?? ($m0['epsGrowth'] ?? ($g0['epsgrowth'] ?? null));
	$data['roe']                     = $data['roe']                     ?? ($m0['roe'] ?? ($r0['returnOnEquityTTM'] ?? null));
	$data['roa']                     = $data['roa']                     ?? ($m0['roa'] ?? ($r0['returnOnAssetsTTM'] ?? null));
	$data['roic']                    = $data['roic']                    ?? ($m0['roic'] ?? ($r0['returnOnCapitalEmployedTTM'] ?? null));
	$data['grossMargin']             = $data['grossMargin']             ?? ($r0['grossProfitMarginTTM'] ?? null);
	$data['netMargin']               = $data['netMargin']               ?? ($r0['netProfitMarginTTM'] ?? null);
	$data['currentRatio']            = $data['currentRatio']            ?? ($m0['currentRatio'] ?? null);
	$data['debtToEquity']            = $data['debtToEquity']            ?? ($r0['debtToEquityTTM'] ?? ($m0['debtToEquity'] ?? null));
	$data['dividendYield']           = $data['dividendYield']           ?? ($r0['dividendYieldTTM'] ?? ($m0['dividendYield'] ?? null));
	$data['payoutRatio']             = $data['payoutRatio']             ?? ($r0['payoutRatioTTM'] ?? ($m0['payoutRatio'] ?? null));
	$data['incomeQuality']           = $data['incomeQuality']           ?? ($m0['incomeQuality'] ?? null);
	$data['returnOnTangibleAssets']  = $data['returnOnTangibleAssets']  ?? ($m0['returnOnTangibleAssets'] ?? null);
	$data['pegRatio']                = $data['pegRatio']                ?? ($r0['pegRatioTTM'] ?? null);
	$data['revenueGrowth']           = $data['revenueGrowth']           ?? ($g0['revenueGrowth'] ?? null);
	$data['bookValueperShareGrowth'] = $data['bookValueperShareGrowth'] ?? ($g0['bookValueperShareGrowth'] ?? null);
	$data['grahamNumber']            = $data['grahamNumber']            ?? ($m0['grahamNumber'] ?? null);
	$data['fcf']                     = $data['fcf']                     ?? ($m0['freeCashFlowPerShare'] ?? null);
	$data['eps']                     = $data['eps']                     ?? ($m0['netIncomePerShare'] ?? null);

	// 2) Ziel-KGV optional aus der UI übernehmen
	$target_pe_override = (!empty($target_pe) && is_numeric($target_pe)) ? (float)$target_pe : null;
	
	// Tab = stabil/legacy: Fallback AUS
	$opts = ['enable_pe_fallback' => false];
	
	$res = bewertung_fundamental_score_from_data($data, $data_rating ?? null, $target_pe_override, $opts);
	
	// Ergebnis verfügbar machen
	$data['ratingScore'] = $res['score'];
	$data['ratingTotal'] = $res['total'];
	
	// Alias für Section-Logik (falls nicht schon vorhanden)
	$data['peRatio'] = $data['peRatio'] ?? ($data['pe'] ?? null);
	$data['pegRatio'] = (is_numeric($data['pe'] ?? null) && is_numeric($data['epsGrowth'] ?? null) && (float)$data['epsGrowth'] != 0.0)
	? ((float)$data['pe'] / (float)$data['epsGrowth'])
	: null;
	
	// Ziel-/Fair-Values für UI zurückspiegeln
	$data['target_pe']    = $res['target_pe_used'] ?? ($target_pe_override ?? ($data['target_pe'] ?? null));
	$data['fairValuePE']  = $res['fairValues']['pe']  ?? ($data['fairValuePE']  ?? null);
	$data['fairValueFCF'] = $res['fairValues']['fcf'] ?? ($data['fairValueFCF'] ?? null);
	
	// Texte/Abstände nur setzen, wenn fehlen (keine Doppellogik)
	$data['bewertungPE']  = $data['bewertungPE']  ?? bewertung_text($data['price'] ?? null, $data['fairValuePE']);
	$data['bewertungFCF'] = $data['bewertungFCF'] ?? bewertung_text($data['price'] ?? null, $data['fairValueFCF']);
	
	$data['distFairValuePE'] = $data['distFairValuePE'] ?? (
		(is_numeric($data['price'] ?? null)
		 && is_numeric($data['fairValuePE'] ?? null)
		 && (float)$data['fairValuePE'] != 0.0)
			? round(100 * (((float)$data['price'] - (float)$data['fairValuePE']) / (float)$data['fairValuePE']), 1)
			: null
	);
	
	$data['distFairValueFCF'] = $data['distFairValueFCF'] ?? (
		(is_numeric($data['price'] ?? null)
		 && is_numeric($data['fairValueFCF'] ?? null)
		 && (float)$data['fairValueFCF'] != 0.0)
			? round(100 * (((float)$data['price'] - (float)$data['fairValueFCF']) / (float)$data['fairValueFCF']), 1)
			: null
	);
}
/* --- /Scoring ----------------------------------------------------------- */

function bewertung_text($price, $fv) {
	if (!is_numeric($price) || !is_numeric($fv) || $fv == 0) return 'Nicht bewertbar';
	$d = ($price - $fv) / $fv;
	if ($d <= -0.3) return 'Stark unterbewertet (Kaufsignal)';
	if ($d <= -0.1) return 'Unterbewertet';
	if ($d <= 0.1)  return 'Fair bewertet';
	if ($d <= 0.25) return 'Leicht überbewertet';
	return 'Überbewertet (Vorsicht)';
}

function evaluate($key, $value) {
	global $CRITERIA_RULES;

	if (isset($CRITERIA_RULES[$key]) && is_numeric($value)) {
		return $CRITERIA_RULES[$key]($value) ? '✅' : '❌';
	}

	$skipKeys = [
		'symbol', 'date', 'sector',
		'sector_avg_pe', 'target_pe',
		'fairValuePE', 'fairValueFCF',
		'bewertungPE', 'bewertungFCF'
	];
	
	if (in_array($key, $skipKeys, true)) {
		return '–';
	}

	return null;
}

function translate_metric($k) {
  static $t = [
	'symbol'        => 'Symbol',
	'company'       => 'Unternehmen',
	'industry'      => 'Branche',
	'exchange'      => 'Börse',
	'volAvg'        => 'Ø Volumen',
	'date'          => 'Datum',
	'calendarYear'  => 'Jahr',
	'period'        => 'Periode',
	'price'         => 'Aktueller Kurs',
	'sector'        => 'Sektor',
	'netMargin'     => 'Nettomarge',
	'fcf'           => 'Free CF/Aktie',
	'epsGrowth'     => 'EPS-Wachstum',
	'pe'            => 'KGV',
	'ratingScore'   => 'Score erfüllt',
	'ratingTotal'   => 'Score gesamt',
	'dividendPerShare'         => 'Dividende/Aktie',
	'revenueGrowth'            => 'Umsatzwachstum',
	'bookValueperShareGrowth'  => 'Buchwert/Aktie Wachstum',
	'freeCashFlowGrowth'       => 'FCF-Wachstum',
	'dividendsperShareGrowth'  => 'Dividende/Aktie Wachstum',
	'distFairValuePE'          => 'Abstand Fair Value KGV',
	'distFairValueFCF'         => 'Abstand Fair Value FCF',
	'altmanZ'     => 'Altman-Z-Score',
	'piotroskiF'  => 'Piotroski-F-Score',
	'ownerEPS'    => 'Owner-Earnings/Aktie',
	'enterpriseValue' => 'Enterprise Value',
	'date'=>'Datum','calendarYear'=>'Jahr'
	,'period'=>'Periode',
	'eps'=>'Gewinn je Aktie','price'=>'Aktueller Kurs',
	'sector'=>'Sektor',
	'marketCap'=>'Marktkapitalisierung',
	'revenuePerShare'=>'Umsatz je Aktie',
	'netIncomePerShare'=>'Nettogewinn je Aktie',
	'operatingCashFlowPerShare'=>'Operativer CF je Aktie',
	'freeCashFlowPerShare'=>'Free CF je Aktie',
	'cashPerShare'=>'Cash je Aktie',
	'bookValuePerShare'=>'Buchwert je Aktie',
	'tangibleBookValuePerShare'=>'Sachbuchwert je Aktie',
	'shareholdersEquityPerShare'=>'Eigenkapital je Aktie',
	'interestDebtPerShare'=>'Zinslast pro Aktie',
	'peRatio'=>'Kurs-Gewinn-Verhältnis (KGV)',
	'priceToSalesRatio'=>'Kurs-Umsatz-Verhältnis',
	'pocfratio'=>'Kurs-Operativer-CF-Verhältnis',
	'pfcfRatio'=>'Kurs-Free-CF-Verhältnis',
	'pbRatio'=>'Kurs-Buchwert-Verhältnis',
	'ptbRatio'=>'Kurs-Sachbuchwert-Verhältnis',
	'earningsYield'=>'Gewinnrendite',
	'freeCashFlowYield'=>'Free CF Rendite',
	'roe'=>'Eigenkapitalrendite (ROE)',
	'roa'=>'Kapitalrendite (ROA)',
	'roic'=>'ROIC – Rendite auf investiertes Kapital',
	'returnOnTangibleAssets'=>'Rendite auf Sachwerte',
	'netProfitMargin'=>'Nettomarge',
	'dividendYield'=>'Dividendenrendite',
	'debtToEquity'=>'Verschuldungsgrad',
	'debtToAssets'=>'Schuldenquote',
	'currentRatio'=>'Liquiditätsgrad (Current Ratio)',
	'interestCoverage'=>'Zinsdeckungsgrad',
	'incomeQuality'=>'Qualität der Gewinne',
	'netDebtToEBITDA'=>'Netto-Schulden/EBITDA',
	'payoutRatio'=>'Ausschüttungsquote',
	'intangiblesToTotalAssets'=>'Immaterielle Vermögenswerte/Bilanz',
	'beta'=>'Beta (Risiko)',
	'workingCapital'=>'Working Capital',
	'sector_avg_pe'=>'Branchen-KGV',
	'target_pe'=>'Ziel-KGV',
	'fairValuePE'=>'Fairer Wert KGV',
	'fairValueFCF'=>'Fairer Wert FCF',
	'bewertungPE'=>'Bewertung KGV',
	'bewertungFCF'=>'Bewertung FCF',
	'evToEbitda'=>'EV/EBITDA',
	'evToSales'=>'EV/Umsatz',
	'enterpriseValue'=>'Enterprise Value (EV)',
	'enterpriseValueOverEBITDA'=>'EV/EBITDA (genauer)',
	'evToOperatingCashFlow'=>'EV/Operativer Cashflow',
	'evToFreeCashFlow'=>'EV/Free Cashflow',
	'pegRatio'=>'PEG-Ratio',
	'epsGrowth5y'=>'EPS-Wachstum (5J)'
	,'grossMargin'=>'Bruttomarge (TTM)',
	'salesGeneralAndAdministrativeToRevenue'=>'Verwaltungs-/Vertriebskostenquote',
	'researchAndDdevelopementToRevenue'=>'F&E-Anteil am Umsatz',
	'capexToOperatingCashFlow'=>'CapEx zu operativem Cashflow',
	'capexToRevenue'=>'CapEx zu Umsatz',
	'capexToDepreciation'=>'CapEx zu Abschreibungen',
	'stockBasedCompensationToRevenue'=>'Aktienvergütung zu Umsatz',
	'grahamNumber'=>'Graham-Zahl',
	'grahamNetNet'=>'Graham-Net-Net-Wert',
	'tangibleAssetValue'=>'Sachvermögen',
	'netCurrentAssetValue'=>'Net Current Asset Value (NCAV)',
	'investedCapital'=>'Investiertes Kapital',
	'averageReceivables'=>'Ø Forderungen','averagePayables'=>'Ø Verbindlichkeiten',
	'averageInventory'=>'Ø Lagerbestand',
	'daysSalesOutstanding'=>'Zahlungseingang in Tagen',
	'daysPayablesOutstanding'=>'Lieferantenzahlung in Tagen',
	'daysOfInventoryOnHand'=>'Lagerdauer in Tagen',
	'receivablesTurnover'=>'Forderungsumschlag',
	'payablesTurnover'=>'Verbindlichkeitenumschlag',
	'inventoryTurnover'=>'Lagerumschlag',
	'capexPerShare'=>'Investitionen je Aktie',
  ];
  return $t[$k] ?? $k;
}

function explain($k) {
  static $e = [
	'symbol'        => 'Ticker-Symbol der Aktie',
	'company'       => 'Name des Unternehmens',
	'industry'      => 'Branche des Unternehmens',
	'exchange'      => 'Börsenplatz',
	'volAvg'        => 'Durchschnittliches Handelsvolumen',
	'date'          => 'Stichtag der letzten Daten',
	'calendarYear'  => 'Kalenderjahr der Daten',
	'period'        => 'Berichtsperiode (z. B. FY für Geschäftsjahr)',
	'price'         => 'Aktueller Börsenkurs',
	'sector'        => 'Sektor gemäß Branchenklassifikation',
	'netMargin'     => 'Nettomarge',
	'fcf'           => 'Free Cashflow je Aktie',
	'epsGrowth'     => 'EPS-Wachstum im letzten Jahr',
	'pe'            => 'Kurs-Gewinn-Verhältnis (KGV)',
	'ratingScore'   => 'Erfüllte Kriterien gesamt',
	'ratingTotal'   => 'Anzahl bewerteter Kriterien gesamt',
	'dividendPerShare' => 'Dividende je Aktie',
	'revenueGrowth' => 'Umsatzwachstum',
	'bookValueperShareGrowth' => 'Buchwert je Aktie – Wachstum',
	'freeCashFlowGrowth' => 'Free-Cashflow-Wachstum',
	'dividendsperShareGrowth' => 'Dividende je Aktie – Wachstum',
	'altmanZ'     => 'Altman-Z-Score (Insolvenzrisiko-Indikator)',
	'piotroskiF'  => 'Piotroski-F-Score (Bilanzqualität 0–9)',
	'ownerEPS'    => 'Owner Earnings je Aktie (qualitätsbereinigter Cashflow)',
	'date'=>'Stichtag der letzten Daten',
	'calendarYear'=>'Kalenderjahr der Daten',
	'period'=>'Berichtsperiode (z. B. FY für Geschäftsjahr)',
	'price'=>'Aktueller Börsenkurs',
	'sector'=>'Sektor gemäß Branchenklassifikation',
	'marketCap'=>'Marktkapitalisierung – Börsenwert des Unternehmens',
	'eps'=>'Gewinn je Aktie (EPS) – sollte positiv sein',
	'peRatio'=>'KGV – zwischen 5 und 40 gilt als fair bewertet',
	'revenuePerShare'=>'Umsatz pro Aktie – über 5 USD ist solide',
	'netIncomePerShare'=>'Nettogewinn pro Aktie – sollte positiv sein',
	'operatingCashFlowPerShare'=>'Operativer Cashflow je Aktie – über 3 USD ist gut',
	'freeCashFlowPerShare'=>'Free Cashflow je Aktie – zeigt Kapitalgenerierung',
	'cashPerShare'=>'Barbestand pro Aktie',
	'bookValuePerShare'=>'Buchwert pro Aktie – bilanzieller Substanzwert',
	'tangibleBookValuePerShare'=>'Sachbuchwert – ohne immaterielle Assets',
	'shareholdersEquityPerShare'=>'Eigenkapital je Aktie – je höher, desto substanzstärker',
	'interestDebtPerShare'=>'Zinstragende Schulden pro Aktie',
	'priceToSalesRatio'=>'Kurs/Umsatz – <10 gilt als fair',
	'pocfratio'=>'Preis zu operativem Cashflow – unter 15 ist attraktiv',
	'pfcfRatio'=>'Preis zu Free Cashflow – <20 bevorzugt',
	'pbRatio'=>'Kurs/Buchwert – <10 ist akzeptabel',
	'ptbRatio'=>'Kurs/Sachbuchwert – substanznahe Bewertung',
	'earningsYield'=>'Gewinnrendite – sollte über 4 % liegen',
	'freeCashFlowYield'=>'Free CF-Rendite – über 3 % ist solide',
	'roe'=>'Return on Equity – über 10 % zeigt starke Eigenkapitalrendite',
	'roa'=>'ROA – Kapitalrendite über 5 % ist gesund',
	'roic'=>'ROIC – über 10 % zeigt gutes Kapitalmanagement',
	'returnOnTangibleAssets'=>'Rendite auf Sachwerte – je höher, desto besser',
	'netProfitMargin'=>'Nettomarge – über 10 % ist solide',
	'dividendYield'=>'Dividendenrendite – je nach Strategie relevant',
	'debtToEquity'=>'Verschuldungsgrad – zwischen 0 und 3 sinnvoll',
	'debtToAssets'=>'Schuldenquote – unter 50 % ist konservativ',
	'currentRatio'=>'Liquiditätsgrad – über 1,2 ist sicher',
	'incomeQuality'=>'Gewinnqualität – misst Realitätsnähe der Gewinne',
	'netDebtToEBITDA'=>'Netto-Schulden/EBITDA – unter 2.5 ist gut',
	'payoutRatio'=>'Ausschüttungsquote – unter 60 % nachhaltig',
	'intangiblesToTotalAssets'=>'Immaterielle Vermögenswerte – unter 30 % bevorzugt',
	'beta'=>'Risiko-Kennzahl – unter 1.2 = unterdurchschnittliche Volatilität',
	'workingCapital'=>'Differenz aus Umlaufvermögen und kurzfristigen Verbindlichkeiten',
	'sector_avg_pe'=>'Branchen-KGV – zum Vergleich mit eigenem KGV',
	'target_pe'=>'Ziel-KGV – kann manuell überschrieben werden',
	'fairValuePE'=>'Fairer Wert auf KGV-Basis',
	'fairValueFCF'=>'Fairer Wert auf Basis Discounted FCF',
	'bewertungPE'=>'Bewertung im Vergleich zum KGV-Fair-Value',
	'distFairValuePE'=>'Abstand in % zum KGV-Fair-Value',
	'bewertungFCF'=>'Bewertung im Vergleich zum FCF-Fair-Value',
	'distFairValueFCF'=>'Abstand in % zum FCF-Fair-Value',
	'bewertungFCF'=>'Bewertung im Vergleich zum FCF-Fair-Value',
	'evToEbitda'=>'EV/EBITDA – 4 bis 15 gilt als fair bewertet',
	'evToSales'=>'EV/Umsatz – unter 3 zeigt günstige Bewertung',
	'enterpriseValue'=>'Enterprise Value – Gesamtwert des Unternehmens (inkl. Schulden)',
	'enterpriseValueOverEBITDA'=>'Alternative zu EV/EBITDA',
	'evToOperatingCashFlow'=>'EV zu operativem Cashflow – unter 15 sinnvoll',
	'evToFreeCashFlow'=>'EV zu Free Cashflow – unter 20 günstig',
	'pegRatio'=>'PEG-Ratio – unter 1.5 ist wachstumsangepasst günstig',
	'epsGrowth5y'=>'EPS-Wachstum 5 Jahre – über 5 % stabil',
	'grossMargin'=>'Bruttomarge – über 30 % zeigt Preissetzungsmacht',
	'salesGeneralAndAdministrativeToRevenue'=>'Verwaltungskostenanteil am Umsatz',
	'researchAndDdevelopementToRevenue'=>'F&E-Quote – Innovationskennzahl',
	'capexToOperatingCashFlow'=>'CapEx/Cashflow – unter 30 % zeigt gesunden Spielraum',
	'capexToRevenue'=>'Investitionsquote bezogen auf Umsatz',
	'capexToDepreciation'=>'CapEx zu Abschreibungen – über 1 = wachstumsorientiert',
	'stockBasedCompensationToRevenue'=>'Aktienvergütung zu Umsatz – unter 5 % solide',
	'grahamNumber'=>'Grahams fairer Wert – konservative Bewertungsformel',
	'grahamNetNet'=>'Netto-Substanzwert (Graham) – sollte positiv sein',
	'tangibleAssetValue'=>'Vermögenswerte ohne immaterielle Posten',
	'netCurrentAssetValue'=>'Net Current Asset Value – konservative Liquidationsbewertung',
	'investedCapital'=>'Kapitalbasis für operatives Geschäft',
	'averageReceivables'=>'Ø Forderungen – für Effizienzmessung',
	'averagePayables'=>'Ø Verbindlichkeiten – für Zahlungslaufzeit',
	'averageInventory'=>'Ø Lagerbestand – für Umschlagrate',
	'daysSalesOutstanding'=>'Zahlungseingang in Tagen – niedriger ist besser',
	'daysPayablesOutstanding'=>'Zahlungsverzögerung an Lieferanten – höher = besserer Cashflow',
	'daysOfInventoryOnHand'=>'Lagerreichweite – kurze Lagerzeiten sind effizient',
	'receivablesTurnover'=>'Forderungsumschlag – wie oft werden Forderungen eingezogen',
	'payablesTurnover'=>'Lieferantenumschlag – je höher, desto schneller wird gezahlt',
	'inventoryTurnover'=>'Lagerumschlag – hohe Umschlagsrate ist positiv',
	'capexPerShare'=>'Investitionen pro Aktie – zeigt Wachstumsinvestitionen',
  ];
  return $e[$k] ?? '';
}

function explain_detailed($k) {
	static $e = [
		
		'symbol'        => 'Ticker-Symbol der Aktie',
		'company'       => 'Vollständiger Name des Unternehmens',
		'industry'      => 'Branche, in der das Unternehmen tätig ist',
		'exchange'      => 'Börse, an der das Wertpapier primär gelistet ist',
		'volAvg'        => 'Durchschnittliches tägliches Handelsvolumen – zeigt Liquidität der Aktie',
		'beta'          => 'Risiko-Kennzahl – unter 1.2 = unterdurchschnittliche Volatilität',
		'marketCap'     => 'Marktkapitalisierung – Börsenwert des Unternehmens',
		'netMargin'     => 'Nettomarge – Gewinn in Prozent des Umsatzes',
		'fcf'           => 'Free Cashflow je Aktie – zeigt Kapitalgenerierung',
		'epsGrowth'     => 'EPS-Wachstum im letzten Jahr – zeigt Gewinnwachstum pro Aktie',
		'pe'            => 'Kurs-Gewinn-Verhältnis (KGV)',
		'ratingScore'   => 'Erfüllte Kriterien in der Gesamtbewertung',
		'ratingTotal'   => 'Gesamtzahl der bewerteten Kriterien',
		'dividendPerShare'         => 'Ausgeschüttete Dividende je Aktie (TTM).',
		'revenueGrowth'            => 'Umsatzwachstum – Veränderung der Erlöse gegenüber Vorperiode.',
		'bookValueperShareGrowth'  => 'Wachstum des Buchwerts je Aktie – Indikator für Substanzaufbau.',
		'freeCashFlowGrowth'       => 'Wachstum des freien Cashflows – zeigt Entwicklung der Mittelgenerierung.',
		'dividendsperShareGrowth'  => 'Wachstum der Dividende je Aktie – Hinweis auf Ausschüttungsdynamik.',
		'altmanZ'     => 'Z-Score > 3 signalisiert solide Bilanz, 1.8–3 Graubereich, < 1.8 distress.',
		'piotroskiF'  => 'Score 0–9: ≥7 gilt als stark; basiert u. a. auf Profitabilität, Verschuldung, Effizienz.',
		'ownerEPS'    => 'Owner Earnings (Buffett-ähnliches Maß): operativer Cashflow – „notwendige“ Wartungs-CapEx je Aktie.',

		// Gewinn & Bewertung
		'eps' => 'Gewinn je Aktie – zeigt, wie profitabel das Unternehmen je Aktie ist.',
		'peRatio' => 'Kurs-Gewinn-Verhältnis – wie oft der Gewinn im Aktienkurs enthalten ist.',
		'earningsYield' => 'Gewinnrendite – Kehrwert des KGV, je höher desto günstiger.',
		'priceToSalesRatio' => 'Kurs-Umsatz-Verhältnis – wie viel Anleger für 1 $ Umsatz zahlen.',
		'pfcfRatio' => 'Kurs/Free-Cashflow – wie teuer ist der freie Cashflow bewertet.',
		'pbRatio' => 'Kurs-Buchwert-Verhältnis – zeigt die Bewertung im Verhältnis zum Eigenkapital.',
		'ptbRatio' => 'Preis zu Sachbuchwert – Variante des PB-Ratios ohne immaterielle Werte.',
		'pegRatio' => 'Preis/Gewinn-Wachstums-Verhältnis – je kleiner, desto günstiger im Verhältnis zum Wachstum.',
		'evToEbitda' => 'EV/EBITDA – Unternehmenswert zu operativem Ergebnis. 4–15 gilt als fair.',
		'evToSales' => 'EV/Sales – Unternehmenswert im Verhältnis zum Umsatz.',
		'enterpriseValue' => 'Unternehmenswert inkl. Schulden – realistischer als Marktkapitalisierung.',
		'pocfratio' => 'Preis/Operating-Cashflow – Kurs in Relation zum operativen Cashflow.',
		'price' => 'Aktueller Börsenkurs der Aktie.',

		// Cashflow & Kapital
		'operatingCashFlowPerShare' => 'Operativer Cashflow je Aktie – wichtiger Indikator für Innenfinanzierung.',
		'freeCashFlowPerShare' => 'Freier Cashflow je Aktie – was nach Investitionen übrig bleibt.',
		'cashPerShare' => 'Cash je Aktie – Liquidität pro Aktie.',
		'capexPerShare' => 'Investitionen pro Aktie – wie viel je Aktie ins Anlagevermögen fließt.',
		'capexToOperatingCashFlow' => 'Investitionen zu operativem Cashflow – wie viel vom Cashflow investiert wird.',
		'capexToRevenue' => 'Capex/Umsatz – wie viel vom Umsatz wird reinvestiert.',
		'capexToDepreciation' => 'Capex zu Abschreibungen – Verhältnis von Neuinvestitionen zu Abschreibungen.',
		'stockBasedCompensationToRevenue' => 'Aktienbasierte Vergütung zu Umsatz – wie stark Mitarbeiter durch Aktien vergütet werden.',

		// Rentabilität & Effizienz
		'roe' => 'Eigenkapitalrendite – wie profitabel arbeitet das Unternehmen mit seinem Eigenkapital.',
		'roa' => 'Gesamtkapitalrendite – Verzinsung des gesamten Kapitals.',
		'roic' => 'Return on Invested Capital – Kapitalrendite für Investoren, sehr wichtig.',
		'netProfitMargin' => 'Nettomarge – wie viel vom Umsatz bleibt als Gewinn übrig.',
		'grossMargin' => 'Bruttomarge – Gewinn nach Materialeinsatz, zeigt Preissetzungsmacht.',
		'returnOnTangibleAssets' => 'Rendite auf Sachwerte – wie effizient physische Assets eingesetzt werden.',

		// Verschuldung & Bilanz
		'debtToEquity' => 'Verschuldungsgrad – wie viel Fremdkapital auf das Eigenkapital entfällt.',
		'netDebtToEBITDA' => 'Netto-Verschuldung im Verhältnis zum EBITDA – misst Rückzahlbarkeit der Schulden.',
		'interestCoverage' => 'Zinsdeckungsgrad – wie gut Zinsen aus dem EBIT bezahlt werden können.',
		'currentRatio' => 'Liquiditätsgrad – kurzfristige Vermögen zu kurzfristigen Verbindlichkeiten.',
		'payoutRatio' => 'Ausschüttungsquote – wie viel vom Gewinn als Dividende gezahlt wird.',
		'intangiblesToTotalAssets' => 'Immaterielle Vermögenswerte zu Bilanzsumme – zeigt Abhängigkeit von z. B. Patenten.',
		'workingCapital' => 'Working Capital – Differenz aus Umlaufvermögen und kurzfristigen Schulden.',
		'debtToAssets' => 'Verschuldung zur Bilanzsumme – wie viel vom Vermögen fremdfinanziert ist.',
		'salesGeneralAndAdministrativeToRevenue' => 'Verwaltungs- & Vertriebskosten zu Umsatz – zeigt Kostenstruktur.',
		'researchAndDdevelopementToRevenue' => 'F&E-Ausgaben zu Umsatz – wie innovationsgetrieben ist das Unternehmen.',
		'shareholdersEquityPerShare' => 'Eigenkapital je Aktie – was Aktionären rechnerisch zusteht.',
		'interestDebtPerShare' => 'Zinstragende Schulden je Aktie – zeigt Verschuldung pro Aktie.',

		// Graham
		'grahamNumber' => 'Graham Number – konservativer fairer Wert nach Benjamin Graham.',
		'grahamNetNet' => 'Net-Net-Wert – Substanzwert nach Graham abzüglich aller Schulden.',

		// Effizienzkennzahlen (Working Capital Days)
		'daysSalesOutstanding' => 'Ø Forderungslaufzeit – wie viele Tage durchschnittlich bis Zahlungseingang.',
		'daysPayablesOutstanding' => 'Ø Kreditorenlaufzeit – wie lange das Unternehmen durchschnittlich für Zahlungen benötigt.',
		'daysOfInventoryOnHand' => 'Ø Lagerdauer – wie lange Produkte durchschnittlich auf Lager liegen.',
		'receivablesTurnover' => 'Umschlagshäufigkeit der Forderungen – je höher, desto schneller der Zahlungseingang.',
		'payablesTurnover' => 'Umschlag der Verbindlichkeiten – je höher, desto schneller werden Lieferanten bezahlt.',
		'inventoryTurnover' => 'Lagerumschlag – misst, wie oft der Lagerbestand verkauft wird.',

		// Substanz- und Kapitalstruktur
		'tangibleAssetValue' => 'Sachvermögen – physisches Vermögen wie Maschinen oder Gebäude.',
		'netCurrentAssetValue' => 'Netto-Umlaufvermögen – aktuelles Vermögen abzüglich kurzfristiger Schulden.',
		'investedCapital' => 'Investiertes Kapital – Eigenkapital + zinstragendes Fremdkapital.',
		'averageReceivables' => 'Ø Forderungen – offenstehende Rechnungen im Schnitt.',
		'averagePayables' => 'Ø Verbindlichkeiten – noch zu zahlende Rechnungen im Schnitt.',
		'averageInventory' => 'Ø Lagerbestand – durchschnittlich gebundenes Kapital im Lager.',
	];
	return $e[$k] ?? '';
}

function weighted_score(array $data, ?array $rating = null): array {
	global $CRITERIA_RULES;

	$criteria = array_keys($CRITERIA_RULES);
	$score = 0;
	$total = 0;

	foreach ($criteria as $key) {
		$result = evaluate($key, $data[$key] ?? null);
		if ($result === '✅' || $result === '❌') {
			$total++;
			if ($result === '✅') $score++;
		}
	}

	return [$score, $total];
}

function rating_color_class($rating) {
	if (!$rating) return 'secondary';
	$r = strtoupper($rating);
	if (in_array($r, ['A+', 'A', 'A-'])) return 'success';
	if (in_array($r, ['B+', 'B', 'B-'])) return 'secondary';
	if (in_array($r, ['C+', 'C', 'C-'])) return 'secondary';
	if (in_array($r, ['D+', 'D', 'D-', 'F'])) return 'danger';
	return 'secondary';
}

function score_to_text($s, $t) {
	$p = $t ? round($s / $t * 100) : 0;
	if ($p >= 85) return ['text' => 'Exzellente Qualitätsaktie mit starker Fundamentaldatenbasis.', 'class' => 'success', 'percent' => $p];
	if ($p >= 70) return ['text' => 'Solide Qualität – gutes Fundament mit kleineren Schwächen.', 'class' => 'info', 'percent' => $p];
	if ($p >= 50) return ['text' => 'Durchschnittliche Qualität – genau prüfen.', 'class' => 'warning', 'percent' => $p];
	return ['text' => 'Sehr schwache Fundamentaldaten – Vorsicht geboten.', 'class' => 'danger', 'percent' => $p];
}

function section_scores(array $data): array {
	global $CRITERIA_RULES;

	$sections = [
		'Bewertungskennzahlen' => ['peRatio','fairValuePE','fairValueFCF','priceToSalesRatio','pbRatio','evToEbitda','pegRatio'],
		'Rentabilität' => ['roe','roa','roic','netProfitMargin','grossMargin','earningsYield'],
		'Bilanzqualität' => ['debtToEquity','currentRatio','intangiblesToTotalAssets','workingCapital','netDebtToEBITDA','payoutRatio'],
		'Cashflow-Betrachtung' => ['freeCashFlowYield','operatingCashFlowPerShare','capexToOperatingCashFlow','capexPerShare','incomeQuality'],
		'Wachstumsperspektive' => ['revenueGrowth','freeCashFlowGrowth','bookValueperShareGrowth','dividendsperShareGrowth'],
	];

	$results = [];

	foreach ($sections as $sectionName => $keys) {
		$score = 0;
		$total = 0;

		foreach ($keys as $k) {
			$value = $data[$k] ?? null;
			$rule = $CRITERIA_RULES[$k] ?? null;

			if (is_callable($rule) && $value !== null) {
				$total++;
				if ($rule($value)) {
					$score++;
				}
			}
		}

		$results[$sectionName] = [
			'score' => $score,
			'total' => $total,
			'percent' => $total > 0 ? round($score / $total * 100) : 0,
			'keys' => $keys
		];
	}

	return $results;
}

function show_warning(array $data, float $avgThreshold = 20.0): bool {
	$peOver  = (($data['bewertungPE']  ?? '') === 'Überbewertet (Vorsicht)');
	$fcfOver = (($data['bewertungFCF'] ?? '') === 'Überbewertet (Vorsicht)');

	if ($peOver && $fcfOver) return true;

	$devs = [];
	if (isset($data['distFairValuePE'])  && is_numeric($data['distFairValuePE'])  && $data['distFairValuePE']  > 0) $devs[] = (float)$data['distFairValuePE'];
	if (isset($data['distFairValueFCF']) && is_numeric($data['distFairValueFCF']) && $data['distFairValueFCF'] > 0) $devs[] = (float)$data['distFairValueFCF'];

	if (!empty($devs)) {
		$avg = array_sum($devs) / count($devs);
		if ($avg > $avgThreshold) return true;
	}
	return false;
}

?>

<div class="row align-items-stretch">
	<?php if (!empty($data['asofSelected'])): ?>
		<div class="col-12">
			<div class="alert alert-light text-dark py-2">
				<strong>Zeitraum bis: <?= htmlspecialchars($data['asofSelected']) ?></strong>
				<?php if (!empty($data['effectiveDate']) && $data['effectiveDate'] !== $data['asofSelected']): ?>
					<small class="text-muted ms-2">
						Datenstand: <?= htmlspecialchars($data['effectiveDate']) ?>
					</small>
				<?php endif; ?>
			</div>
		</div>
	<?php endif; ?>
	<div class="col-lg-6 d-flex">
		<div class="card w-100 h-100">
			<div class="card-body d-flex flex-column h-100">
				<?php
				$logoUrl =
					$data['raw']['profile'][0]['image']
					?? ($data['raw']['profile']['image'] ?? null)
					?? null;
				
				$companyLabel = $data['company'] ?: $data['symbol'];
				?>
				<div class="d-flex align-items-center justify-content-start mb-2">
					<?php
					$imgFallback = '/assets/img/company-placeholder.webp';
					$imgSrc = (!empty($logoUrl) && filter_var($logoUrl, FILTER_VALIDATE_URL))
						? $logoUrl
						: $imgFallback;
					?>
					<img
					  src="<?= htmlspecialchars($imgSrc) ?>"
					  alt="<?= htmlspecialchars($companyLabel) ?> Logo"
					  loading="lazy"
					  decoding="async"
					  width="45" height="45"
					  class="rounded-circle border me-3"
					  referrerpolicy="no-referrer"
					  onerror="this.onerror=null;this.src='<?= htmlspecialchars($imgFallback) ?>';"
					/>
					<div>
						<h5 class="mb-0">
							<strong><?= htmlspecialchars($data['company'] ?? '') ?> (<?= htmlspecialchars($symbol) ?>)</strong>
						</h5>
						<p class="mb-0 text-muted"><?= htmlspecialchars($data['sector'] ?? 'Branche unbekannt') ?></p>
					</div>
				</div>
				<ul class="list-group mb-4">
					<?php if (!empty($data['raw']['profile'][0]['mktCap'])): ?>
						<?php
						$marketCap = $data['raw']['profile'][0]['mktCap'];
						$marketCapBillion = $marketCap / 1_000_000_000;
						$marketCapClass = ($marketCap < 3_000_000_000) ? 'text-danger' : 'text-body';
						$marketCapDiffPercent = ($marketCap < 3_000_000_000)
							? round((3_000_000_000 - $marketCap) / 3_000_000_000 * 100, 1)
							: null;
						?>
						<li class="list-group-item">
							Marktkapitalisierung:
							<strong class="<?= $marketCapClass ?>">
								<?= number_format($marketCapBillion, 2, ',', '.') ?> Mrd. USD
							</strong>
							<?php if ($marketCapDiffPercent !== null): ?>
								<br><small class="text-muted">−<?= $marketCapDiffPercent ?> % unter der 3 Mrd.-Schwelle</small>
							<?php endif; ?>
						</li>
					<?php endif; ?>
					<li class="list-group-item">
						Akt. Kurs: <strong><?= number_format($data['price'], 2) ?> USD</strong>
					</li>
					<li class="list-group-item">
						<?php if (is_numeric($data['target_pe'] ?? null)): ?>
							Fairer Wert KGV (<?= is_numeric($data['fairValuePE']) ? number_format($data['fairValuePE'], 2) . ' USD' : '–' ?>): 
						<?php else: ?>
							Fairer Wert KGV:
						<?php endif; ?>
						<?php if (is_numeric($data['fairValuePE'] ?? null)): ?>
							<strong><?= number_format((float)$data['fairValuePE'], 2) ?> USD</strong>
						<?php else: ?>
							<strong>–</strong>
						<?php endif; ?>
						→ <?= htmlspecialchars($data['bewertungPE'] ?? 'Nicht bewertbar') ?>
						<?php if (isset($data['distFairValuePE']) && is_numeric($data['distFairValuePE'])): ?>
							<br><small class="text-muted">Abweichung: <?= ($data['distFairValuePE'] >= 0 ? '+' : '') . $data['distFairValuePE'] ?> %</small>
						<?php endif; ?>
					</li>
					<li class="list-group-item">
						Fairer Wert FCF: 
						<strong><?= is_numeric($data['fairValueFCF'] ?? null) ? number_format((float)$data['fairValueFCF'], 2) . ' USD' : 'Nicht berechenbar' ?></strong>
						<?= is_numeric($data['fairValueFCF'] ?? null) ? '→ ' . htmlspecialchars($data['bewertungFCF'] ?? '') : '' ?>
						<?php if (isset($data['distFairValueFCF'])): ?>
							<br><small class="text-muted">Abweichung: <?= ($data['distFairValueFCF'] >= 0 ? '+' : '') . $data['distFairValueFCF'] ?> %</small>
						<?php endif; ?>
					</li>
				</ul>
				<?php list($sc, $to) = weighted_score($data, $data_rating ?? null); $txt = score_to_text($sc, $to); ?>
				<div class="alert alert-<?= htmlspecialchars($txt['class']) ?>">
					<i class="fa-solid fa-circle text-<?= htmlspecialchars($txt['class']) ?> me-2"></i>
					<?= htmlspecialchars($txt['text']) ?>
				</div>
				<div class="progress mb-2" style="height:20px;">
					<div class="progress-bar bg-<?= htmlspecialchars($txt['class']) ?>" style="width:<?= htmlspecialchars($txt['percent']) ?>%;">
						<?= htmlspecialchars($txt['percent']) ?>%
					</div>
				</div>
				<?php list($sc, $to) = weighted_score($data, $data_rating ?? null); $txt = score_to_text($sc,$to); ?>
				<p class="mb-0">Erfüllt: <strong><?= $sc ?> von <?= $to ?></strong></p>
			</div>
		</div>
	</div>
	<div class="col-lg-6 d-flex">
		<div class="card w-100 h-100">
			<div class="card-body d-flex flex-column h-100">
				<canvas id="valuationChart" width="400" height="280"></canvas>
			</div>
		</div>
	</div>
</div>

<div class="row g-3 mt-3">
	<div class="col-12">
		<h5 class="mb-0">Strukturierte Teilbewertung:</h5>
	</div>
	<?php
		$sections = section_scores($data);
		
		if (show_warning($data, 20)) {  // z. B. 20% Schwelle
			echo '<div class="col-12"><div class="alert alert-danger"><strong>Vorsicht:</strong> Mehrere Bewertungsmethoden deuten auf eine Überbewertung hin!</div></div>';
		}
		
		foreach ($sections as $name => $s) {
			echo '<div class="col-md-6 col-lg-4">';
			echo '<div class="card h-100">';
			echo '<div class="card-body">';
			echo '<h6>' . htmlspecialchars($name) . '</h6>';
			echo '<div class="progress" style="height:20px;">';
			echo '<div class="progress-bar bg-dark" style="width:' . $s['percent'] . '%">' . $s['percent'] . '%</div>';
			echo '</div>';
			echo '<p class="mt-2 mb-0 small">Erfüllt: ' . $s['score'] . ' von ' . $s['total'] . '</p>';
			echo '</div></div></div>';
		}
	?>
	<div class="col-md-6 col-lg-4">
		<div class="card h-100">
			<div class="card-body">
				<?php
				// === Institutionelle Zusatzkriterien (robust, paket-agnostisch) ===
				
				// 1) Default-Container (falls noch nicht gesetzt)
				if (!isset($data['inst']) || !is_array($data['inst'])) {
					$data['inst'] = ['altmanZ'=>null,'piotroskiF'=>null,'ownerEPS'=>null];
				}
				
				// 2) Regeln einmalig setzen
				if (!isset($CRITERIA_RULES_INST) || !is_array($CRITERIA_RULES_INST)) {
					$CRITERIA_RULES_INST = [
						'altmanZ'    => function($v){ return is_numeric($v) ? ($v >= 3.0) : null; },
						'piotroskiF' => function($v){ return is_numeric($v) ? ($v >= 7)   : null; },
						'ownerEPS'   => function($v){ return is_numeric($v) ? ($v > 0)    : null; },
					];
				}
				
				// 3) Nur Kriterien bewerten, die tatsächlich Werte haben (FMP Starter/Premium-kompatibel)
				$availableKeys = [];
				foreach (['altmanZ','piotroskiF','ownerEPS'] as $key) {
					if (isset($data['inst'][$key]) && is_numeric($data['inst'][$key])) {
						$availableKeys[] = $key;
					}
				}
				
				// 4) Schutzfunktion für leere/NULL-Ergebnisse
				if (!function_exists('safe_section_scores')) {
					function safe_section_scores(array $vals, array $rules, array $keys): array {
						if (empty($keys)) return [0, 0];
						$res = section_scores($vals, $rules, $keys);
						if (!is_array($res)) return [0, 0];
						$vals = array_values($res);
						$vals = array_pad($vals, 2, 0);
						return [(int)$vals[0], (int)$vals[1]];
					}
				}
				
				// 5) Score berechnen (ohne list(), ohne direkte Indizes)
				list($scInst, $toInst) = safe_section_scores($data['inst'], $CRITERIA_RULES_INST, $availableKeys);
				$txtInst = score_to_text($scInst, $toInst);
				?>
				<h6>Institutionelle Zusatzkriterien</h6>
				<div class="progress mb-2" style="height:20px;">
					<div class="progress-bar bg-dark" style="width:<?= htmlspecialchars($txtInst['percent']) ?>%;">
						<?= htmlspecialchars($txtInst['percent']) ?>%
				    </div>
				</div>
				<p class="mt-2 mb-0 small">Erfüllt: <?= (int)$scInst ?> von <?= (int)$toInst ?></p>
			</div>
		</div>
	</div>
</div>

<div class="row mt-3">	
	<div class="col-12">
		<button
			class="btn btn-outline-secondary btn-sm mb-2"
			type="button"
			data-bs-toggle="collapse"
			data-bs-target="#fundamental-table"
			aria-expanded="false"
			aria-controls="fundamental-table">
			Details Kennzahlen
		</button>
		<div class="collapse" id="fundamental-table">
			<div class="card mt-2">
				<div class="card-body"
					<h5>Fundamentale Kennzahlen</h5>
					<div class="table-responsive">
						<table class="table mb-0">
							<thead class="table-dark"><tr><th>Beschreibung</th><th>Wert</th><th>Kennzahl</th><th>Status</th></tr></thead><tbody>
							<?php foreach ($data as $k => $v): if (is_array($v)) continue; ?>
								<?php $r = evaluate($k, $v); ?>
								<tr>
									<td>
										<?php if ($detail = explain_detailed($k)): ?>
											<i class="fa-solid fa-circle-info text-muted me-1"
											data-bs-toggle="tooltip"
											title="<?= htmlspecialchars($detail) ?>"></i>
										<?php endif; ?>
										<?= htmlspecialchars(translate_metric($k)) ?>
									</td>
									<td>
										<?= isset($v) && $v !== '' ? htmlspecialchars(is_numeric($v) ? number_format($v, 4, ',', '.') : $v) : '–' ?>
									</td>
									<td>
										<small class="text-muted"><?= htmlspecialchars($k) ?></small>
									</td>
									<td>
									<?= $r ?>
									<small class="text-muted ms-1"><?= htmlspecialchars(explain($k)) ?></small>
									</td>
								</tr>
							<?php endforeach; ?>
							</tbody>
						</table>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>

<script>
function renderValuationChart() {
	const el = document.getElementById('valuationChart');
	if (!el) return;

	const ctx = el.getContext('2d');
	new Chart(ctx, {
		type: 'bar',
		data: {
			labels: [
				'Aktueller Kurs',
				<?php if (is_numeric($data['fairValuePE']) && is_numeric($data['distFairValuePE'])): ?>
					'Fair Value (KGV) (<?= ($data['distFairValuePE'] >= 0 ? '+' : '') . $data['distFairValuePE'] ?>%)',
				<?php else: ?>
					'Fair Value (KGV)',
				<?php endif; ?>
				<?php if (is_numeric($data['fairValueFCF']) && is_numeric($data['distFairValueFCF'])): ?>
					'Fair Value (FCF) (<?= ($data['distFairValueFCF'] >= 0 ? '+' : '') . $data['distFairValueFCF'] ?>%)'
				<?php else: ?>
					'Fair Value (FCF)'
				<?php endif; ?>
			],
			datasets: [{
				label: 'USD',
				data: [
					<?= $data['price'] ?? 'null' ?>,
					<?= $data['fairValuePE'] ?? 'null' ?>,
					<?= $data['fairValueFCF'] ?? 'null' ?>
				],
				backgroundColor: ['#000000', '#000000', '#000000'],
			}]
		},
		options: {
			responsive: true,
			plugins: {
				title: {
					display: true,
					text: 'Bewertung der Aktie im Vergleich'
				},
				tooltip: {
					callbacks: {
						label: ctx => {
							const value = ctx.raw;
							const label = ctx.label;
							return value ? `${label}: ${value.toFixed(2)} USD` : `${label}: Keine Daten`;
						}
					}
				},
				legend: {
					display: false
				},
				annotation: {
					annotations: {
						priceLine: {
							type: 'line',
							yMin: <?= $data['price'] ?? 'null' ?>,
							yMax: <?= $data['price'] ?? 'null' ?>,
							borderColor: 'red',
							borderWidth: 1
						}
					}
				}
			},
			scales: {
				y: {
					beginAtZero: true
				}
			}
		}
	});
}

if (typeof Chart !== 'undefined') {
	renderValuationChart();
}
</script>