(function (root, factory) {
  const renderer = factory();
  if (typeof module === "object" && module.exports) {
    module.exports = renderer;
  } else {
    root.MealSnapshotFallbackRenderer = renderer;
  }
}(typeof globalThis !== "undefined" ? globalThis : this, function () {
  "use strict";

  const NUTRITION_FIELDS = Object.freeze([
    Object.freeze({ field: "calories", label: "Optional estimated calories", unit: "kcal" }),
    Object.freeze({ field: "protein", label: "Optional protein", unit: "g" }),
    Object.freeze({ field: "carbs", label: "Optional carbs", unit: "g" }),
    Object.freeze({ field: "fat", label: "Optional fat", unit: "g" })
  ]);

  function element(documentRef, tagName, className, text) {
    const node = documentRef.createElement(tagName);
    if (className) node.className = className;
    if (text !== undefined && text !== null) node.textContent = String(text);
    return node;
  }

  function field(documentRef, options) {
    const wrapper = element(documentRef, "label", options.className || "meal-snapshot-fallback-field");
    wrapper.append(element(documentRef, "span", "meal-snapshot-review-label", options.label));
    const control = element(documentRef, options.multiline ? "textarea" : "input", "meal-snapshot-review-input");
    if (!options.multiline) control.type = options.type || "text";
    control.value = String(options.value ?? "");
    control.setAttribute("autocomplete", "off");
    control.setAttribute("data-fallback-field", options.name);
    if (options.inputMode) control.setAttribute("inputmode", options.inputMode);
    if (options.maxLength) control.setAttribute("maxlength", options.maxLength);
    if (options.type === "number") {
      control.setAttribute("min", "0");
      control.setAttribute("max", "10000");
    }
    if (typeof options.onInput === "function") {
      control.addEventListener("input", () => options.onInput(control.value));
    }
    wrapper.append(control);
    return wrapper;
  }

  function action(documentRef, actionName, label, callback) {
    const button = element(documentRef, "button", "meal-snapshot-review-action", label);
    button.type = "button";
    button.setAttribute("data-fallback-action", actionName);
    if (typeof callback === "function") button.addEventListener("click", callback);
    return button;
  }

  function shell(container, options, title, intro) {
    if (!container || typeof container.replaceChildren !== "function") {
      throw new TypeError("Meal Snapshot fallback requires a target DOM element.");
    }
    const documentRef = options.documentRef || container.ownerDocument;
    if (!documentRef || typeof documentRef.createElement !== "function") {
      throw new TypeError("Meal Snapshot fallback requires a document interface.");
    }
    const section = element(documentRef, "section", "meal-snapshot-beta-fallback-form");
    section.setAttribute("role", "region");
    section.setAttribute("aria-labelledby", "mealSnapshotFallbackTitle");
    section.append(
      element(documentRef, "p", "meal-snapshot-beta-eyebrow", "Meal Snapshot Beta"),
      element(documentRef, "h1", "meal-snapshot-beta-title", title),
      element(documentRef, "p", "meal-snapshot-review-context", intro),
      element(documentRef, "p", "meal-snapshot-fallback-local-note", "This stays on this screen only in the current beta."),
      element(documentRef, "p", "meal-snapshot-fallback-save-note", "Saving is not available in this beta phase.")
    );
    section.children[1].setAttribute("id", "mealSnapshotFallbackTitle");
    return { documentRef, section };
  }

  function appendActions(documentRef, section, options) {
    const actions = element(documentRef, "div", "meal-snapshot-review-actions");
    actions.setAttribute("role", "group");
    actions.setAttribute("aria-label", "Local fallback options");
    actions.append(
      action(documentRef, "reset", "Clear draft", options.onReset),
      action(documentRef, "back", "Back", options.onBack)
    );
    section.append(actions);
  }

  function renderManualEntry(container, draft = {}, options = {}) {
    const { documentRef, section } = shell(
      container,
      options,
      "Manual meal entry",
      "Use this when the photo flow is unavailable or you prefer to type it yourself. Keep it simple and review before saving."
    );
    section.append(
      field(documentRef, {
        label: "Meal title or short description",
        name: "title",
        value: draft.title,
        maxLength: 100,
        onInput: (value) => options.onEdit?.({ field: "title", value })
      }),
      field(documentRef, {
        label: "Optional ingredients or portion notes",
        name: "notes",
        value: draft.notes,
        multiline: true,
        maxLength: 1000,
        onInput: (value) => options.onEdit?.({ field: "notes", value })
      })
    );

    const nutritionHeading = element(documentRef, "h2", "meal-snapshot-review-section-title", "Optional starting-point estimate");
    const nutrition = element(documentRef, "div", "meal-snapshot-review-macros");
    for (const item of NUTRITION_FIELDS) {
      nutrition.append(field(documentRef, {
        label: `${item.label} (${item.unit})`,
        name: item.field,
        value: draft.nutrition?.[item.field] ?? "",
        type: "number",
        inputMode: "decimal",
        className: "meal-snapshot-review-macro",
        onInput: (value) => options.onEdit?.({ field: item.field, value })
      }));
    }
    section.append(nutritionHeading, nutrition);
    appendActions(documentRef, section, options);
    container.replaceChildren(section);
    return section;
  }

  function renderNoteOnly(container, draft = {}, options = {}) {
    const { documentRef, section } = shell(
      container,
      options,
      "Note-only fallback",
      "Add a short draft note when you do not want a nutrition estimate. Review it before saving in a future beta phase."
    );
    section.append(field(documentRef, {
      label: "Meal note",
      name: "note",
      value: draft.note,
      multiline: true,
      maxLength: 1000,
      onInput: (value) => options.onEdit?.({ field: "note", value })
    }));
    appendActions(documentRef, section, options);
    container.replaceChildren(section);
    return section;
  }

  return Object.freeze({ renderManualEntry, renderNoteOnly });
}));
