// quiz-helpers.jsx
// Shared choice-navigation helpers used by every quiz-* level.
// Babel transpiles `function` declarations here to globals so each
// later `<script type="text/babel">` can call them by name.

const quizHelperFoundation = window.SpaceExplorerFoundation || {};
const quizSafeArray = quizHelperFoundation.safeArray || ((value) =>
  Array.isArray(value) ? value : []);

function clampChoiceIndex(index, length) {
  const count = Math.max(0, Number.isFinite(length) ? Math.floor(length) : 0);
  if (!count) return 0;
  const safeIndex = Number.isFinite(index) ? index : 0;
  return Math.max(0, Math.min(count - 1, Math.floor(safeIndex)));
}

function nextChoiceIndex(index, delta, length) {
  return clampChoiceIndex(index + delta, length);
}

function resolveChoiceItems(ids, resolveItem) {
  if (typeof resolveItem !== "function") return [];
  const seen = new Set();
  return quizSafeArray(ids)
    .map(resolveItem)
    .filter((item) => {
      if (!item) return false;
      const key = String(item.id || item.label || JSON.stringify(item)).trim();
      if (!key) return false;
      if (seen.has(key)) return false;
      seen.add(key);
      return true;
    });
}

function clearChoiceFeedbackTimer(timerRef) {
  if (!timerRef || !timerRef.current) return;
  window.clearTimeout(timerRef.current);
  timerRef.current = null;
}

function normalizeChoiceList(choices) {
  return quizSafeArray(choices);
}

function choiceLabelFor(choice, getLabel) {
  let label = choice?.label || choice?.name || choice?.id;
  if (typeof getLabel === "function") {
    try {
      label = getLabel(choice);
    } catch {
      label = choice?.label || choice?.name || choice?.id;
    }
  }
  return String(label || "choice").trim() || "choice";
}

function choiceButtonLabel(choice, index, choices, getLabel, action = "Choose") {
  const items = normalizeChoiceList(choices);
  const safeIndex = clampChoiceIndex(index, items.length);
  const label = choiceLabelFor(choice || items[safeIndex], getLabel);
  const count = items.length;
  return count
    ? `${action} ${label}, ${safeIndex + 1} of ${count}`
    : `${action} ${label}`;
}

function choiceStatusText(index, choices, getLabel) {
  const items = normalizeChoiceList(choices);
  const safeIndex = clampChoiceIndex(index, items.length);
  const choice = items[safeIndex];
  if (!choice) return "";
  return `${safeIndex + 1} of ${items.length}: ${choiceLabelFor(choice, getLabel)}`;
}

function choiceSelectionState(index, choices, getLabel) {
  const items = normalizeChoiceList(choices);
  const safeIndex = clampChoiceIndex(index, items.length);
  const choice = items[safeIndex] || null;
  return {
    index: safeIndex,
    choice,
    statusText: choiceStatusText(safeIndex, items, getLabel),
  };
}

function handleChoiceNavigationKey(event, config) {
  const {
    choices,
    selectedChoice,
    disabled = false,
    onMove,
    onSelectIndex,
    onChoose,
  } = config || {};
  const length = normalizeChoiceList(choices).length;
  if (!event || disabled || !length) return false;
  if (event.key === "ArrowLeft" || event.key === "ArrowUp") {
    event.preventDefault();
    if (typeof onMove === "function") onMove(-1);
    return true;
  }
  if (event.key === "ArrowRight" || event.key === "ArrowDown") {
    event.preventDefault();
    if (typeof onMove === "function") onMove(1);
    return true;
  }
  if (event.key === "Home" || event.key === "End") {
    event.preventDefault();
    if (typeof onSelectIndex === "function") {
      onSelectIndex(event.key === "Home" ? 0 : length - 1);
    }
    return true;
  }
  if (event.key === " " || event.key === "Enter") {
    event.preventDefault();
    if (typeof onChoose === "function") {
      onChoose(selectedChoice && selectedChoice.choice);
    }
    return true;
  }
  return false;
}
