const documentTypeSelect = document.getElementById("documentTypeSelect");
const documentDescription = document.getElementById("documentDescription");
const fieldsContainer = document.getElementById("fieldsContainer");
const docForm = document.getElementById("docForm");
const statusBox = document.getElementById("status");
const clearFormButton = document.getElementById("clearFormButton");
const presetFileInput = document.getElementById("presetFileInput");
const dataFileInput = document.getElementById("dataFileInput");
const downloadDataButton = document.getElementById("downloadDataButton");
const downloadJsonButton = document.getElementById("downloadJsonButton");
const defaultDocumentOptions = document.getElementById("defaultDocumentOptions");
const uploadedJsonOptions = document.getElementById("uploadedJsonOptions");
const legacyTemplateSelect = document.getElementById("legacyTemplateSelect");
const legacyTemplateRow = document.getElementById("legacyTemplateRow");
const documentPickerToggle = document.getElementById("documentPickerToggle");
const documentPickerMenu = document.getElementById("documentPickerMenu");
const selectedDocumentLabel = document.getElementById("selectedDocumentLabel");

let currentDocumentType = null;
let currentFields = [];
let defaultDocumentTypes = [];
let activePickerKind = "default";
let activePickerId = "";
let selectedTemplateId = "";

function setStatus(message) {
  statusBox.innerHTML = message || "";
}

function setActivePicker(kind, id, label = "") {
  activePickerKind = kind;
  activePickerId = id;

  document.querySelectorAll(".picker-item").forEach(item => {
    item.classList.toggle(
      "active",
      item.dataset.kind === kind && item.dataset.id === id
    );
  });

  if (label) {
    selectedDocumentLabel.textContent = label;
  }
}

function normalizeField(field, index, inheritedSection = "General Fields") {
  return {
    name: field.name || `field${index + 1}`,
    label: field.label || field.name || `Field ${index + 1}`,
    type: field.type || "text",
    required: Boolean(field.required),
    section: field.section || inheritedSection,
    value: field.value ?? "",
    options: field.options || []
  };
}

function createInput(field) {
  let input;

  if (field.type === "textarea") {
    input = document.createElement("textarea");
  } else if (field.type === "select") {
    input = document.createElement("select");
    for (const option of field.options || []) {
      const opt = document.createElement("option");
      opt.value = option.value ?? option;
      opt.textContent = option.label ?? option;
      input.appendChild(opt);
    }
  } else {
    input = document.createElement("input");
    input.type = "text";

    if (field.type === "autocomplete" && field.list) {
      input.setAttribute("list", `datalist-${field.list}`);
    } else {
      input.type = field.type || "text";
    }
  }

  input.id = field.name;
  input.name = field.name;
  input.required = field.required;
  input.value = field.value ?? "";
  return input;
}

function makeFormGroup(field) {
  const group = document.createElement("div");
  group.className = "form-group";

  const label = document.createElement("label");
  label.setAttribute("for", field.name);
  label.textContent = field.label;

  group.appendChild(label);
  group.appendChild(createInput(field));
  return group;
}

function appendFieldRows(parent, fields) {
  for (let i = 0; i < fields.length; i += 3) {
    const row = document.createElement("div");
    row.className = "form-row";

    for (const field of fields.slice(i, i + 3)) {
      row.appendChild(makeFormGroup(field));
    }

    parent.appendChild(row);
  }
}

function renderSection(section, level = 2) {
  const sectionWrapper = document.createElement("div");
  sectionWrapper.className = "json-section";

  const collapsible = section.collapsible !== false;
  const defaultOpen = Boolean(section.defaultOpen);

  let contentParent = sectionWrapper;

  if (collapsible) {
    const details = document.createElement("details");
    details.open = defaultOpen;

    const summary = document.createElement("summary");
    summary.textContent = section.heading || "Section";
    details.appendChild(summary);

    sectionWrapper.appendChild(details);
    contentParent = details;
  } else {
    const heading = document.createElement(`h${Math.min(level, 4)}`);
    heading.textContent = section.heading || "Section";
    sectionWrapper.appendChild(heading);
  }

  const normalizedFields = (section.fields || []).map((field, index) =>
    normalizeField(field, currentFields.length + index, section.heading || "General Fields")
  );

  currentFields.push(...normalizedFields);
  appendFieldRows(contentParent, normalizedFields);

  for (const subsection of section.subsections || []) {
    contentParent.appendChild(renderSection(subsection, level + 1));
  }

  return sectionWrapper;
}

function renderFlatFields(fields) {
  const bySection = {};
  const normalizedFields = fields.map((field, index) => normalizeField(field, index));

  for (const field of normalizedFields) {
    const section = field.section || "General Fields";
    if (!bySection[section]) bySection[section] = [];
    bySection[section].push(field);
  }

  currentFields = [];

  for (const [sectionName, sectionFields] of Object.entries(bySection)) {
    fieldsContainer.appendChild(renderSection({
      heading: sectionName,
      collapsible: sectionName !== "General Fields",
      defaultOpen: sectionName === "General Fields",
      fields: sectionFields
    }));
  }
}


function renderDatalists(documentType) {
  document.querySelectorAll("datalist[data-generated-list='true']").forEach(el => el.remove());

  const lists = documentType.lists || {};
  for (const [listName, values] of Object.entries(lists)) {
    const datalist = document.createElement("datalist");
    datalist.id = `datalist-${listName}`;
    datalist.dataset.generatedList = "true";

    for (const value of values || []) {
      const option = document.createElement("option");
      option.value = value;
      datalist.appendChild(option);
    }

    document.body.appendChild(datalist);
  }
}

function renderTemplateSelector(documentType) {
  if (!legacyTemplateSelect || !legacyTemplateRow) return;

  const templates = documentType.templates || [];

  legacyTemplateSelect.innerHTML = "";

  if (!templates.length) {
    legacyTemplateRow.style.display = "none";
    selectedTemplateId = "";
    return;
  }

  legacyTemplateRow.style.display = "block";

  for (const template of templates) {
    const option = document.createElement("option");
    option.value = template.id;
    option.textContent = template.label || template.id;
    legacyTemplateSelect.appendChild(option);
  }

  const savedTemplate = localStorage.getItem(`utilityAppSelectedTemplate:${documentType.id}`);
  selectedTemplateId = savedTemplate && templates.some(t => t.id === savedTemplate)
    ? savedTemplate
    : (documentType.defaultTemplateId || templates[0].id);

  legacyTemplateSelect.value = selectedTemplateId;
}

function getSelectedTemplateId() {
  if (!legacyTemplateSelect || legacyTemplateRow?.style.display === "none") {
    return "";
  }
  return legacyTemplateSelect.value || selectedTemplateId || "";
}


function renderDocumentType(documentType) {
  fieldsContainer.innerHTML = "";
  currentFields = [];
  renderDatalists(documentType);
  renderTemplateSelector(documentType);

  if (Array.isArray(documentType.sections)) {
    for (const section of documentType.sections) {
      fieldsContainer.appendChild(renderSection(section));
    }
    return;
  }

  renderFlatFields(documentType.fields || []);
}

function applyDataToForm(data) {
  for (const field of currentFields) {
    const el = document.getElementById(field.name);
    if (el && data[field.name] !== undefined) {
      el.value = data[field.name];
    }
  }
}

function loadPresetObject(preset) {
  if (preset.documentTypeId || preset.document_type_id) {
    documentTypeSelect.value = preset.documentTypeId || preset.document_type_id;
  }

  if (preset.sections) {
    currentDocumentType = {
      ...currentDocumentType,
      ...preset,
      id: currentDocumentType?.id || preset.documentTypeId || preset.document_type_id || "uploaded_json"
    };
    documentDescription.textContent = currentDocumentType.description || "";
    renderDocumentType(currentDocumentType);
    return;
  }

  if (Array.isArray(preset.fields)) {
    currentDocumentType = {
      ...currentDocumentType,
      ...preset,
      id: currentDocumentType?.id || preset.documentTypeId || preset.document_type_id || "uploaded_json",
      sections: [
        {
          heading: preset.heading || preset.name || "Imported Fields",
          collapsible: false,
          defaultOpen: true,
          fields: preset.fields
        }
      ]
    };
    documentDescription.textContent = currentDocumentType.description || "";
    renderDocumentType(currentDocumentType);
    return;
  }

  if (preset.data && typeof preset.data === "object") {
    applyDataToForm(preset.data);
    return;
  }

  if (typeof preset === "object") {
    currentDocumentType = {
      ...currentDocumentType,
      id: currentDocumentType?.id || "uploaded_json",
      name: "Uploaded JSON",
      sections: [
        {
          heading: "Imported Fields",
          collapsible: false,
          defaultOpen: true,
          fields: Object.entries(preset).map(([key, value]) => ({
            name: key,
            label: key,
            type: typeof value === "string" && value.length > 80 ? "textarea" : "text",
            value
          }))
        }
      ]
    };
    renderDocumentType(currentDocumentType);
  }
}

async function loadDocumentTypes() {
  const response = await fetch("/api/doc-generator/document-types");
  const json = await response.json();

  defaultDocumentTypes = json.document_types || [];
  renderDefaultDocumentOptions();
  await loadUploadedJsonOptions();

  const savedSelectionRaw = localStorage.getItem("utilityAppSelectedDocument");
  let savedSelection = null;

  try {
    savedSelection = savedSelectionRaw ? JSON.parse(savedSelectionRaw) : null;
  } catch {
    savedSelection = null;
  }

  if (savedSelection?.kind === "uploaded" && savedSelection.id) {
    await loadUploadedJson(savedSelection.id);
    return;
  }

  if (savedSelection?.kind === "default" && savedSelection.id) {
    await loadDefaultDocumentType(savedSelection.id);
    return;
  }

  if (defaultDocumentTypes.length > 0) {
    await loadDefaultDocumentType(defaultDocumentTypes[0].id);
  }
}

function renderDefaultDocumentOptions() {
  defaultDocumentOptions.innerHTML = "";

  for (const documentType of defaultDocumentTypes) {
    const item = document.createElement("button");
    item.type = "button";
    item.className = "picker-item";
    item.dataset.kind = "default";
    item.dataset.id = documentType.id;
    item.textContent = documentType.name;

    item.addEventListener("click", async () => {
      await loadDefaultDocumentType(documentType.id);
    });

    defaultDocumentOptions.appendChild(item);
  }
}

async function loadDefaultDocumentType(documentTypeId) {
  const response = await fetch(`/api/doc-generator/document-types/${documentTypeId}`);
  currentDocumentType = await response.json();

  documentTypeSelect.value = documentTypeId;
  documentDescription.textContent = currentDocumentType.description || "";
  renderDocumentType(currentDocumentType);
  setActivePicker("default", documentTypeId, currentDocumentType.name || documentTypeId);
  closeDocumentPicker();

  localStorage.setItem("utilityAppSelectedDocument", JSON.stringify({
    kind: "default",
    id: documentTypeId,
    label: currentDocumentType.name || documentTypeId
  }));

  restoreSavedFormData();
}

async function loadUploadedJsonOptions() {
  const response = await fetch("/api/doc-generator/uploaded-json");
  const json = await response.json();

  uploadedJsonOptions.innerHTML = "";

  if (!json.files || json.files.length === 0) {
    const empty = document.createElement("div");
    empty.className = "picker-empty";
    empty.textContent = "No uploaded JSON files yet.";
    uploadedJsonOptions.appendChild(empty);
    return;
  }

  for (const file of json.files) {
    const row = document.createElement("div");
    row.className = "uploaded-json-row";

    const loadButton = document.createElement("button");
    loadButton.type = "button";
    loadButton.className = "picker-item uploaded-json-load";
    loadButton.dataset.kind = "uploaded";
    loadButton.dataset.id = file.filename;
    loadButton.textContent = file.filename;

    loadButton.addEventListener("click", async () => {
      await loadUploadedJson(file.filename);
    });

    const deleteButton = document.createElement("button");
    deleteButton.type = "button";
    deleteButton.className = "delete-json-button";
    deleteButton.textContent = "x";
    deleteButton.title = `Delete ${file.filename}`;

    deleteButton.addEventListener("click", async event => {
      event.stopPropagation();

      if (!confirm(`Delete uploaded JSON file?\n\n${file.filename}`)) {
        return;
      }

      const response = await fetch(`/api/doc-generator/uploaded-json/${encodeURIComponent(file.filename)}`, {
        method: "DELETE"
      });

      const result = await response.json();

      if (!response.ok) {
        setStatus(`Could not delete JSON: ${result.detail || "Delete failed."}`);
        return;
      }

      setStatus(`Deleted uploaded JSON: ${result.deleted}`);
      await loadUploadedJsonOptions();

      if (activePickerKind === "uploaded" && activePickerId === file.filename) {
        if (defaultDocumentTypes.length > 0) {
          await loadDefaultDocumentType(defaultDocumentTypes[0].id);
        }
      }
    });

    row.appendChild(loadButton);
    row.appendChild(deleteButton);
    uploadedJsonOptions.appendChild(row);
  }
}

async function loadUploadedJson(filename) {
  const response = await fetch(`/api/doc-generator/uploaded-json/${encodeURIComponent(filename)}`);
  const result = await response.json();

  if (!response.ok) {
    setStatus(`Could not load JSON: ${result.detail || "Load failed."}`);
    return;
  }

  loadPresetObject(result.json);
  setActivePicker("uploaded", filename, filename);
  closeDocumentPicker();

  localStorage.setItem("utilityAppSelectedDocument", JSON.stringify({
    kind: "uploaded",
    id: filename,
    label: filename
  }));

  restoreSavedFormData();
  setStatus(`Loaded uploaded JSON: ${filename}`);
}

function getFormData(useFieldNameForBlanks = true) {
  const data = {};
  for (const field of currentFields) {
    const el = document.getElementById(field.name);
    const value = el ? el.value.trim() : "";
    data[field.name] = useFieldNameForBlanks ? (value || field.name) : value;
  }
  return data;
}

function csvEscape(value) {
  const text = String(value ?? "");
  if (/[",\n\r]/.test(text)) {
    return `"${text.replaceAll('"', '""')}"`;
  }
  return text;
}

function downloadCurrentDataCsv() {
  const headers = currentFields.map(field => field.name);
  const data = getFormData(false);

  const csv = [
    headers.map(csvEscape).join(","),
    headers.map(header => csvEscape(data[header] ?? "")).join(",")
  ].join("\n");

  const blob = new Blob([csv], {type: "text/csv;charset=utf-8"});
  const url = URL.createObjectURL(blob);

  const a = document.createElement("a");
  a.href = url;
  a.download = `${currentDocumentType?.id || "document"}_data.csv`;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);

  URL.revokeObjectURL(url);
}

function cloneWithCurrentValues(value) {
  const byName = {};
  for (const field of currentFields) {
    const el = document.getElementById(field.name);
    byName[field.name] = el ? el.value : "";
  }

  const clone = JSON.parse(JSON.stringify(value));

  function patchSection(section) {
    for (const field of section.fields || []) {
      if (field.name && byName[field.name] !== undefined) {
        field.value = byName[field.name];
      }
    }

    for (const subsection of section.subsections || []) {
      patchSection(subsection);
    }
  }

  if (Array.isArray(clone.sections)) {
    for (const section of clone.sections) {
      patchSection(section);
    }
  } else if (Array.isArray(clone.fields)) {
    for (const field of clone.fields) {
      if (field.name && byName[field.name] !== undefined) {
        field.value = byName[field.name];
      }
    }
  }

  return clone;
}

function downloadCurrentJson() {
  if (!currentDocumentType) {
    setStatus("No document type selected.");
    return;
  }

  const exportJson = cloneWithCurrentValues({
    ...currentDocumentType,
    exportedAt: new Date().toISOString()
  });

  const text = JSON.stringify(exportJson, null, 2);
  const blob = new Blob([text], {type: "application/json;charset=utf-8"});
  const url = URL.createObjectURL(blob);

  const a = document.createElement("a");
  a.href = url;
  a.download = `${currentDocumentType.id || "document"}_preset.json`;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);

  URL.revokeObjectURL(url);
}

clearFormButton.addEventListener("click", () => {
  for (const field of currentFields) {
    const el = document.getElementById(field.name);
    if (el) el.value = "";
  }

  localStorage.removeItem(getFormStorageKey());
  setStatus("Cleared form data.");
});

presetFileInput.addEventListener("change", async event => {
  const file = event.target.files[0];
  if (!file) return;

  try {
    const formData = new FormData();
    formData.append("file", file);

    const response = await fetch("/api/doc-generator/upload-json", {
      method: "POST",
      body: formData
    });

    const result = await response.json();

    if (!response.ok) {
      throw new Error(result.detail || "JSON upload failed.");
    }

    await loadUploadedJsonOptions();
    loadPresetObject(result.json);
    setActivePicker("uploaded", result.filename, result.filename);
    closeDocumentPicker();
    setStatus(`Uploaded JSON: ${result.filename}<br>Saved to: ${result.saved_path}`);
  } catch (error) {
    setStatus(`Could not upload JSON: ${error.message}`);
  } finally {
    presetFileInput.value = "";
  }
});

dataFileInput.addEventListener("change", async event => {
  const file = event.target.files[0];
  if (!file) return;

  try {
    const formData = new FormData();
    formData.append("file", file);

    const response = await fetch("/api/doc-generator/upload-data", {
      method: "POST",
      body: formData
    });

    const result = await response.json();

    if (!response.ok) {
      throw new Error(result.detail || "CSV upload failed.");
    }

    applyDataToForm(result.data);
    setStatus(`Uploaded data CSV: ${result.filename}<br>Saved to: ${result.saved_path}<br>Rows found: ${result.row_count}`);
  } catch (error) {
    setStatus(`Could not upload CSV: ${error.message}`);
  } finally {
    dataFileInput.value = "";
  }
});

downloadDataButton.addEventListener("click", () => {
  downloadCurrentDataCsv();
});

downloadJsonButton.addEventListener("click", () => {
  downloadCurrentJson();
});

docForm.addEventListener("submit", async event => {
  event.preventDefault();

  setStatus("Generating DOCX...");

  const response = await fetch("/api/doc-generator/generate", {
    method: "POST",
    headers: {"Content-Type": "application/json"},
    body: JSON.stringify({
      document_type_id: currentDocumentType.id,
      template_id: getSelectedTemplateId(),
      data: getFormData(true)
    })
  });

  const json = await response.json();

  if (!response.ok) {
    setStatus(`Error: ${json.detail || "Generation failed."}`);
    return;
  }

  setStatus(`<a href="${json.download_url}">Download ${json.filename}</a>`);
});

loadDocumentTypes().catch(error => {
  setStatus(`Startup error: ${error.message}`);
});


function openDocumentPicker() {
  documentPickerMenu.classList.add("open");
  documentPickerToggle.classList.add("open");
}

function closeDocumentPicker() {
  documentPickerMenu.classList.remove("open");
  documentPickerToggle.classList.remove("open");
}

function toggleDocumentPicker() {
  if (documentPickerMenu.classList.contains("open")) {
    closeDocumentPicker();
  } else {
    openDocumentPicker();
  }
}

documentPickerToggle.addEventListener("click", event => {
  event.stopPropagation();
  toggleDocumentPicker();
});

document.addEventListener("click", event => {
  if (!event.target.closest(".dropdown-picker")) {
    closeDocumentPicker();
  }
});

function showView(viewId) {
  document.querySelectorAll(".app-view").forEach(view => {
    view.classList.toggle("active", view.id === viewId);
  });

  document.querySelectorAll(".nav-button").forEach(button => {
    button.classList.toggle("active", button.dataset.view === viewId);
  });

  localStorage.setItem("utilityAppActiveView", viewId);
}

document.querySelectorAll(".nav-button").forEach(button => {
  button.addEventListener("click", () => {
    showView(button.dataset.view);
  });
});

const mainPageContent = document.getElementById("mainPageContent");
const saveMainPageButton = document.getElementById("saveMainPageButton");
const resetMainPageButton = document.getElementById("resetMainPageButton");

function loadMainPageContent() {
  const saved = localStorage.getItem("utilityAppMainPageContent");
  if (saved) {
    mainPageContent.innerHTML = saved;
  }
}

saveMainPageButton.addEventListener("click", () => {
  localStorage.setItem("utilityAppMainPageContent", mainPageContent.innerHTML);
  setStatus("Saved main page text in this browser.");
});

resetMainPageButton.addEventListener("click", () => {
  localStorage.removeItem("utilityAppMainPageContent");
  mainPageContent.innerHTML = `
    <p>Select a tool above. This main page text is editable in the browser for quick notes, instructions, or workflow reminders.</p>
    <p><strong>Current tools:</strong> Document Generator and Document Processor.</p>
  `;
  setStatus("Reset main page text.");
});

loadMainPageContent();


function getFormStorageKey() {
  const selectedRaw = localStorage.getItem("utilityAppSelectedDocument");
  let selected = null;

  try {
    selected = selectedRaw ? JSON.parse(selectedRaw) : null;
  } catch {
    selected = null;
  }

  const kind = selected?.kind || activePickerKind || "default";
  const id = selected?.id || activePickerId || currentDocumentType?.id || "unknown";
  return `utilityAppFormData:${kind}:${id}`;
}

function saveCurrentFormData() {
  if (!currentFields || currentFields.length === 0) return;

  const data = getFormData(false);
  localStorage.setItem(getFormStorageKey(), JSON.stringify(data));
}

function restoreSavedFormData() {
  const saved = localStorage.getItem(getFormStorageKey());
  if (!saved) return;

  try {
    const data = JSON.parse(saved);
    applyDataToForm(data);
  } catch {
    return;
  }
}

fieldsContainer.addEventListener("input", () => {
  saveCurrentFormData();
});

fieldsContainer.addEventListener("change", () => {
  saveCurrentFormData();
});

window.addEventListener("beforeunload", () => {
  saveCurrentFormData();
});

const savedActiveView = localStorage.getItem("utilityAppActiveView");
if (savedActiveView) {
  showView(savedActiveView);
}



requestAnimationFrame(() => {
  document.body.classList.remove("app-loading");
});


if (legacyTemplateSelect) {
  legacyTemplateSelect.addEventListener("change", () => {
    selectedTemplateId = legacyTemplateSelect.value;
    if (currentDocumentType?.id) {
      localStorage.setItem(`utilityAppSelectedTemplate:${currentDocumentType.id}`, selectedTemplateId);
    }
    saveCurrentFormData();
  });
}

function removeDynamicFields(groupId) {
  document.querySelectorAll(`[data-dynamic-group="${groupId}"]`).forEach(el => el.remove());
  currentFields = currentFields.filter(field => field.dynamicGroup !== groupId);
}

function renderDynamicFieldGroup(group) {
  if (!currentDocumentType) return;

  const countEl = document.getElementById(group.countField);
  if (!countEl) return;

  const count = Math.min(
    parseInt(countEl.value || "0", 10) || 0,
    group.maxCount || 100
  );

  removeDynamicFields(group.id);

  if (count <= 0) return;

  const wrapper = document.createElement("div");
  wrapper.dataset.dynamicGroup = group.id;
  wrapper.className = "json-section dynamic-field-group";

  const details = document.createElement("details");
  details.open = group.defaultOpen !== false;

  const summary = document.createElement("summary");
  summary.textContent = `${group.section || "Dynamic Fields"} (${count})`;
  details.appendChild(summary);

  const generatedFields = [];

  for (let n = 1; n <= count; n++) {
    for (const fieldDef of group.fields || []) {
      generatedFields.push({
        name: fieldDef.namePattern.replaceAll("{n}", String(n)),
        label: fieldDef.labelPattern.replaceAll("{n}", String(n)),
        type: fieldDef.type || "text",
        list: fieldDef.list,
        required: Boolean(fieldDef.required),
        dynamicGroup: group.id
      });
    }
  }

  currentFields.push(...generatedFields);
  appendFieldRows(details, generatedFields);

  wrapper.appendChild(details);

  const countField = document.getElementById(group.countField);
  const sectionWrapper = countField?.closest(".json-section");

  if (sectionWrapper) {
    sectionWrapper.appendChild(wrapper);
  } else {
    fieldsContainer.appendChild(wrapper);
  }

  restoreSavedFormData();
}

function renderAllDynamicFieldGroups() {
  if (!currentDocumentType?.dynamicFieldGroups) return;

  for (const group of currentDocumentType.dynamicFieldGroups) {
    renderDynamicFieldGroup(group);

    const countEl = document.getElementById(group.countField);
    if (countEl && !countEl.dataset.dynamicListenerAttached) {
      countEl.dataset.dynamicListenerAttached = "true";

      countEl.addEventListener("input", () => {
        saveCurrentFormData();
        renderDynamicFieldGroup(group);
      });

      countEl.addEventListener("change", () => {
        saveCurrentFormData();
        renderDynamicFieldGroup(group);
      });
    }
  }
}

const originalRenderDocumentTypeForDynamicGroups = renderDocumentType;
renderDocumentType = function(documentType) {
  originalRenderDocumentTypeForDynamicGroups(documentType);
  renderAllDynamicFieldGroups();
  loadExcelMaps();
};

const templateFileInput = document.getElementById("templateFileInput");

async function fetchUploadedTemplatesForCurrentProfile() {
  if (!currentDocumentType?.id) return [];

  try {
    const response = await fetch(`/api/doc-generator/uploaded-templates/${encodeURIComponent(currentDocumentType.id)}`);
    const json = await response.json();

    if (!response.ok) {
      return [];
    }

    return json.templates || [];
  } catch {
    return [];
  }
}

const originalRenderTemplateSelectorWithUploads = renderTemplateSelector;
renderTemplateSelector = function(documentType) {
  if (!legacyTemplateSelect || !legacyTemplateRow) return;

  const libraryTemplates = documentType.templates || [];

  legacyTemplateSelect.innerHTML = "";

  if (!libraryTemplates.length && !documentType.id) {
    legacyTemplateRow.style.display = "none";
    selectedTemplateId = "";
    return;
  }

  legacyTemplateRow.style.display = "block";

  if (libraryTemplates.length) {
    const libraryGroup = document.createElement("optgroup");
    libraryGroup.label = "Library Templates";

    for (const template of libraryTemplates) {
      const option = document.createElement("option");
      option.value = template.id;
      option.textContent = template.label || template.id;
      libraryGroup.appendChild(option);
    }

    legacyTemplateSelect.appendChild(libraryGroup);
  }

  const uploadedGroup = document.createElement("optgroup");
  uploadedGroup.label = "Uploaded Templates";
  uploadedGroup.id = "uploadedTemplateOptGroup";
  legacyTemplateSelect.appendChild(uploadedGroup);

  const savedTemplate = localStorage.getItem(`utilityAppSelectedTemplate:${documentType.id}`);
  selectedTemplateId = savedTemplate || documentType.defaultTemplateId || libraryTemplates[0]?.id || "";

  if (selectedTemplateId) {
    legacyTemplateSelect.value = selectedTemplateId;
  }

  refreshUploadedTemplateOptions();
};

async function refreshUploadedTemplateOptions() {
  if (!legacyTemplateSelect || !currentDocumentType?.id) return;

  let uploadedGroup = document.getElementById("uploadedTemplateOptGroup");

  if (!uploadedGroup) {
    uploadedGroup = document.createElement("optgroup");
    uploadedGroup.label = "Uploaded Templates";
    uploadedGroup.id = "uploadedTemplateOptGroup";
    legacyTemplateSelect.appendChild(uploadedGroup);
  }

  uploadedGroup.innerHTML = "";

  const uploadedTemplates = await fetchUploadedTemplatesForCurrentProfile();

  for (const template of uploadedTemplates) {
    const option = document.createElement("option");
    option.value = template.id;
    option.textContent = template.label || template.filename;
    uploadedGroup.appendChild(option);
  }

  const savedTemplate = localStorage.getItem(`utilityAppSelectedTemplate:${currentDocumentType.id}`);
  if (savedTemplate && [...legacyTemplateSelect.options].some(option => option.value === savedTemplate)) {
    legacyTemplateSelect.value = savedTemplate;
    selectedTemplateId = savedTemplate;
  }
}

if (templateFileInput) {
  templateFileInput.addEventListener("change", async event => {
    const file = event.target.files[0];
    if (!file) return;

    if (!currentDocumentType?.id) {
      setStatus("Select a profile before uploading a template.");
      templateFileInput.value = "";
      return;
    }

    try {
      const formData = new FormData();
      formData.append("file", file);

      const response = await fetch(`/api/doc-generator/upload-template/${encodeURIComponent(currentDocumentType.id)}`, {
        method: "POST",
        body: formData
      });

      const result = await response.json();

      if (!response.ok) {
        throw new Error(result.detail || "Template upload failed.");
      }

      await refreshUploadedTemplateOptions();

      legacyTemplateSelect.value = result.template_id;
      selectedTemplateId = result.template_id;
      localStorage.setItem(`utilityAppSelectedTemplate:${currentDocumentType.id}`, selectedTemplateId);

      setStatus(`Uploaded template: ${result.filename}<br>Saved to: ${result.saved_path}`);
    } catch (error) {
      setStatus(`Could not upload template: ${error.message}`);
    } finally {
      templateFileInput.value = "";
    }
  });
}

const excelMapSelect = document.getElementById("excelMapSelect");
const exportExcelButton = document.getElementById("exportExcelButton");
const excelImportInput = document.getElementById("excelImportInput");

async function loadExcelMaps() {
  if (!excelMapSelect) return;

  try {
    if (!currentDocumentType?.id) return;
    const response = await fetch(`/api/doc-generator/excel-maps/${encodeURIComponent(currentDocumentType.id)}`);
    const json = await response.json();

    if (!response.ok) {
      throw new Error(json.detail || "Could not load Excel maps.");
    }

    excelMapSelect.innerHTML = "";

    for (const item of json.maps || []) {
      const option = document.createElement("option");
      option.value = item.id;
      option.textContent = `${item.label || item.id} (${item.field_count} fields)`;
      excelMapSelect.appendChild(option);
    }

    const saved = localStorage.getItem("utilityAppExcelMapId");
    if (saved && [...excelMapSelect.options].some(option => option.value === saved)) {
      excelMapSelect.value = saved;
    }
  } catch (error) {
    setStatus(`Could not load Excel maps: ${error.message}`);
  }
}

if (excelMapSelect) {
  excelMapSelect.addEventListener("change", () => {
    localStorage.setItem("utilityAppExcelMapId", excelMapSelect.value);
  });
}

if (exportExcelButton) {
  exportExcelButton.addEventListener("click", async () => {
    if (!currentDocumentType?.id) {
      setStatus("Select a profile before exporting Excel.");
      return;
    }

    try {
      saveCurrentFormData();

      const response = await fetch("/api/doc-generator/export-excel", {
        method: "POST",
        headers: {"Content-Type": "application/json"},
        body: JSON.stringify({
          document_type_id: currentDocumentType.id,
          map_id: excelMapSelect?.value || "field_to_cell_map",
          data: getFormData(true)
        })
      });

      const result = await response.json();

      if (!response.ok) {
        throw new Error(result.detail || "Excel export failed.");
      }

      const link = document.createElement("a");
      link.href = result.download_url;
      link.download = result.filename;
      document.body.appendChild(link);
      link.click();
      link.remove();

      setStatus(`Exported Excel: ${result.filename}`);
    } catch (error) {
      setStatus(`Could not export Excel: ${error.message}`);
    }
  });
}

if (excelImportInput) {
  excelImportInput.addEventListener("change", () => {
    setStatus("Excel import is not wired yet. Export is ready.");
    excelImportInput.value = "";
  });
}

loadExcelMaps();

/* Excel template download button */
const downloadExcelTemplateButton = document.getElementById("downloadExcelTemplateButton");

if (downloadExcelTemplateButton) {
  downloadExcelTemplateButton.addEventListener("click", () => {
    if (!currentDocumentType?.id || !excelMapSelect?.value) {
      setStatus("Select a profile and Excel template/map first.");
      return;
    }

    window.location.href = `/api/doc-generator/excel-template-by-map/${encodeURIComponent(currentDocumentType.id)}/${encodeURIComponent(excelMapSelect.value)}`;
  });
}


/* final legal profile UI normalization */

function normalizeLegalUi() {
  const profileSelect = document.getElementById("documentTypeSelect");
  const excelSelect = document.getElementById("excelMapSelect");
  const templateSelect = document.getElementById("legacyTemplateSelect");

  for (const select of [profileSelect, excelSelect, templateSelect]) {
    if (select) {
      select.classList.add("same-dropdown-style");
    }
  }

  if (profileSelect) {
    for (const option of [...profileSelect.options]) {
      if (option.value === "legal_profile" || option.textContent.trim() === "Legal Profile") {
        option.textContent = "Legal";
      }
    }
  }

  const longText = "Consumer debt defense legal profile based on the legacy app form fields. Additional template fields are calculated at generation time.";
  for (const el of [...document.querySelectorAll("p, div, span")]) {
    const value = el.textContent.trim();
    if (value === longText || value === "Consumer Debt Defense Legal Profile") {
      el.textContent = "Consumer Debt Defense Legal Profile";
      el.classList.add("legal-profile-caption");
    }
  }
}

async function fetchUploadedTemplatesForDeleteUi() {
  if (!currentDocumentType?.id) return [];
  const response = await fetch(`/api/doc-generator/uploaded-templates/${encodeURIComponent(currentDocumentType.id)}`);
  if (!response.ok) return [];
  const json = await response.json();
  return json.templates || [];
}

function ensureUploadedTemplateManager() {
  const row = document.getElementById("legacyTemplateRow");
  if (!row) return null;

  let manager = document.getElementById("uploadedTemplatesManager");
  if (manager) return manager;

  manager = document.createElement("div");
  manager.id = "uploadedTemplatesManager";
  manager.className = "uploaded-template-manager";
  manager.innerHTML = `
    <div class="uploaded-template-manager-title">Uploaded Templates</div>
    <div id="uploadedTemplatesList"></div>
  `;
  row.appendChild(manager);
  return manager;
}

async function renderUploadedTemplateDeleteUi() {
  const manager = ensureUploadedTemplateManager();
  if (!manager) return;

  const list = document.getElementById("uploadedTemplatesList");
  if (!list) return;

  const templates = await fetchUploadedTemplatesForDeleteUi();
  const uploaded = templates.filter(item => {
    const id = item.id || item.filename || "";
    return id.startsWith("uploaded:") || item.source === "uploaded" || item.uploaded === true;
  });

  if (!uploaded.length) {
    manager.style.display = "none";
    list.innerHTML = "";
    return;
  }

  manager.style.display = "";
  list.innerHTML = "";

  for (const item of uploaded) {
    const rawId = item.id || item.filename || "";
    const filename = rawId.replace(/^uploaded:/, "");

    const row = document.createElement("div");
    row.className = "uploaded-template-row";

    const name = document.createElement("span");
    name.className = "uploaded-template-name";
    name.textContent = item.label || filename;

    const button = document.createElement("button");
    button.type = "button";
    button.className = "small-delete-button";
    button.textContent = "Delete";

    button.addEventListener("click", async () => {
      if (!confirm(`Delete uploaded template "${filename}"?`)) return;

      const response = await fetch(
        `/api/doc-generator/uploaded-template/${encodeURIComponent(currentDocumentType.id)}/${encodeURIComponent(filename)}`,
        {method: "DELETE"}
      );

      if (!response.ok) {
        const json = await response.json().catch(() => ({}));
        setStatus(`Could not delete template: ${json.detail || response.statusText}`);
        return;
      }

      setStatus("Uploaded template deleted.");

      if (typeof renderTemplateSelector === "function") {
        await renderTemplateSelector(currentDocumentType);
      }

      await renderUploadedTemplateDeleteUi();
    });

    row.appendChild(name);
    row.appendChild(button);
    list.appendChild(row);
  }
}

function runLegalUiCleanup() {
  normalizeLegalUi();
  renderUploadedTemplateDeleteUi();
}

document.addEventListener("DOMContentLoaded", () => {
  runLegalUiCleanup();
  setTimeout(runLegalUiCleanup, 300);
  setTimeout(runLegalUiCleanup, 1000);
});

const finalLegalUiObserver = new MutationObserver(() => {
  clearTimeout(window.__legalUiTimer);
  window.__legalUiTimer = setTimeout(runLegalUiCleanup, 100);
});

finalLegalUiObserver.observe(document.body, {
  childList: true,
  subtree: true
});
