<?php
require_once __DIR__ . '/engine/engine.php';
require_once __DIR__ . '/engine/api-handling/fmp_client.php';
require_once __DIR__ . '/engine/bewertungsmethoden/bewertung_whale-patterns.php';

$requires_search = true;
$requires_chartjs = true;

$symbol  = strtoupper(trim($_GET['symbol'] ?? $_POST['symbol'] ?? ''));

require_once __DIR__ . '/views/header.php';
require_once __DIR__ . '/views/navigation.php';
?>
<main class="flex-grow-1">
	<div class="container pb-5">
		<div class="row">
			<div class="col-12">
				<div class="sticky-top mt-5 bg-white z-3 pb-3">
					<div class="d-flex justify-content-between align-items-center">
						<h1 class="mb-4">Chart Whale Patterns</h1>
						<div>
						<?php
						if ($symbol) {
							$category = 'Whale Patterns';
							include 'execute/watchlist/watchlist_button.php';
						}
						?>
						</div>
					</div>
			
					<form id="fcForm" method="get" class="mb-0">
						<div class="row g-3">
							<div class="col-md-6">
								<label for="symbol" class="form-label">Symbol eingeben</label>
								<input type="text" class="form-control symbol-autocomplete" name="symbol" id="symbol" placeholder="AAPL" value="<?= htmlspecialchars($symbol) ?>" required>
							</div>
							<div class="col-md-6 d-flex align-items-end">
								<button type="submit" class="btn btn-dark w-100" id="runBtn">Prüfen</button>
							</div>
						</div>
					</form>
					<div id="status" class="text-muted mt-2"></div>
				</div>
			</div>
		
			<div class="row mt-3">
				<div class="col-12">
					<?php
					function pct($v, $digits=2){ return is_numeric($v) ? number_format((float)$v, $digits, ',', '.') : '-'; }
					
					if ($symbol):
						$res = patterns_evaluate($symbol);
					
						if (!empty($res['error'])): ?>
							<div class="alert alert-warning">Keine Daten für <strong><?= htmlspecialchars($symbol) ?></strong> gefunden.</div>
						<?php else:
							// --- robuste Defaults aus dem Ergebnis ---
							$name    = (string)($res['name'] ?? '');
							$ex      = (string)($res['exchange'] ?? '');
							$score   = (int)   ($res['score'] ?? 0);
							$signals = (array) ($res['signals'] ?? []);
							$weights = (array) ($res['weights'] ?? (defined('WP_DEFAULT_WEIGHTS') ? WP_DEFAULT_WEIGHTS : []));
					
							// --- Chart-Daten: Close + Volumen ---
							$dailyCloses  = [];
							$dailyDates   = [];
							$dailyVolumes = [];
							$benchCloses  = [];   // für RS
							$pivotPrice = $res['pivot_price'] ?? null;
							
							try {
								$r = fmp_multi([
									'hist' => [
										'key'   => 'historical_price_full',
										'vars'  => ['symbol' => $symbol],
										'query' => ['timeseries' => 180],
									],
									'bench' => [
										'key'   => 'historical_price_full',
										'vars'  => ['symbol' => 'SPY'], // Benchmark, S&P 500 ETF
										'query' => ['timeseries' => 180],
									],
								]);
							
								// Symbol-Daten
								$hist = $r['hist']['historical'] ?? [];
								if ($hist) {
									$hist = array_reverse($hist); // oldest→newest
									foreach ($hist as $bar) {
										if (!isset($bar['date'],$bar['close'])) continue;
										$dailyDates[]   = $bar['date'];
										$dailyCloses[]  = (float)$bar['close'];
										$dailyVolumes[] = isset($bar['volume']) ? (int)$bar['volume'] : null;
									}
								}
							
								// Benchmark-Daten
								$benchHist = $r['bench']['historical'] ?? [];
								if ($benchHist) {
									$benchHist = array_reverse($benchHist);
									// gleiche Länge wie $dailyDates, ggf. per Datum matchen
									$map = [];
									foreach ($benchHist as $bar) {
										$map[$bar['date']] = (float)$bar['close'];
									}
									foreach ($dailyDates as $d) {
										$benchCloses[] = $map[$d] ?? null;
									}
								}
								
								if (isset($s['metrics']['pivot_price'])) {
									$details[] = 'pivot: '.pct($s['metrics']['pivot_price'], 2);
								}

								// Beispiel Pivot: letztes 52-Wochen-Hoch aus den geladenen Kursen
								if ($dailyCloses) {
									$pivotPrice = max($dailyCloses);
								}
							
							} catch (Throwable $e) {
								// noop
							}
					
							// Ampel
							$ampel = [
								'label' => ($score >= 70 ? 'Grün' : ($score >= 40 ? 'Gelb' : 'Rot')),
								'class' => ($score >= 70 ? 'bg-success' : ($score >= 40 ? 'bg-warning' : 'bg-danger')),
							];
					
							// Erklärungen (einmalig)
							$explanations = [
							  'three_weeks_tight'   => '3 Wochen enge Seitwärtsbewegung nach Kursanstieg, Hinweis auf institutionelle Unterstützung.',
							  'flat_base'           => 'Flache Basis über ca. 6 Wochen mit geringer Schwankung, oft als Sprungbrett für Breakouts.',
							  'cup_with_handle'     => 'Typisches Trendfortsetzungsmuster mit Bodenbildung und kleinem Rücksetzer (Handle).',
							  'high_tight_flag'     => 'Sehr starker Kursanstieg (>100%) mit kurzer Konsolidierung, extrem bullisch.',
							  'pocket_pivot'        => 'Up-Day über 10-DMA, Volumen > max Down-Vol (10T) und > Vol-SMA(10).',
							  'accumulation_days'   => 'Up-Day bei höherem Volumen (vs. Vortag & SMA10) – Käufe starker Hände.',
							  'up_down_volume'      => 'Volumen an Up- vs. Down-Tagen; >1,2 zeigt Nachfrage.',
							  'low_volume_pullback' => 'Pullback bei niedrigem Volumen – Verkäufer schwach.',
							  'distribution_days'   => 'Down-Day bei höherem Volumen (vs. Vortag & SMA10); zu viele = Warnsignal.',
							  'relative_strength'   => 'Preis relativ zum Benchmark (z. B. SPY) steigt und liegt über RS-SMA(50).',
							];
							?>
					
							<?php if ($dailyCloses): ?>
								<div class="height-300 mb-4">
									<canvas id="closeChart" height="200"></canvas>
								</div>
							<?php endif; ?>
					
							<div class="card mb-3">
								<div class="card-body">
									<h2 class="h5 mb-2">
										<?= htmlspecialchars($symbol) ?> <?= $name ? '– '.htmlspecialchars($name) : '' ?> <?= $ex ? '<small>('.htmlspecialchars($ex).')</small>' : '' ?>
									</h2>
					
									<div class="mb-2">
										<div class="d-flex justify-content-between align-items-center mt-3 mb-1">
											<strong>Whale Activity</strong>
											<span class="fw-semibold"><?= $score ?>/100</span>
										</div>
										<div class="progress" style="height:10px;">
											<div class="progress-bar <?= $ampel['class'] ?>" role="progressbar"
												 style="width: <?= max(0,min(100,$score)) ?>%"></div>
										</div>
									</div>
					
									<div class="table-responsive mt-4">
										<table class="table table-sm align-middle mb-0">
											<thead>
												<tr>
													<th>Signal</th>
													<th>OK</th>
													<th>Bewertung</th>
													<th>Details</th>
													<th>Erklärung</th>
												</tr>
											</thead>
											<tbody>
											<?php
											$labels = [
												'three_weeks_tight'   => 'Three-Weeks-Tight',
												'flat_base'           => 'Flat Base',
												'cup_with_handle'     => 'Cup-with-Handle',
												'high_tight_flag'     => 'High-Tight Flag',
												'pocket_pivot'        => 'Pocket Pivot',
												'accumulation_days'   => 'Accumulation Days',
												'up_down_volume'      => 'Up/Down-Vol Ratio',
												'low_volume_pullback' => 'Low-Volume Pullback',
												'distribution_days'   => 'Distribution Days',
												'relative_strength'   => 'Relative Strength',
											];
					
											foreach ($labels as $key=>$label):
												$s = $signals[$key] ?? null;
												if (!$s) continue;
											
												$ok     = !empty($s['ok']);
												$weight = (int)($weights[$key] ?? 0);
											
												// ✨ Proportional aus 0..100-Subscore auf das Weight umrechnen
												if (isset($s['score']) && is_numeric($s['score'])) {
													$raw  = max(0, min(100, (int)$s['score']));      // 0..100
													$part = (int)round($raw * $weight / 100);        // 0..$weight
												} else {
													// Fallback falls ein Detector keinen 'score' liefert
													$part = $ok ? $weight : 0;
												}
											
												// Details zusammenstellen
												$details = [];
												if (!empty($s['metrics']) && is_array($s['metrics'])){
													foreach ($s['metrics'] as $mk=>$mv){
														if (is_array($mv)) continue;
														$val = (strpos($mk,'pct')!==false) ? (pct($mv,2).' %') : htmlspecialchars((string)$mv);
														$details[] = htmlspecialchars($mk).': '.$val;
													}
												}
												if (isset($s['ratio']))    $details[] = 'ratio: '.htmlspecialchars((string)$s['ratio']);
												if (isset($s['count']))    $details[] = 'count: '.htmlspecialchars((string)$s['count']);
												if (isset($s['lastDate'])) $details[] = 'last: '.htmlspecialchars((string)$s['lastDate']);
											?>
											<tr>
												<td><?= htmlspecialchars($label) ?></td>
												<td><?= $ok ? '<i class="fa fa-check-circle text-success"></i>' : '—' ?></td>
												<td><?= $part ?><?= $weight ? ' / '.$weight : '' ?></td>
												<td><?= $details ? implode(' · ', $details) : '' ?></td>
												<td class="small"><?= htmlspecialchars($explanations[$key] ?? '') ?></td>
											</tr>
											<?php endforeach; ?>

											</tbody>
										</table>
									</div>
					
								</div>
							</div>
					
							<?php if (!empty($dailyCloses)): ?>
							<script>
							(function(){
							  const ctx = document.getElementById('closeChart');
							  if (!ctx || typeof Chart === 'undefined') return;
							
							  const labels  = <?= json_encode($dailyDates ?? []) ?>;
							  const closes  = <?= json_encode($dailyCloses ?? []) ?>;
							  const volumes = <?= json_encode($dailyVolumes ?? []) ?>;
							
							  // Optional: Benchmark-Closes (kann leer sein)
							  const bench = <?= json_encode($benchCloses ?? []) ?>;
							
							  // Optional: Pivot-Preis (kann null sein)
							  const pivotPrice = <?= json_encode($pivotPrice ?? null) ?>;
							
							  // ---- Helpers ----
							  function sma(arr, len){
								const out = Array(arr.length).fill(null);
								let sum = 0, q = [];
								for (let i=0; i<arr.length; i++){
								  const v = (typeof arr[i]==='number' && !isNaN(arr[i])) ? arr[i] : 0;
								  q.push(v); sum += v;
								  if (q.length > len) sum -= q.shift();
								  if (i >= len-1) out[i] = sum / len;
								}
								return out;
							  }
							
							  // Price-MAs
							  const ma = (arr,n)=>{const o=Array(arr.length).fill(null); let s=0,q=[];
								for(let i=0;i<arr.length;i++){const v=(typeof arr[i]==='number'&& !isNaN(arr[i]))?arr[i]:0;
								  q.push(v); s+=v; if(q.length>n)s-=q.shift(); if(i>=n-1)o[i]=s/n;} return o;};
							  const ma10p = ma(closes,10), ma20p = ma(closes,20), ma50p = ma(closes,50);
							
							  // Volumen-MA
							  const ma10v = sma(volumes, 10);
							  const ma10c = sma(closes, 10);
							
							  // Marker (Pocket Pivot / Accumulation)
							  const pocketPivotPts = [];
							  const accumulationPts = [];
							  const accIdxCandidates = [];
							
							  for (let i = 11; i < labels.length; i++) {
								const upDay = closes[i] > closes[i-1];
								const closeAbove10 = ma10c[i] != null ? (closes[i] > ma10c[i]) : false;
							
								let maxDownVol = 0;
								for (let k = i - 10; k < i; k++) {
								  if (k <= 0) continue;
								  if (typeof volumes[k] !== 'number' || typeof closes[k] !== 'number' || typeof closes[k-1] !== 'number') continue;
								  if (closes[k] < closes[k-1]) maxDownVol = Math.max(maxDownVol, volumes[k] || 0);
								}
								const volOK = (volumes[i] || 0) > Math.max(maxDownVol, (ma10v[i] || 0) * 1.05);
								if (upDay && closeAbove10 && maxDownVol > 0 && volOK) {
								  pocketPivotPts.push({ x: labels[i], y: closes[i] });
								}
							
								const priceUp = closes[i] >= (closes[i-1] * 1.002);
								const volUp   = (volumes[i] || 0) > (volumes[i-1] || 0) && (volumes[i] || 0) > (ma10v[i] || 0);
								if (priceUp && volUp) accIdxCandidates.push(i);
							  }
							  let last = -999;
							  for (const i of accIdxCandidates) {
								if (i - last >= 3) { accumulationPts.push({ x: labels[i], y: closes[i] }); last = i; }
							  }
							
							  // Volumen-Balkenfarben (grün/rot je Tag)
							  const volColors = volumes.map((_, i) => {
								if (i === 0) return 'rgba(108,117,125,0.2)';
								return (closes[i] >= closes[i-1]) ? 'rgba(25,135,84,0.25)' : 'rgba(220,53,69,0.25)';
							  });
							
							  // ---- Datasets Grundgerüst ----
							  const datasets = [
								{ // Close
								  label: 'Close',
								  data: closes,
								  yAxisID: 'y',
								  borderColor: '#000000',
								  backgroundColor: '#000000',
								  borderWidth: 1.5,
								  pointRadius: 0,
								  fill: false,
								  tension: 0.15
								},
								{ // Volumen
								  type: 'bar',
								  label: 'Volumen',
								  data: volumes,
								  yAxisID: 'y1',
								  backgroundColor: volColors,
								  borderWidth: 0,
								  barPercentage: 1.0,
								  categoryPercentage: 1.0
								},
								{ // Volumen SMA(10)
								  label: 'Volumen SMA(10)',
								  data: ma10v,
								  yAxisID: 'y1',
								  borderColor: '#ff0000',
								  backgroundColor: '#ff0000',
								  borderWidth: 1.2,
								  pointRadius: 0,
								  fill: false,
								  tension: 0.2
								},
								{ // Pocket Pivot Marker
								  type: 'scatter',
								  label: 'Pocket Pivot',
								  data: pocketPivotPts,
								  yAxisID: 'y',
								  pointBackgroundColor: '#000000',
								  pointBorderColor: '#000000',
								  pointRadius: 4,
								  pointHoverRadius: 5,
								  showLine: false
								},
								{ // Accumulation Day Marker
								  type: 'scatter',
								  label: 'Accumulation Day',
								  data: accumulationPts,
								  yAxisID: 'y',
								  pointBackgroundColor: '#ff0000',
								  pointBorderColor: '#ff0000',
								  pointStyle: 'rectRot',
								  pointRadius: 4,
								  pointHoverRadius: 5,
								  showLine: false
								}
							  ];
							
							  // Price-MAs hinzufügen
							  datasets.push(
								{label:'MA10', data:ma10p, yAxisID:'y', borderColor:'#6c757d', pointRadius:0, borderWidth:1, fill:false},
								{label:'MA20', data:ma20p, yAxisID:'y', borderColor:'#0d6efd', pointRadius:0, borderWidth:1, fill:false},
								{label:'MA50', data:ma50p, yAxisID:'y', borderColor:'#198754', pointRadius:0, borderWidth:1, fill:false},
							  );
							
							  // RS (optional, nur wenn Bench vorhanden & auswertbar)
							  if (Array.isArray(bench) && bench.length && bench.length === closes.length) {
								const rs = closes.map((c,i)=> (bench[i] && bench[i]!==0) ? c/bench[i] : null);
								const base = rs.find(v=>v!=null) || 1;
								const rsIdx = rs.map(v=> v!=null ? v/base*100 : null);
								datasets.push({label:'Relative Strength (idx)', data:rsIdx, yAxisID:'y1',
											   borderColor:'#fd7e14', pointRadius:0, borderWidth:1, fill:false});
							  }
							
							  // Pivot-Linie (optional)
							  if (typeof pivotPrice === 'number') {
								datasets.push({
								  label:'Pivot',
								  data: closes.map(()=> pivotPrice),
								  yAxisID:'y',
								  borderColor:'#ff0000',
								  borderDash:[4,4],
								  borderWidth: 1,
								  pointRadius:0,
								  fill:false
								});
							  }
							
							  // ---- Chart ----
							  new Chart(ctx, {
								type: 'line',
								data: { labels, datasets },
								options: {
								  plugins: {
									legend: { display: true },
									tooltip: {
									  mode: 'index',
									  intersect: false,
									  callbacks: {
										label: function(ctx){
										  const ds = ctx.dataset;
										  if (ds.type === 'scatter') return `${ds.label}: ${ctx.parsed.y}`;
										  return `${ds.label}: ${ctx.formattedValue}`;
										}
									  }
									}
								  },
								  scales: {
									x: {
									  display: true,
									  ticks: {
										autoSkip: true,
										maxTicksLimit: 12,
										callback: (value) => {
										  const lbl = (labels && labels[value]) ? String(labels[value]) : '';
										  return lbl.substring(0,7); // YYYY-MM
										}
									  },
									  grid: { display: true }
									},
									y:  { display: true, ticks: { callback:(v)=>v } },
									y1: { display: true, position: 'right', grid: { drawOnChartArea: false } }
								  },
								  layout: { padding: { bottom: 8 } },
								  interaction: { mode: 'index', intersect: false },
								  maintainAspectRatio: false
								}
							  });
							})();
							</script>

							<?php endif; ?>
					
						<?php endif; ?>
					<?php endif; ?>

				</div>
			</div>
		</div>
	   </div>
</main>

<?php require_once __DIR__ . '/views/footer.php'; ?>