<?php

function generateCompetitionRuns($conn, $competitionCode) {

	// Überprüfe, ob competitionCode leer ist
	if (empty($competitionCode)) {
		return ["success" => false, "error" => "Parameter 'competitionCode' ist leer."];
	}

	// Fetch competition ID from competitionCode
	$competitionSql = "SELECT id FROM competitions WHERE code = ? LIMIT 1";
	$competitionStmt = $conn->prepare($competitionSql);
	if (!$competitionStmt) {
		return ["success" => false, "error" => "Fehler beim Vorbereiten der Competition-Abfrage: " . $conn->error];
	}

	$competitionStmt->bind_param("s", $competitionCode);
	$competitionStmt->execute();
	$competitionResult = $competitionStmt->get_result();
	$competition = $competitionResult->fetch_assoc();
	$competitionStmt->close();

	if (!$competition) {
		return ["success" => false, "error" => "Kein Wettbewerb mit dem angegebenen Code gefunden."];
	}

	$competitionId = $competition['id'];

	// Fetch all schedule data with heatsystem details for this competition
	$scheduleSql = "
		SELECT 
			s.id AS schedule_id,
			s.comp,
			s.event,
			s.category,
			s.heatsystem AS heatsystem_id,
			h.id AS hs_id,
			h.heatsystem AS hs_heatsystem,
			h.athletes AS hs_athletes,
			h.round AS hs_round,
			h.groups AS hs_groups,
			h.name AS hs_name,
			h.capacity AS hs_capacity,
			h.runs AS hs_runs,
			h.seeding AS hs_seeding,
			h.system AS hs_system,
			h.qualify AS hs_qualify,
			h.termination AS hs_termination,
			h.reversed AS hs_reversed
		FROM schedule s
		LEFT JOIN heatsystem h ON s.heatsystem = h.id
		WHERE s.comp = ?
		ORDER BY s.timestamp ASC
	";

	$scheduleStmt = $conn->prepare($scheduleSql);
	if (!$scheduleStmt) {
		return ["success" => false, "error" => "Fehler beim Vorbereiten der Schedule-Abfrage: " . $conn->error];
	}

	$scheduleStmt->bind_param("i", $competitionId);
	$scheduleStmt->execute();
	$scheduleResult = $scheduleStmt->get_result();

	// Wir speichern die Daten in einer verschachtelten Struktur:
	// data[comp][event][category][round] = array von Zeitplänen (alle mit gleicher Runde)
	$data = [];

	while ($row = $scheduleResult->fetch_assoc()) {
		$comp = $row['comp'];
		$event = $row['event'];
		$category = $row['category'];
		$round = (int)$row['hs_round'];

		if (!isset($data[$comp])) {
			$data[$comp] = [];
		}
		if (!isset($data[$comp][$event])) {
			$data[$comp][$event] = [];
		}
		if (!isset($data[$comp][$event][$category])) {
			$data[$comp][$event][$category] = [];
		}
		if (!isset($data[$comp][$event][$category][$round])) {
			$data[$comp][$event][$category][$round] = [];
		}

		$data[$comp][$event][$category][$round][] = [
			"schedule_id" => $row['schedule_id'],
			"heatsystem_id" => $row['heatsystem_id'],
			"hs_id" => $row['hs_id'],
			"hs_heatsystem" => $row['hs_heatsystem'],
			"hs_athletes" => (int)$row['hs_athletes'],
			"hs_round" => $round,
			"hs_groups" => (int)$row['hs_groups'],
			"hs_name" => $row['hs_name'],
			"hs_capacity" => (int)$row['hs_capacity'],
			"hs_runs" => (int)$row['hs_runs'],
			"hs_seeding" => (int)$row['hs_seeding'],
			"hs_system" => $row['hs_system'],
			"hs_qualify" => (int)$row['hs_qualify'],
			"hs_termination" => (int)$row['hs_termination'],
			"hs_reversed" => (int)$row['hs_reversed']
		];
	}

	$scheduleStmt->close();

	// Jetzt transformiere $data in eine lesbare Struktur und berechne athletes_in_round.
	// Wir wissen, dass die Runden sortiert sind, daher iterieren wir aufsteigend.

	$output = [];

	foreach ($data as $comp => $events) {
		foreach ($events as $event => $categories) {
			foreach ($categories as $category => $rounds) {
				ksort($rounds, SORT_NUMERIC);

				// Extrahiere eine einzelne repräsentative Runde (erste Eintrag)
				$roundInfo = [];
				foreach ($rounds as $r => $schedules) {
					// Angenommen, alle Zeitpläne in dieser Runde haben dieselben hs-Parameter
					$first = $schedules[0]; 
					$roundInfo[$r] = [
						"hs_athletes" => $first['hs_athletes'],
						"hs_qualify" => $first['hs_qualify'],
						"hs_termination" => $first['hs_termination'],
						"hs_groups" => $first['hs_groups']
					];
				}

				// Berechnung der Athleten pro Runde
				$athletesInRound = [];
				$qualifier_pool = []; // Puffer für Qualifikationen aus nicht-terminierenden Runden
				$last_round_terminated = false;
				$roundQualifiers = [];

				// Runde 1 festlegen
				foreach ($roundInfo as $r => $info) {
					$roundQualifiers[$r] = $info['hs_qualify'];
				}

				// Athleten pro Runde berechnen
				foreach ($roundInfo as $r => $info) {
					if ($r === 1) {
						// Runde 1: direkt hs_athletes
						$athletesInRound[$r] = $info['hs_athletes'];
						// keine Qualifikationen zu handhaben, da keine vorherige Runde
						$last_round_terminated = false;
						continue;
					}

					// Für Runden > 1:
					$prevRound = $r - 1;
					$prevTerm = $roundInfo[$prevRound]['hs_termination'];
					$prevQualify = $roundQualifiers[$prevRound];

					if ($prevTerm === 0) {
						// Nicht terminierende vorherige Runde
						// athletes_in_round(r) = athletes_in_round(r-1) - qualify(r-1)
						$athletesInRound[$r] = $athletesInRound[$prevRound] - $prevQualify;
						// Qualifikationen zur Puffer hinzufügen
						$qualifier_pool[] = $prevQualify;
						$last_round_terminated = false;
					} else {
						// Terminierende vorherige Runde
						if (!$last_round_terminated) {
							// Erste terminierende Runde nach einigen nicht terminierenden Runden
							// athletes_in_round(r) = sum(qualifier_pool) + qualify(r-1)
							$sumAll = array_sum($qualifier_pool) + $prevQualify;
							$athletesInRound[$r] = $sumAll;
							// Puffer leeren und neu mit qualifizieren der vorherigen Runde starten
							$qualifier_pool = [$prevQualify];
							$last_round_terminated = true;
						} else {
							// Aufeinanderfolgende terminierende Runde
							// athletes_in_round(r) = qualify(r-1)
							$athletesInRound[$r] = $prevQualify;
							// Puffer auf [qualify(r-1)] zurücksetzen
							$qualifier_pool = [$prevQualify];
							$last_round_terminated = true;
						}
					}
				}

				// Jetzt berechnen wir die Gruppen und Läufe für jede Runde
				$roundList = [];
				foreach ($rounds as $r => $schedules) {
					$roundSchedules = [];
					foreach ($schedules as $sch) {
						$athletes_in_round = $athletesInRound[$r];
						$capacity = $sch['hs_capacity'];
						$previous_round_termination = 0;
						$qualify_previous_round = 0;

						if ($r > 1) {
							$prevRound = $r - 1;
							if (isset($roundInfo[$prevRound]['hs_termination'])) {
								$previous_round_termination = $roundInfo[$prevRound]['hs_termination'];
							}
							if (isset($roundInfo[$prevRound]['hs_qualify'])) {
								$qualify_previous_round = $roundInfo[$prevRound]['hs_qualify'];
							}
						}

						// Gruppen generieren basierend auf dem Heatsystem
						if ($sch['hs_system'] == "snake") {
							$groups = generateSnakeSystemStartList(
								$athletes_in_round,
								$capacity,
								$sch['hs_groups'],
								$sch['hs_round'],
								$previous_round_termination,
								$sch['hs_athletes'],
								$qualify_previous_round
							);
						} elseif ($sch['hs_system'] == "step-ladder") {
							$groups = generateStepLadderStartList(
								$conn,
								$sch['schedule_id']
							);
						} elseif ($sch['hs_system'] == "ladder") {
						$groups = generateLadderStartList(
							$conn,
							$sch['schedule_id']
						);
						} else {
							// Andere Heatsysteme können hier behandelt werden
							$groups = [];
						}

						$roundSchedules[] = [
							"schedule_id" => $sch['schedule_id'],
							"heatsystem_id" => $sch['heatsystem_id'],
							"heatsystem_details" => [
								"id" => $sch['hs_id'],
								"heatsystem" => $sch['hs_heatsystem'],
								"athletes" => $sch['hs_athletes'],
								"round" => $sch['hs_round'],
								"groups" => $sch['hs_groups'],
								"name" => $sch['hs_name'],
								"capacity" => $sch['hs_capacity'],
								"runs" => $sch['hs_runs'],
								"seeding" => $sch['hs_seeding'],
								"system" => $sch['hs_system'],
								"qualify" => $sch['hs_qualify'],
								"termination" => $sch['hs_termination'],
								"reversed" => $sch['hs_reversed'],
								"athletes_in_round" => $athletes_in_round,
								"groups" => $groups // Neue Gruppen basierend auf Kapazität
							]
						];
					}

					$roundList[] = [
						"round" => $r,
						"schedules" => $roundSchedules
					];
				}

				$output[] = [
					"comp" => $comp,
					"event" => $event,
					"category" => $category,
					"rounds" => $roundList
				];
			}
		}
	}

	// Gebe die Ausgabe zurück
	return [
		"success" => true,
		"competitionCode" => $competitionCode,
		"data" => $output
	];
}

?>