document.addEventListener("DOMContentLoaded", function () {
	
  // Merge or fallback for editing config
  const config = {
	allowEditingSchedule: false,
	publicSchedule: false, // <--- Default
  };
  if (window.config) {
	// If your global config object sets these, override
	if (window.config.allowEditingSchedule === true) {
	  config.allowEditingSchedule = true;
	}
	if (window.config.publicSchedule === true) {
	  config.publicSchedule = true;
	}
  }

  /*******************************************************
   * 1) Inject basic CSS for table & icons,
   *    plus new rules for single-line text on mobile
   *******************************************************/
  const style = document.createElement("style");
  style.textContent = `
	.mobile-optimized-card {
	  margin-bottom: 1rem;
	}
	@media (max-width: 576px) {
	  .mobile-optimized-card h3 {
		font-size: 1.25rem;
	  }
	  .mobile-optimized-card .btn-link {
		padding: 0.5rem;
	  }
	}
	/* Keep table cells on a single line and allow horizontal scroll if needed */
	.table-responsive {
	  overflow-x: auto;
	  -webkit-overflow-scrolling: touch; /* for smooth scrolling on iOS */
	}
	.table thead th,
	.table tbody td {
	  white-space: nowrap;        /* Single line */
	  overflow: hidden;
	  text-overflow: ellipsis;    /* if text is too long, show "..." */
	  max-width: 150px;           /* adjust as needed */
	}
	/* On very small screens, reduce the padding & font-size further if you like */
	@media (max-width: 576px) {
	  .table thead th,
	  .table tbody td {
		font-size: 0.8rem;
		padding: 0.3rem;
	  }
	}

	/* Over-the-row highlight for "active" run */
	.highlight-row {
	  background-color: #f1f1f1;
	}
	.bib-number {
	  font-size: 0.8em;
	  color: #666;
	  margin-left: 4px;
	}

	/* Icons for reordering or editing, only shown if editing is enabled */
	.move-up-btn i, .move-down-btn i {
	  font-size: 1.2rem;
	}
	.edit-datetime-icon,
	.delete-datetime-icon {
	  cursor: pointer;
	  font-size: 1.2rem;
	  margin: 0 0.3rem;
	  line-height: 1.2;
	}
	.delete-datetime-icon {
	  color: red;
	}

	/* Badge samples */
	.badge {
	  display: inline-block;
	  padding: 0.25em 0.4em;
	  font-size: 75%;
	  font-weight: 700;
	  line-height: 1;
	  text-align: center;
	  white-space: nowrap;
	  vertical-align: middle;
	  border-radius: 0.375rem;
	}
	.bg-primary {
	  background-color: #0d6efd !important;
	  color: #fff !important;
	}
	.bg-danger {
	  background-color: #dc3545 !important;
	  color: #fff !important;
	}
	.me-2 {
	  margin-right: 0.5rem !important;
	}

	/* A "completed" card styling.  */
	.competition-complete-card {
	  border: 1px solid #d4edda;
	  border-radius: 6px;
	  padding: 1rem;
	  background-color: #d4edda; /* light greenish */
	  color: #155724;           /* dark greenish text */
	  margin-bottom: 2rem;
	}
	.competition-complete-card h3 {
	  margin-top: 0;
	}
	.competition-complete-card p {
	  margin: 0.75rem 0;
	}
  `;
  document.head.appendChild(style);

  /*******************************************************
   * 2) Retrieve competition code from localStorage or URL
   *******************************************************/
  let storedCompetition = JSON.parse(localStorage.getItem("activeCompetition"));
  if (!storedCompetition || !storedCompetition.code) {
	console.warn("No active competition found in localStorage. Checking URL...");

	const urlParams = new URLSearchParams(window.location.search);
	const competitionCodeFromUrl = urlParams.get("CompetitionCode");
	if (competitionCodeFromUrl) {
	  storedCompetition = { code: competitionCodeFromUrl };
	  console.log("Using competitionCode from URL:", competitionCodeFromUrl);
	} else {
	  console.error("No competition code found in local storage or GET parameter.");
	  return;
	}
  }
  const competitionCode = storedCompetition.code;

  /*******************************************************
   * 2B) Retrieve Bearer token from localStorage (if any)
   *******************************************************/
  let bearerToken = null;
  const localUserData = localStorage.getItem("user");
  if (localUserData) {
	try {
	  const parsedUser = JSON.parse(localUserData);
	  if (parsedUser?.bearer) {
		bearerToken = parsedUser.bearer;
	  }
	} catch (e) {
	  console.warn("Could not parse local user data:", e);
	}
  }

  /*******************************************************
   * 2C) If API fails => remove user & go to index
   *******************************************************/
  function handleNotOkResponse(response) {
	console.error(`API responded with status ${response.status}: ${response.statusText}`);
	localStorage.removeItem("user");
	window.location.href = "index.html";
  }
  function checkServerError(data) {
	if (!data) return;
	const errMsg = String(data.error || "").toLowerCase();
	if (errMsg.includes("token") || errMsg.includes("expired")) {
	  localStorage.removeItem("user");
	  window.location.href = "index.html";
	}
  }

  /*******************************************************
   * 2D) Check if competition is complete (all runs != 0)
   *******************************************************/
  async function checkCompetitionComplete() {
	try {
	  const headers = {
		"Content-Type": "application/json",
		"Authorization": bearerToken
		  ? `Bearer ${bearerToken}`
		  : "Bearer 50afb255cfa3a36834e0a51185b1eb09",
	  };

	  const resp = await fetch(
		`${API_BASE_URL}?api=results&competitionCode=${encodeURIComponent(
		  competitionCode
		)}&public=false`,
		{ method: "GET", headers }
	  );
	  if (!resp.ok) {
		throw new Error(`HTTP error ${resp.status}`);
	  }
	  const data = await resp.json();
	  if (!data || !data.data || !data.data.runs) {
		console.warn("No runs array found. Assuming not complete.");
		return false;
	  }

	  // If data.data.runs is an array, use directly; if grouped, flatten them as needed
	  const allRuns = data.data.runs; 
	  // e.g. const allRuns = data.data.runs.flatMap(grp => grp.runs);

	  // If ANY run has status=0 => not complete
	  const anyRunInProgress = allRuns.some((ath) =>
		ath.runs && ath.runs.some((r) => r.status === 0)
	  );
	  return !anyRunInProgress; // true if competition is fully complete
	} catch (err) {
	  console.error("Error in checkCompetitionComplete:", err);
	  return false; // fallback => show schedule if we can't confirm
	}
  }

  /*******************************************************
   * 3) Global variable to store previously rendered data
   *******************************************************/
  let previousScheduleData = null;

  /*******************************************************
   * 4) Fetch the schedule data (and auto-update)
   *******************************************************/
  fetchScheduleData(competitionCode);

  // Poll every 2s for demonstration; adjust for production
  setInterval(() => {
	fetchScheduleData(competitionCode);
  }, 2000);

  async function fetchScheduleData(code) {
	try {
	  const response = await fetch(
		`${API_BASE_URL}?api=schedule&competitionCode=${encodeURIComponent(code)}&scores=true`,
		{
		  method: "GET",
		  headers: {
			"Content-Type": "application/json",
			"Authorization": bearerToken
			  ? `Bearer ${bearerToken}`
			  : "Bearer 50afb255cfa3a36834e0a51185b1eb09",
		  },
		}
	  );
	  if (!response.ok) {
		handleNotOkResponse(response);
		return null;
	  }

	  const data = await response.json();
	  if (!data) return;
	  checkServerError(data);

	  if (!data.data || !Array.isArray(data.data)) {
		console.error("Unexpected schedule API response:", data);
		return;
	  }

	  // If publicSchedule = true, check if competition is complete
	  if (config.publicSchedule) {
		const isComplete = await checkCompetitionComplete();
		if (isComplete) {
		  renderCompletedMessage();
		  return; // No schedule rendering
		}
	  }

	  // If not complete or publicSchedule = false => proceed
	  checkAndRenderSchedule(data.data);
	} catch (error) {
	  console.error("Error fetching schedule data:", error);
	}
  }

  /*******************************************************
   * 4B) RENDER the "Competition Completed" message
   *******************************************************/
  function renderCompletedMessage() {
	const container = document.querySelector("#container-schedule");
	if (!container) return;

	// Overwrite the container with a "completed" card
	container.innerHTML = `
	  <div class="competition-complete-card">
		<h3>Competition Completed</h3>
		<p><strong>Thank you</strong> to all the athletes, sponsors, and supporters who made this event a success!</p>
		<p>We hope to see you next time.</p>
	  </div>
	`;
  }

  function checkAndRenderSchedule(newData) {
	if (!previousScheduleData || !isSameSchedule(previousScheduleData, newData)) {
	  previousScheduleData = newData;
	  renderSchedule(newData);
	} else {
	}
  }

  function isSameSchedule(oldData, newData) {
	return JSON.stringify(oldData) === JSON.stringify(newData);
  }

  /*******************************************************
   * 5) RENDER the schedule
   *******************************************************/
  function renderSchedule(scheduleArray) {
	const contentContainer = document.querySelector("#container-schedule");
	if (!contentContainer) {
	  console.error("Content container element not found!");
	  return;
	}

	// Clear existing content
	contentContainer.innerHTML = "";

	// Group schedules by day
	const groupedByDay = groupByDay(scheduleArray);

	let htmlString = "";
	let dayIndex = 0;

	Object.keys(groupedByDay).forEach((day) => {
	  htmlString += `
		<div class="card mb-3 mobile-optimized-card">
		  <div class="card-header d-flex justify-content-between align-items-center">
			<h3 class="card-title mb-0">${day}</h3>
		  </div>
		  <div class="card-body">
			${generateDayContent(groupedByDay[day], dayIndex)}
		  </div>
		</div>
	  `;
	  dayIndex++;
	});

	contentContainer.innerHTML = htmlString;
  }

  /*******************************************************
   * 6) Group schedules by day
   *******************************************************/
  function groupByDay(scheduleData) {
	return scheduleData.reduce((days, scheduleItem) => {
	  let day;
	  if (scheduleItem.time_planned) {
		day = new Date(scheduleItem.time_planned * 1000).toLocaleDateString();
	  } else {
		day = "No Planned Date";
	  }
	  if (!days[day]) {
		days[day] = [];
	  }
	  days[day].push(scheduleItem);
	  return days;
	}, {});
  }

  /*******************************************************
   * 7) Generate the content for a single day
   *******************************************************/
  function generateDayContent(daySchedules, dayIndex) {
	// Sort by "order"
	daySchedules.sort((a, b) => (a.order || 0) - (b.order || 0));

	return daySchedules
	  .map((scheduleItem, idx, arr) => {
		const {
		  heatsystem_name,
		  runs,
		  time_planned,
		  category_name,
		  round_name,
		  order,
		  schedule_id,
		  event_name,
		} = scheduleItem;

		const plannedTimeFormatted = formatTime(time_planned);
		const disableUp = idx === 0 ? "" : "";
		const disableDown = idx === arr.length - 1 ? "" : "";

		let eventBadge = "";
		if (event_name === "Wakeboard") {
		  eventBadge = `<span class="badge bg-primary me-2">WB</span>`;
		} else if (event_name === "Wakeskate") {
		  eventBadge = `<span class="badge bg-danger me-2">WS</span>`;
		} else if (event_name === "Wakeboard Seated") {
		  eventBadge = `<span class="badge bg-warning me-2">ST</span>`;
		}

		let iconsHTML = "";
		if (config.allowEditingSchedule) {
		  iconsHTML = `
			<button 
			  class="btn btn-link p-1 move-up-btn"
			  ${disableUp}
			  data-schedule-id="${schedule_id}"
			  data-current-order="${order}"
			  title="Move up"
			>
			  <i class="bi bi-arrow-up"></i>
			</button>
			<button
			  class="btn btn-link p-1 move-down-btn"
			  ${disableDown}
			  data-schedule-id="${schedule_id}"
			  data-current-order="${order}"
			  title="Move down"
			>
			  <i class="bi bi-arrow-down"></i>
			</button>
			<i
			  class="bi bi-pencil-square edit-datetime-icon p-1"
			  data-schedule-id="${schedule_id}"
			  data-initial-time="${time_planned || ""}"
			  title="Edit planned time"
			></i>
			<i
			  class="bi bi-trash delete-datetime-icon p-1"
			  style="color: red;"
			  data-schedule-id="${schedule_id}"
			  title="Delete planned time"
			></i>
		  `;
		}

		return `
		  <div class="mb-4">
			<h4 class="fw-bold d-flex justify-content-between align-items-center flex-wrap">
			  <div>
				<span>${plannedTimeFormatted}</span>
				${eventBadge}${category_name || "Unknown Category"} ${heatsystem_name || "Unknown Round"}
			  </div>
			  <div class="d-flex align-items-center">
				${iconsHTML}
			  </div>
			</h4>
			${generateGroupCollapsibles(runs, dayIndex, idx, category_name, heatsystem_name)}
		  </div>
		`;
	  })
	  .join("");
  }

  /*******************************************************
   * 8) Generate collapsibles for groups
   *******************************************************/
  function generateGroupCollapsibles(runs, dayIndex, scheduleIndex, categoryName, roundName) {
	if (!Array.isArray(runs)) return "<p>No runs available</p>";
	const groupedRuns = groupBy(runs, "group");

	return Object.keys(groupedRuns)
	  .map((group) => {
		const groupRuns = groupedRuns[group];
		const hasActiveRun = groupRuns.some((run) => run.active === 1);

		const groupCollapseId = `collapseDay${dayIndex}_Sched${scheduleIndex}_Group${group}`;
		const groupPlannedTime = formatTime(groupRuns[0]?.calculated_planned_time);

		return `
		  <div class="card mb-1">
			<div class="card-header mb-1" id="headingDay${dayIndex}_Sched${scheduleIndex}_Group${group}">
			  <h5 class="mb-0">
				<button
				  class="btn btn-link text-dark text-decoration-none toggle-collapse-btn"
				  type="button"
				  data-target="#${groupCollapseId}"
				  aria-expanded="${hasActiveRun}"
				>
				  ${groupPlannedTime || "N/A"} - 
				  ${categoryName || "Unknown Category"} 
				  ${roundName || "Unknown Round"} Group ${group}
				</button>
			  </h5>
			</div>
			<div 
			  id="${groupCollapseId}" 
			  class="collapse ${hasActiveRun ? "show" : ""}" 
			  aria-labelledby="headingDay${dayIndex}_Sched${scheduleIndex}_Group${group}"
			>
			  <div class="card-body p-0">
				<div class="table-responsive">
				  <table class="table table-hover table-sm mb-0">
					<thead>
					  <tr>
						<th class="fw-bold">Time</th>
						<th class="fw-bold">Live</th>
						<th class="fw-bold">Run</th>
						<th class="fw-bold text-start">Country</th>
						<th class="fw-bold text-start">Athlete</th>
						<th class="fw-bold">Score</th>
					  </tr>
					</thead>
					<tbody>
					  ${generateRunsTable(groupRuns)}
					</tbody>
				  </table>
				</div>
			  </div>
			</div>
		  </div>
		`;
	  })
	  .join("");
  }

  /*******************************************************
   * 9) Generate runs table
   *******************************************************/
  function generateRunsTable(runsArray) {
	if (!Array.isArray(runsArray)) return "";

	return runsArray
	  .map((run) => {
		const highlightClass = run.active === 1 ? "highlight-row" : "";
		const bibNumber = run.bib ? `<span class="bib-number">(${run.bib})</span>` : "";

		let displayedScore = getStatusText(run.status);
		if (run.status === 1 && typeof run.average_score === "number") {
		  displayedScore = run.average_score.toFixed(2);
		}
		if (run.status === 0 && run.real_time) {
		  displayedScore = "Riding athlete";
		}

		let liveVal = formatTime(run.real_time);
		if (run.delay !== 0 && !run.real_time) {
		  const adjustedTimestamp = (run.calculated_planned_time || 0) + run.delay;
		  liveVal = formatTime(adjustedTimestamp);
		}
		if (liveVal === "N/A") liveVal = "";

		return `
		  <tr class="${highlightClass}">
			<td>${formatTime(run.calculated_planned_time)}</td>
			<td>${liveVal}</td>
			<td>${run.run || "N/A"}</td>
			<td class="text-start">${run.country || "N/A"}</td>
			<td class="text-start">${run.athlete_name || "N/A"} ${bibNumber}</td>
			<td>${displayedScore}</td>
		  </tr>
		`;
	  })
	  .join("");
  }

  function getStatusText(status) {
	switch (status) {
	  case 0: return "Pending";
	  case 1: return "Completed";
	  case 2: return "FRS";
	  case 3: return "DNS";
	  case 4: return "DSQ";
	  default: return "Unknown";
	}
  }

  function formatTime(timestamp) {
	if (!timestamp) return "N/A";
	const dateObj = new Date(timestamp * 1000);
	return dateObj.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
  }

  function groupBy(array, key) {
	return array.reduce((result, currentValue) => {
	  const groupValue = currentValue[key];
	  if (!result[groupValue]) {
		result[groupValue] = [];
	  }
	  result[groupValue].push(currentValue);
	  return result;
	}, {});
  }

  /*******************************************************
   * 10) Single Global Event Listener (instead of multiple)
   *******************************************************/
  document.addEventListener("click", function (e) {
	// 10A) Expand/collapse group
	const toggleBtn = e.target.closest(".toggle-collapse-btn");
	if (toggleBtn) {
	  const targetId = toggleBtn.getAttribute("data-target");
	  const targetElement = document.querySelector(targetId);
	  if (targetElement) {
		const isOpen = targetElement.classList.contains("show");
		if (isOpen) {
		  targetElement.classList.remove("show");
		  toggleBtn.setAttribute("aria-expanded", "false");
		} else {
		  targetElement.classList.add("show");
		  toggleBtn.setAttribute("aria-expanded", "true");
		}
	  }
	  return; // End here so we don't process editing code for the same click
	}

	// 10B) If editing is disabled => return
	if (!config.allowEditingSchedule) {
	  return;
	}

	// 10C) Move up
	if (e.target.closest(".move-up-btn")) {
	  const btn = e.target.closest(".move-up-btn");
	  const scheduleId = btn.getAttribute("data-schedule-id");
	  const currentOrder = parseInt(btn.getAttribute("data-current-order"), 10);
	  changeScheduleOrder(scheduleId, currentOrder, currentOrder - 1);
	}
	// 10D) Move down
	else if (e.target.closest(".move-down-btn")) {
	  const btn = e.target.closest(".move-down-btn");
	  const scheduleId = btn.getAttribute("data-schedule-id");
	  const currentOrder = parseInt(btn.getAttribute("data-current-order"), 10);
	  changeScheduleOrder(scheduleId, currentOrder, currentOrder + 1);
	}
	// 10E) Edit date/time
	else if (e.target.classList.contains("edit-datetime-icon")) {
	  const icon = e.target;
	  const scheduleId = icon.getAttribute("data-schedule-id");
	  const initialTime = icon.getAttribute("data-initial-time");
	  handleEditDateTime(scheduleId, initialTime);
	}
	// 10F) Delete date/time
	else if (e.target.classList.contains("delete-datetime-icon")) {
	  const icon = e.target;
	  const scheduleId = icon.getAttribute("data-schedule-id");
	  deleteTimePlanned(scheduleId);
	}
  });

  /*******************************************************
   * 12) Reorder API
   *******************************************************/
  function changeScheduleOrder(scheduleId, oldOrder, newOrder) {
	if (!scheduleId || newOrder < 0) {
	  console.error("Invalid schedule ID or newOrder < 0");
	  return;
	}
	const payload = {
	  schedule_id: scheduleId,
	  new_order: newOrder
	};
	fetch(`${API_BASE_URL}?api=updateScheduleOrder`, {
	  method: "POST",
	  headers: {
		"Content-Type": "application/json",
		...(bearerToken ? { Authorization: `Bearer ${bearerToken}` } : {})
	  },
	  body: JSON.stringify(payload),
	})
	  .then((res) => res.json())
	  .then((data) => {
		checkServerError(data);
		if (!data.success) {
		  console.error("Reorder failed:", data.error);
		  alert(`Reorder failed: ${data.error || "Unknown error"}`);
		  return;
		}
		fetchScheduleData(competitionCode);
	  })
	  .catch((err) => console.error("Error reordering schedule:", err));
  }

  /*******************************************************
   * 13) handleEditDateTime => user picks new date/time
   *******************************************************/
  function handleEditDateTime(scheduleId, initialTime) {
	const initialTimestamp = parseInt(initialTime, 10);
	const initialDate = initialTimestamp ? new Date(initialTimestamp * 1000) : new Date();
	const defaultDate = initialDate.toISOString().split("T")[0]; // "YYYY-MM-DD"
	const dateInput = prompt("Enter date (YYYY-MM-DD):", defaultDate);
	if (!dateInput) return;

	const defaultTime = initialDate.toTimeString().split(" ")[0].slice(0, 5); // "HH:MM"
	const timeInput = prompt("Enter time (HH:MM):", defaultTime);
	if (!timeInput) return;

	const [hours, minutes] = timeInput.split(":").map(Number);
	const updatedDate = new Date(dateInput);
	updatedDate.setHours(hours, minutes);

	updateTimePlanned(scheduleId, Math.floor(updatedDate.getTime() / 1000));
  }

  /*******************************************************
   * 14) Update planned time => calls updateSchedule
   *******************************************************/
  function updateTimePlanned(scheduleId, newTimestamp) {
	fetch(`${API_BASE_URL}?api=updateSchedule`, {
	  method: "POST",
	  headers: {
		"Content-Type": "application/json",
		...(bearerToken ? { Authorization: `Bearer ${bearerToken}` } : {})
	  },
	  body: JSON.stringify({
		schedule_id: scheduleId,
		time_planned: newTimestamp
	  }),
	})
	  .then((res) => res.json())
	  .then((data) => {
		checkServerError(data);
		if (!data.success) {
		  console.error("Update timePlanned failed:", data.error);
		  alert(`Update timePlanned failed: ${data.error || "Unknown error"}`);
		  return;
		}
		fetchScheduleData(competitionCode);
	  })
	  .catch((err) => console.error("Error updating timePlanned:", err));
  }

  /*******************************************************
   * 15) Delete planned time => calls updateSchedule
   *******************************************************/
  function deleteTimePlanned(scheduleId) {
	if (!confirm("Are you sure you want to delete the planned time?")) return;

	fetch(`${API_BASE_URL}?api=updateSchedule`, {
	  method: "POST",
	  headers: {
		"Content-Type": "application/json",
		...(bearerToken ? { Authorization: `Bearer ${bearerToken}` } : {})
	  },
	  body: JSON.stringify({
		schedule_id: scheduleId,
		time_planned: null
	  }),
	})
	  .then((res) => res.json())
	  .then((data) => {
		checkServerError(data);
		if (!data.success) {
		  console.error("Delete timePlanned failed:", data.error);
		  alert(`Delete timePlanned failed: ${data.error || "Unknown error"}`);
		  return;
		}
		fetchScheduleData(competitionCode);
	  })
	  .catch((err) => console.error("Error deleting timePlanned:", err));
  }
});