/**
 * Parse onboarding media manifests into guide groups.
 *
 * WHY: keeping manifest shaping outside the view makes guide behavior
 * testable without mounting the whole onboarding page.
 *
 * @param {string[]} files - Manifest file paths relative to the onboarding media root.
 * @returns {object} Guide groups keyed by service, step, and variant.
 */
export function parseManifest(files) {
  const grouped = {};
  for (const path of files) {
    if (typeof path !== "string") continue;
    const cleaned = path.replace(/^\/+/, "").replace(/\\/g, "/");
    const parts = cleaned.split("/");
    if (parts.length < 3) continue;
    const service = parts[0];
    const step = parts[1];
    const rest = parts.slice(2);
    let variant = "default";
    let filename = rest.join("/");
    if (rest.length > 1) {
      variant = rest[0];
      filename = rest.slice(1).join("/");
    }
    const order = guideOrder(filename);
    const label = guideLabel(filename);
    const url = `/media/onboarding/${cleaned}`;
    grouped[service] = grouped[service] || {};
    grouped[service][step] = grouped[service][step] || {};
    grouped[service][step][variant] = grouped[service][step][variant] || { id: variant, title: variant === "default" ? "" : variant, shots: [] };
    grouped[service][step][variant].shots.push({ url, order, label, file: filename });
  }

  Object.values(grouped).forEach((serviceSteps) => {
    Object.values(serviceSteps).forEach((variants) => {
      Object.values(variants).forEach((group) => {
        group.shots.sort((a, b) => (a.order - b.order) || a.file.localeCompare(b.file));
      });
    });
  });

  return grouped;
}

function guideOrder(filename) {
  const prefix = filename.match(/^(\d{1,3})/);
  if (prefix) return Number(prefix[1]);
  const step = filename.match(/step[-_ ]?(\d{1,3})/i);
  if (step) return Number(step[1]);
  return Number.MAX_SAFE_INTEGER;
}

function guideLabel(filename) {
  const base = filename.replace(/\.(png|jpe?g|webp)$/i, "");
  return base.replace(/^\d+[-_]?/, "").replace(/[-_]/g, " ").trim();
}
