(function () {
  const bootstrapNode = document.getElementById("rips-operativo-bootstrap");
  if (!bootstrapNode) return;

  const bootstrap = JSON.parse(bootstrapNode.textContent || "{}");
  const catalogs = bootstrap.catalogs || {};
  const initialCaseKey = String(bootstrap.selected_case_key || "").trim();

  const OTHER_SERVICE_SECTIONS = [
    { key: "examenes_laboratorio", label: "Laboratorio", tip: "Exámenes apoyados por factura clínica." },
    { key: "imagenologia", label: "Imagenología", tip: "Radiología, TAC, resonancia y estudios afines." },
    { key: "hospitalizacion", label: "Estancias", tip: "Días cama y consumos asociados a estancia." },
    { key: "honorarios_medicos", label: "Honorarios", tip: "Honorarios médicos llevados a otros servicios." },
  ];

  const TYPE_LABELS = {
    approved: "Aprobado",
    rejected: "Rechazado",
    notified: "Con notificación",
    idle: "Sin resultado",
  };

  const EXPORT_STATUS_LABELS = {
    ready: "Listo para exportar",
    preliminary: "Exportable preliminar",
  };

  const DEFAULT_FORM_STATE = {
    transaction: {
      tipo_nota: "",
      num_nota: "",
    },
    user: {
      tipo_usuario: "01",
      cod_municipio_residencia: "11001",
      cod_zona_territorial_residencia: "02",
      incapacidad: "NO",
      cod_pais_residencia: "170",
      cod_pais_origen: "170",
      tipo_documento_identificacion: "",
      num_documento_identificacion: "",
      fecha_nacimiento: "",
      cod_sexo: "",
    },
    procedure: {
      via_ingreso_servicio_salud: "01",
      modalidad_grupo_servicio_tec_sal: "01",
      grupo_servicios: "04",
      cod_servicio: 1,
      finalidad_tecnologia_salud: "44",
      concepto_recaudo: "02",
      valor_pago_moderador: 0,
      num_fev_pago_moderador: "",
      num_autorizacion: "",
      id_mipres: "",
      cod_diagnostico_relacionado: "",
      cod_complicacion: "",
    },
    hospitalizationEnabled: false,
    hospitalization: {
      via_ingreso_servicio_salud: "02",
      causa_motivo_atencion: "21",
      condicion_destino_usuario_egreso: "02",
      num_autorizacion: "",
      cod_diagnostico_principal_egreso: "",
      cod_complicacion: "",
    },
    medication_catalog: [
      {
        match_key: "",
        cod_tecnologia_salud: "",
        tipo_medicamento: "01",
        unidad_medida: 1,
        forma_farmaceutica: "",
        unidad_min_dispensa: 1,
        dias_tratamiento: 1,
        concentracion_medicamento: 0,
        concepto_recaudo: "02",
      },
    ],
    other_service_defaults: [
      { source_section: "examenes_laboratorio", tipo_os: "04", concepto_recaudo: "05" },
      { source_section: "imagenologia", tipo_os: "04", concepto_recaudo: "05" },
      { source_section: "hospitalizacion", tipo_os: "03", concepto_recaudo: "05" },
      { source_section: "honorarios_medicos", tipo_os: "04", concepto_recaudo: "05" },
    ],
    other_service_catalog: [
      {
        source_section: "honorarios_medicos",
        match_key: "",
        tipo_os: "04",
        cod_tecnologia_salud: "",
        nom_tecnologia_salud: "",
      },
    ],
  };

  const state = {
    cases: [],
    selectedCase: null,
    latestResult: null,
    templateContext: null,
  };

  const elements = {
    caseList: document.getElementById("caseList"),
    casesCountPill: document.getElementById("casesCountPill"),
    workspaceTitle: document.getElementById("workspaceTitle"),
    workspaceSubtitle: document.getElementById("workspaceSubtitle"),
    workspaceMeta: document.getElementById("workspaceMeta"),
    caseSummaryGrid: document.getElementById("caseSummaryGrid"),
    documentsCountPill: document.getElementById("documentsCountPill"),
    latestVersionPill: document.getElementById("latestVersionPill"),
    ripsMetrics: document.getElementById("ripsMetrics"),
    validationStatusBadge: document.getElementById("validationStatusBadge"),
    validationSummary: document.getElementById("validationSummary"),
    validationFindings: document.getElementById("validationFindings"),
    exportStatusBadge: document.getElementById("exportStatusBadge"),
    payloadPreview: document.getElementById("payloadPreview"),
    copyPayloadButton: document.getElementById("copyPayloadButton"),
    traceabilityTable: document.getElementById("traceabilityTable"),
    traceCountPill: document.getElementById("traceCountPill"),
    downloadButton: document.getElementById("downloadButton"),
    loadLatestButton: document.getElementById("loadLatestButton"),
    generateButton: document.getElementById("generateButton"),
    regenerateButton: document.getElementById("regenerateButton"),
    applyPresetButton: document.getElementById("applyPresetButton"),
    loadTemplateButton: document.getElementById("loadTemplateButton"),
    saveTemplateButton: document.getElementById("saveTemplateButton"),
    saveDraftButton: document.getElementById("saveDraftButton"),
    reloadCasesButton: document.getElementById("reloadCasesButton"),
    operationFeedbackPanel: document.getElementById("operationFeedbackPanel"),
    operationFeedbackTitle: document.getElementById("operationFeedbackTitle"),
    operationFeedbackMessage: document.getElementById("operationFeedbackMessage"),
    operationFeedbackDetails: document.getElementById("operationFeedbackDetails"),
    dismissOperationFeedbackButton: document.getElementById("dismissOperationFeedbackButton"),
    templateScopeLevel: document.getElementById("templateScopeLevel"),
    templateScopeSummary: document.getElementById("templateScopeSummary"),
    hospitalizationEnabled: document.getElementById("hospitalizationEnabled"),
    hospitalizationFields: document.getElementById("hospitalizationFields"),
    medicationCatalogRows: document.getElementById("medicationCatalogRows"),
    otherServiceCatalogRows: document.getElementById("otherServiceCatalogRows"),
    otherServiceDefaultsGrid: document.getElementById("otherServiceDefaultsGrid"),
    form: document.getElementById("ripsForm"),
  };

  function draftKey(caseKey) {
    return `rips-operativo:${caseKey}`;
  }

  function deepClone(value) {
    return JSON.parse(JSON.stringify(value));
  }

  function mergeDeep(base, override) {
    if (!override || typeof override !== "object" || Array.isArray(override)) return base;
    const result = Array.isArray(base) ? base.slice() : { ...base };
    Object.entries(override).forEach(([key, value]) => {
      if (Array.isArray(value)) {
        result[key] = deepClone(value);
        return;
      }
      if (value && typeof value === "object") {
        result[key] = mergeDeep(result[key] && typeof result[key] === "object" ? result[key] : {}, value);
        return;
      }
      result[key] = value;
    });
    return result;
  }

  function getFormDraft() {
    if (!state.selectedCase) return deepClone(DEFAULT_FORM_STATE);
    try {
      const stored = globalThis.localStorage.getItem(draftKey(state.selectedCase.case_key));
      if (!stored) return deepClone(DEFAULT_FORM_STATE);
      return mergeDeep(deepClone(DEFAULT_FORM_STATE), JSON.parse(stored));
    } catch (_) {
      return deepClone(DEFAULT_FORM_STATE);
    }
  }

  function persistDraft(showToast) {
    if (!state.selectedCase) return;
    const draft = collectFormState();
    globalThis.localStorage.setItem(draftKey(state.selectedCase.case_key), JSON.stringify(draft));
    if (showToast) {
      AppToast.show("Borrador RIPS guardado en este navegador.", {
        type: "success",
        duration: 2200,
      });
    }
  }

  function normalizeText(value) {
    return String(value == null ? "" : value).trim();
  }

  function toNumberOrEmpty(value) {
    const text = normalizeText(value);
    if (!text) return "";
    const number = Number(text);
    return Number.isFinite(number) ? number : "";
  }

  function populateCatalogSelects() {
    document.querySelectorAll("[data-catalog]").forEach((select) => {
      const catalogName = select.dataset.catalog;
      const options = catalogs[catalogName] || {};
      const includeBlank = !select.hasAttribute("data-no-blank");
      select.innerHTML = "";
      if (includeBlank) {
        const blank = document.createElement("option");
        blank.value = "";
        blank.textContent = "Selecciona...";
        select.appendChild(blank);
      }
      Object.entries(options).forEach(([code, label]) => {
        const option = document.createElement("option");
        option.value = code;
        option.textContent = `${code} · ${label}`;
        select.appendChild(option);
      });
    });
  }

  function createField(label, input) {
    const field = document.createElement("label");
    field.className = "rips-field";
    const span = document.createElement("span");
    span.textContent = label;
    field.appendChild(span);
    field.appendChild(input);
    return field;
  }

  function buildSelect(optionsMap, value, includeBlank) {
    const select = document.createElement("select");
    if (includeBlank) {
      const blank = document.createElement("option");
      blank.value = "";
      blank.textContent = "Selecciona...";
      select.appendChild(blank);
    }
    Object.entries(optionsMap || {}).forEach(([code, label]) => {
      const option = document.createElement("option");
      option.value = code;
      option.textContent = `${code} · ${label}`;
      if (String(value) === code) option.selected = true;
      select.appendChild(option);
    });
    return select;
  }

  function renderOtherServiceDefaults(defaultsState) {
    elements.otherServiceDefaultsGrid.innerHTML = "";
    OTHER_SERVICE_SECTIONS.forEach((section) => {
      const values = defaultsState.find((item) => item.source_section === section.key) || {
        source_section: section.key,
        tipo_os: "",
        concepto_recaudo: "05",
      };

      const card = document.createElement("article");
      card.className = "rips-default-card";
      card.dataset.section = section.key;

      const title = document.createElement("h5");
      title.textContent = section.label;
      card.appendChild(title);

      const description = document.createElement("p");
      description.textContent = section.tip;
      card.appendChild(description);

      const grid = document.createElement("div");
      grid.className = "rips-field-grid rips-field-grid--two";

      const tipoSelect = buildSelect(catalogs.tipo_otro_servicio || {}, values.tipo_os || "", true);
      tipoSelect.name = `other_service_defaults.${section.key}.tipo_os`;
      grid.appendChild(createField("Tipo OS", tipoSelect));

      const recaudoSelect = buildSelect(catalogs.concepto_recaudo || {}, values.concepto_recaudo || "05", true);
      recaudoSelect.name = `other_service_defaults.${section.key}.concepto_recaudo`;
      grid.appendChild(createField("Concepto recaudo", recaudoSelect));

      const autorizacionInput = document.createElement("input");
      autorizacionInput.type = "text";
      autorizacionInput.name = `other_service_defaults.${section.key}.num_autorizacion`;
      autorizacionInput.value = values.num_autorizacion || "";
      grid.appendChild(createField("Autorización", autorizacionInput));

      const mipresInput = document.createElement("input");
      mipresInput.type = "text";
      mipresInput.name = `other_service_defaults.${section.key}.id_mipres`;
      mipresInput.value = values.id_mipres || "";
      grid.appendChild(createField("ID MIPRES", mipresInput));

      card.appendChild(grid);
      elements.otherServiceDefaultsGrid.appendChild(card);
    });
  }

  function renderMedicationRows(rows) {
    elements.medicationCatalogRows.innerHTML = "";
    rows.forEach((row, index) => {
      const wrapper = document.createElement("div");
      wrapper.className = "rips-repeatable-row";

      const head = document.createElement("div");
      head.className = "rips-repeatable-row__head";
      head.innerHTML = `<span class="rips-repeatable-row__title">Medicamento ${index + 1}</span>`;
      const removeButton = document.createElement("button");
      removeButton.type = "button";
      removeButton.className = "rips-remove-button";
      removeButton.textContent = "Eliminar";
      removeButton.addEventListener("click", () => {
        const nextRows = collectFormState().medication_catalog.filter((_, rowIndex) => rowIndex !== index);
        renderMedicationRows(nextRows.length ? nextRows : []);
        persistDraft(false);
      });
      head.appendChild(removeButton);
      wrapper.appendChild(head);

      const grid = document.createElement("div");
      grid.className = "rips-repeatable-row__grid";
      const fields = [
        ["match_key", "Match key", "text"],
        ["cod_tecnologia_salud", "Cod tecnología", "text"],
        ["tipo_medicamento", "Tipo medicamento", "text"],
        ["unidad_medida", "Unidad medida", "number"],
        ["forma_farmaceutica", "Forma farmacéutica", "text"],
        ["unidad_min_dispensa", "Unidad mínima", "number"],
        ["dias_tratamiento", "Días tratamiento", "number"],
        ["concentracion_medicamento", "Concentración", "number"],
      ];
      fields.forEach(([key, label, type]) => {
        const input = document.createElement("input");
        input.type = type;
        input.name = `medication_catalog.${index}.${key}`;
        if (type === "number") input.step = key === "concentracion_medicamento" ? "0.01" : "1";
        input.value = row[key] ?? "";
        grid.appendChild(createField(label, input));
      });

      const recaudoSelect = buildSelect(catalogs.concepto_recaudo || {}, row.concepto_recaudo || "02", true);
      recaudoSelect.name = `medication_catalog.${index}.concepto_recaudo`;
      grid.appendChild(createField("Concepto recaudo", recaudoSelect));

      wrapper.appendChild(grid);
      elements.medicationCatalogRows.appendChild(wrapper);
    });
  }

  function renderOtherServiceRows(rows) {
    elements.otherServiceCatalogRows.innerHTML = "";
    rows.forEach((row, index) => {
      const wrapper = document.createElement("div");
      wrapper.className = "rips-repeatable-row";

      const head = document.createElement("div");
      head.className = "rips-repeatable-row__head";
      head.innerHTML = `<span class="rips-repeatable-row__title">Override ${index + 1}</span>`;
      const removeButton = document.createElement("button");
      removeButton.type = "button";
      removeButton.className = "rips-remove-button";
      removeButton.textContent = "Eliminar";
      removeButton.addEventListener("click", () => {
        const nextRows = collectFormState().other_service_catalog.filter((_, rowIndex) => rowIndex !== index);
        renderOtherServiceRows(nextRows.length ? nextRows : []);
        persistDraft(false);
      });
      head.appendChild(removeButton);
      wrapper.appendChild(head);

      const grid = document.createElement("div");
      grid.className = "rips-repeatable-row__grid";

      const sectionSelect = document.createElement("select");
      OTHER_SERVICE_SECTIONS.forEach((section) => {
        const option = document.createElement("option");
        option.value = section.key;
        option.textContent = section.label;
        if ((row.source_section || "") === section.key) option.selected = true;
        sectionSelect.appendChild(option);
      });
      sectionSelect.name = `other_service_catalog.${index}.source_section`;
      grid.appendChild(createField("Sección", sectionSelect));

      const tipoSelect = buildSelect(catalogs.tipo_otro_servicio || {}, row.tipo_os || "", true);
      tipoSelect.name = `other_service_catalog.${index}.tipo_os`;
      grid.appendChild(createField("Tipo OS", tipoSelect));

      const fields = [
        ["match_key", "Match key", "text"],
        ["cod_tecnologia_salud", "Cod tecnología", "text"],
        ["nom_tecnologia_salud", "Nombre tecnología", "text"],
      ];
      fields.forEach(([key, label, type]) => {
        const input = document.createElement("input");
        input.type = type;
        input.name = `other_service_catalog.${index}.${key}`;
        input.value = row[key] ?? "";
        grid.appendChild(createField(label, input));
      });

      wrapper.appendChild(grid);
      elements.otherServiceCatalogRows.appendChild(wrapper);
    });
  }

  function applyDraftToForm(draft) {
    Object.entries(draft.transaction || {}).forEach(([key, value]) => {
      const input = elements.form.querySelector(`[name="transaction.${key}"]`);
      if (input) input.value = value ?? "";
    });
    Object.entries(draft.user || {}).forEach(([key, value]) => {
      const input = elements.form.querySelector(`[name="user.${key}"]`);
      if (input) input.value = value ?? "";
    });
    Object.entries(draft.procedure || {}).forEach(([key, value]) => {
      const input = elements.form.querySelector(`[name="procedure.${key}"]`);
      if (input) input.value = value ?? "";
    });
    Object.entries(draft.hospitalization || {}).forEach(([key, value]) => {
      const input = elements.form.querySelector(`[name="hospitalization.${key}"]`);
      if (input) input.value = value ?? "";
    });
    elements.hospitalizationEnabled.checked = Boolean(draft.hospitalizationEnabled);
    toggleHospitalizationFields();
    renderOtherServiceDefaults(draft.other_service_defaults || []);
    renderMedicationRows(draft.medication_catalog || []);
    renderOtherServiceRows(draft.other_service_catalog || []);
  }

  function buildTemplateScopeSummary(template) {
    const scope = template?.scope || {};
    const segments = [];
    const levelLabels = {
      global: "Global",
      provider: "Prestador",
      provider_payer: "Prestador + pagador",
      provider_payer_site: "Prestador + pagador + sede",
    };
    segments.push(`Alcance: ${levelLabels[scope.level] || "Sin definir"}`);
    if (scope.provider_nit || scope.provider_name) {
      segments.push(`Prestador: ${(scope.provider_name || "Sin nombre")} ${scope.provider_nit ? `(${scope.provider_nit})` : ""}`.trim());
    }
    if (scope.payer_nit || scope.payer_name) {
      segments.push(`Pagador: ${(scope.payer_name || "Sin nombre")} ${scope.payer_nit ? `(${scope.payer_nit})` : ""}`.trim());
    }
    if (scope.site_name) {
      segments.push(`Sede: ${scope.site_name}`);
    }
    if (template?.stored) {
      segments.push(`Plantilla v${template.version ?? "-"}`);
    } else {
      segments.push("Sin plantilla persistida para este alcance.");
    }
    return segments.join(" · ");
  }

  function buildDraftFromOptions(options) {
    const normalized = deepClone(DEFAULT_FORM_STATE);
    if (!options || typeof options !== "object") return normalized;
    const merged = mergeDeep(normalized, options);
    merged.hospitalizationEnabled = Boolean(options.hospitalization);
    return merged;
  }

  function collectRows(containerSelector, keys, numericKeys) {
    const rows = [];
    document.querySelectorAll(containerSelector).forEach((rowNode, rowIndex) => {
      const row = {};
      let hasValue = false;
      keys.forEach((key) => {
        const input = rowNode.querySelector(`[name$=".${key}"]`);
        if (!input) return;
        const value = numericKeys.includes(key) ? toNumberOrEmpty(input.value) : normalizeText(input.value);
        if (value !== "" && value !== null) hasValue = true;
        row[key] = value;
      });
      if (hasValue) rows.push(row);
      rowIndex;
    });
    return rows;
  }

  function collectFormState() {
    const read = (name) => elements.form.querySelector(`[name="${name}"]`);
    const draft = deepClone(DEFAULT_FORM_STATE);

    ["tipo_nota", "num_nota"].forEach((key) => {
      draft.transaction[key] = normalizeText(read(`transaction.${key}`)?.value);
    });

    [
      "tipo_usuario",
      "cod_municipio_residencia",
      "cod_zona_territorial_residencia",
      "incapacidad",
      "cod_pais_residencia",
      "cod_pais_origen",
      "tipo_documento_identificacion",
      "num_documento_identificacion",
      "fecha_nacimiento",
      "cod_sexo",
    ].forEach((key) => {
      draft.user[key] = normalizeText(read(`user.${key}`)?.value);
    });

    [
      "via_ingreso_servicio_salud",
      "modalidad_grupo_servicio_tec_sal",
      "grupo_servicios",
      "finalidad_tecnologia_salud",
      "concepto_recaudo",
      "num_fev_pago_moderador",
      "num_autorizacion",
      "id_mipres",
      "cod_diagnostico_relacionado",
      "cod_complicacion",
    ].forEach((key) => {
      draft.procedure[key] = normalizeText(read(`procedure.${key}`)?.value);
    });
    draft.procedure.cod_servicio = toNumberOrEmpty(read("procedure.cod_servicio")?.value);
    draft.procedure.valor_pago_moderador = toNumberOrEmpty(read("procedure.valor_pago_moderador")?.value);

    draft.hospitalizationEnabled = elements.hospitalizationEnabled.checked;
    [
      "via_ingreso_servicio_salud",
      "causa_motivo_atencion",
      "condicion_destino_usuario_egreso",
      "num_autorizacion",
      "cod_diagnostico_principal_egreso",
      "cod_complicacion",
    ].forEach((key) => {
      draft.hospitalization[key] = normalizeText(read(`hospitalization.${key}`)?.value);
    });

    draft.other_service_defaults = OTHER_SERVICE_SECTIONS.map((section) => ({
      source_section: section.key,
      tipo_os: normalizeText(read(`other_service_defaults.${section.key}.tipo_os`)?.value),
      concepto_recaudo: normalizeText(read(`other_service_defaults.${section.key}.concepto_recaudo`)?.value),
      num_autorizacion: normalizeText(read(`other_service_defaults.${section.key}.num_autorizacion`)?.value),
      id_mipres: normalizeText(read(`other_service_defaults.${section.key}.id_mipres`)?.value),
    }));

    draft.medication_catalog = collectRows(
      "#medicationCatalogRows .rips-repeatable-row",
      [
        "match_key",
        "cod_tecnologia_salud",
        "tipo_medicamento",
        "unidad_medida",
        "forma_farmaceutica",
        "unidad_min_dispensa",
        "dias_tratamiento",
        "concentracion_medicamento",
        "concepto_recaudo",
      ],
      ["unidad_medida", "unidad_min_dispensa", "dias_tratamiento", "concentracion_medicamento"]
    );

    draft.other_service_catalog = collectRows(
      "#otherServiceCatalogRows .rips-repeatable-row",
      ["source_section", "match_key", "tipo_os", "cod_tecnologia_salud", "nom_tecnologia_salud"],
      []
    );

    return draft;
  }

  function stripEmptyValues(value) {
    if (Array.isArray(value)) {
      return value
        .map(stripEmptyValues)
        .filter((item) => {
          if (item == null) return false;
          if (Array.isArray(item)) return item.length > 0;
          if (typeof item === "object") return Object.keys(item).length > 0;
          return item !== "";
        });
    }
    if (value && typeof value === "object") {
      return Object.entries(value).reduce((acc, [key, item]) => {
        const cleanValue = stripEmptyValues(item);
        const shouldKeep =
          cleanValue !== "" &&
          cleanValue != null &&
          (!Array.isArray(cleanValue) || cleanValue.length > 0) &&
          (typeof cleanValue !== "object" || Array.isArray(cleanValue) || Object.keys(cleanValue).length > 0);
        if (shouldKeep) acc[key] = cleanValue;
        return acc;
      }, {});
    }
    return value;
  }

  function buildOptionsPayload() {
    const draft = collectFormState();
    const payload = {
      transaction: draft.transaction,
      user: draft.user,
      procedure: draft.procedure,
      medication_catalog: draft.medication_catalog,
      other_service_defaults: draft.other_service_defaults,
      other_service_catalog: draft.other_service_catalog,
    };
    if (draft.hospitalizationEnabled) {
      payload.hospitalization = draft.hospitalization;
    }
    return stripEmptyValues(payload);
  }

  function buildSummaryGrid(caseItem) {
    elements.caseSummaryGrid.innerHTML = "";
    const entries = [
      ["Case key", caseItem?.case_key || "Sin selección"],
      ["Número", caseItem?.case_number || "Sin número"],
      ["Paciente", caseItem?.patient_name || "Sin selección"],
      ["Documento", caseItem?.patient_id || "No identificado"],
    ];
    entries.forEach(([label, value]) => {
      const wrapper = document.createElement("div");
      wrapper.innerHTML = `<dt>${label}</dt><dd>${value}</dd>`;
      elements.caseSummaryGrid.appendChild(wrapper);
    });
  }

  function updateWorkspaceHeader(caseItem) {
    if (!caseItem) {
      elements.workspaceTitle.textContent = "Selecciona un caso para operar el RIPS";
      elements.workspaceSubtitle.textContent =
        "Define parámetros administrativos, revisa hallazgos normativos y descarga el JSON listo para auditoría.";
      elements.workspaceMeta.innerHTML = '<span class="rips-status-badge rips-status-badge--idle">Sin caso</span>';
      buildSummaryGrid(null);
      elements.documentsCountPill.textContent = "0 docs";
      return;
    }

    elements.workspaceTitle.textContent = `Caso ${caseItem.case_number || caseItem.case_key}`;
    elements.workspaceSubtitle.textContent = `${caseItem.patient_name || "Paciente"} · ${caseItem.tipos_documento.join(", ")}`;
    elements.workspaceMeta.innerHTML = `
      <span class="rips-status-badge rips-status-badge--idle">${caseItem.case_key || "legacy"}</span>
      <a class="rips-link-chip" href="/casos?case_key=${encodeURIComponent(caseItem.case_key || "")}" ${caseItem.case_key ? "" : "style=\"pointer-events:none;opacity:.5;\""}>Ver caso</a>
    `;
    buildSummaryGrid(caseItem);
    elements.documentsCountPill.textContent = `${(caseItem.documentos || []).length} docs`;
  }

  function renderCases() {
    elements.caseList.innerHTML = "";
    elements.casesCountPill.textContent = String(state.cases.length);

    if (!state.cases.length) {
      elements.caseList.innerHTML = '<div class="rips-empty-state rips-empty-state--compact">No hay casos disponibles.</div>';
      return;
    }

    state.cases.forEach((caseItem) => {
      const button = document.createElement("button");
      button.type = "button";
      button.className = "rips-case-card";
      if (state.selectedCase?.group_key === caseItem.group_key) {
        button.classList.add("is-active");
      }
      button.innerHTML = `
        <p class="rips-case-card__title">${caseItem.case_number || caseItem.case_key || "Caso sin número"}</p>
        <p class="rips-case-card__meta">${caseItem.patient_name || "Paciente"}${caseItem.patient_id ? ` · ${caseItem.patient_id}` : ""}</p>
        <p class="rips-case-card__types">${(caseItem.tipos_documento || []).join(", ")}</p>
      `;
      button.addEventListener("click", () => selectCase(caseItem));
      elements.caseList.appendChild(button);
    });
  }

  async function loadCases() {
    const toastId = AppToast.start("Cargando casos operables...");
    try {
      const response = await fetch("/mis_historias");
      const payload = await response.json();
      if (!response.ok) {
        throw new Error(payload.detail || "No se pudieron cargar los casos.");
      }
      const sourceCases = payload.historias_por_caso || {};
      state.cases = Object.values(sourceCases)
        .filter((item) => item.case_key)
        .sort((a, b) => String(b.case_number || b.case_key).localeCompare(String(a.case_number || a.case_key)));
      AppToast.success(toastId, "Casos cargados.");
      const selected =
        state.cases.find((item) => item.case_key === initialCaseKey) ||
        state.cases.find((item) => item.case_key === state.selectedCase?.case_key) ||
        state.cases[0] ||
        null;
      renderCases();
      selectCase(selected, { silent: true });
    } catch (error) {
      AppToast.error(toastId, `Error cargando casos: ${error.message}`);
      elements.caseList.innerHTML = `<div class="rips-empty-state rips-empty-state--compact">${error.message}</div>`;
    }
  }

  function updateUrl(caseKey) {
    const url = new URL(globalThis.location.href);
    if (caseKey) {
      url.searchParams.set("case_key", caseKey);
    } else {
      url.searchParams.delete("case_key");
    }
    globalThis.history.replaceState({}, "", url.toString());
  }

  function selectCase(caseItem, options) {
    state.selectedCase = caseItem || null;
    state.templateContext = null;
    clearOperationFeedback();
    renderCases();
    updateWorkspaceHeader(caseItem);
    updateUrl(caseItem?.case_key || "");
    clearLatestResult();
    applyDraftToForm(getFormDraft());
    updateTemplateSummary(null);
    if (caseItem?.case_key) {
      void fetchCaseTemplate({ applyToForm: false, silent: true });
    }
    if (!(options && options.silent)) {
      AppToast.show(caseItem ? `Caso ${caseItem.case_number || caseItem.case_key} listo para operar.` : "Selecciona un caso.", {
        type: "info",
        duration: 1800,
      });
    }
  }

  function clearLatestResult() {
    state.latestResult = null;
    elements.latestVersionPill.textContent = "v-";
    elements.ripsMetrics.innerHTML = `
      <div class="rips-metric"><span class="rips-metric__label">Fuente</span><strong class="rips-metric__value">Sin dato</strong></div>
      <div class="rips-metric"><span class="rips-metric__label">CUV</span><strong class="rips-metric__value">Pendiente</strong></div>
      <div class="rips-metric"><span class="rips-metric__label">Hallazgos</span><strong class="rips-metric__value">0</strong></div>
    `;
    elements.validationStatusBadge.className = "rips-status-badge rips-status-badge--idle";
    elements.validationStatusBadge.textContent = TYPE_LABELS.idle;
    elements.exportStatusBadge.className = "rips-status-badge rips-status-badge--idle";
    elements.exportStatusBadge.textContent = "Sin exportación";
    elements.validationSummary.className = "rips-empty-state";
    elements.validationSummary.textContent = "Genera o consulta un RIPS para ver hallazgos.";
    elements.validationFindings.innerHTML = "";
    elements.payloadPreview.textContent = "Sin payload generado.";
    elements.traceabilityTable.className = "rips-empty-state";
    elements.traceabilityTable.textContent = "La trazabilidad aparecerá después de generar o consultar un RIPS.";
    elements.traceCountPill.textContent = "0";
    elements.downloadButton.disabled = true;
    elements.downloadButton.textContent = "Descargar JSON";
    elements.copyPayloadButton.disabled = true;
  }

  function clearOperationFeedback() {
    elements.operationFeedbackPanel.hidden = true;
    elements.operationFeedbackMessage.textContent = "";
    elements.operationFeedbackDetails.innerHTML = "";
  }

  function renderOperationFeedback(summary, title) {
    elements.operationFeedbackTitle.textContent = title || "Error operativo";
    elements.operationFeedbackMessage.textContent = summary.message || "Falló la operación.";
    elements.operationFeedbackDetails.innerHTML = "";

    if (!summary.items.length) {
      const empty = document.createElement("div");
      empty.className = "rips-empty-state";
      empty.textContent = "No se recibió detalle adicional del error.";
      elements.operationFeedbackDetails.appendChild(empty);
    } else {
      summary.items.forEach((item, index) => {
        const article = document.createElement("article");
        article.className = "rips-finding rips-finding--reject";
        article.innerHTML = `
          <div class="rips-finding__head">
            <span class="rips-finding__code">FORM-${String(index + 1).padStart(3, "0")}</span>
            <span class="rips-pill">Formulario</span>
          </div>
          <p>${item.message}</p>
          <div class="rips-finding__meta">
            ${item.fieldPath ? `<div>Campo: ${item.fieldPath}</div>` : ""}
          </div>
        `;
        elements.operationFeedbackDetails.appendChild(article);
      });
    }

    elements.operationFeedbackPanel.hidden = false;
    elements.operationFeedbackPanel.scrollIntoView({ behavior: "smooth", block: "start" });
  }

  function summarizeApiError(detail, fallbackMessage) {
    const fallback = String(fallbackMessage || "Falló la operación RIPS.").trim();
    if (Array.isArray(detail)) {
      const normalized = detail
        .filter((item) => item && typeof item === "object")
        .map((item) => {
          const fieldPath = Array.isArray(item.loc) ? item.loc.slice(1).join(".") : "";
          return {
            fieldPath,
            message: normalizeText(item.msg || item.message || "Error de validación."),
          };
        })
        .filter((item) => item.message);

      if (!normalized.length) {
        return { message: fallback, items: [] };
      }

      return {
        message: `${fallback} Se encontraron ${normalized.length} error(es) de validación.`,
        items: normalized,
      };
    }

    const text = normalizeText(detail);
    return {
      message: text || fallback,
      items: [],
    };
  }

  function renderOperationError(summary) {
    clearLatestResult();
    renderOperationFeedback(summary, "Error operativo RIPS");
    elements.validationStatusBadge.className = "rips-status-badge rips-status-badge--rejected";
    elements.validationStatusBadge.textContent = "Error operativo";
    elements.exportStatusBadge.className = "rips-status-badge rips-status-badge--rejected";
    elements.exportStatusBadge.textContent = "Operación fallida";
    elements.validationSummary.className = "rips-empty-state";
    elements.validationSummary.innerHTML = `
      <strong>${summary.message}</strong>
      <div class="rips-muted" style="margin-top:8px;">
        Corrige los campos señalados y vuelve a ejecutar la operación.
      </div>
    `;

    elements.validationFindings.innerHTML = "";
    if (!summary.items.length) {
      elements.validationFindings.innerHTML = '<div class="rips-empty-state">No se recibió detalle adicional del error.</div>';
      return;
    }

    summary.items.forEach((item, index) => {
      const article = document.createElement("article");
      article.className = "rips-finding rips-finding--reject";
      article.innerHTML = `
        <div class="rips-finding__head">
          <span class="rips-finding__code">FORM-${String(index + 1).padStart(3, "0")}</span>
          <span class="rips-pill">Formulario</span>
        </div>
        <p>${item.message}</p>
        <div class="rips-finding__meta">
          ${item.fieldPath ? `<div>Campo: ${item.fieldPath}</div>` : ""}
        </div>
      `;
      elements.validationFindings.appendChild(article);
    });
  }

  function normalizeErrorSummary(error, fallbackMessage) {
    if (error && typeof error === "object" && "message" in error) {
      return {
        message: normalizeText(error.message) || fallbackMessage,
        items: Array.isArray(error.items) ? error.items : [],
      };
    }
    return summarizeApiError("", fallbackMessage);
  }

  function updateTemplateSummary(template) {
    state.templateContext = template || null;
    elements.templateScopeSummary.textContent = buildTemplateScopeSummary(template);
    if (template?.scope?.level) {
      elements.templateScopeLevel.value = template.scope.level;
    }
  }

  function renderResult(result) {
    state.latestResult = result;
    const report = result.validation_report || {};
    const findings = Array.isArray(report.findings) ? report.findings : [];
    const status = String(report.status || "idle");
    const ready = Boolean(report.ready_for_cuv);
    const exportStatus = result.export_status === "ready" ? "ready" : "preliminary";
    const badgeClass =
      status === "approved"
        ? "approved"
        : status === "rejected"
          ? "rejected"
          : status === "notified"
            ? "notified"
            : "idle";

    elements.latestVersionPill.textContent = `v${result.version ?? "-"}`;
    elements.ripsMetrics.innerHTML = `
      <div class="rips-metric"><span class="rips-metric__label">Fuente</span><strong class="rips-metric__value">${result.source || "Sin dato"}</strong></div>
      <div class="rips-metric"><span class="rips-metric__label">CUV</span><strong class="rips-metric__value">${ready ? "Listo" : "No listo"}</strong></div>
      <div class="rips-metric"><span class="rips-metric__label">Hallazgos</span><strong class="rips-metric__value">${findings.length}</strong></div>
    `;

    elements.validationStatusBadge.className = `rips-status-badge rips-status-badge--${badgeClass}`;
    elements.validationStatusBadge.textContent = TYPE_LABELS[status] || TYPE_LABELS.idle;
    elements.exportStatusBadge.className = `rips-status-badge rips-status-badge--${ready ? "approved" : "notified"}`;
    elements.exportStatusBadge.textContent = EXPORT_STATUS_LABELS[exportStatus];

    elements.validationSummary.className = ready ? "rips-empty-state" : "rips-empty-state";
    elements.validationSummary.innerHTML = `
      <strong>${result.export_message || (ready ? "El JSON puede pasar a revisión final." : "El caso requiere ajuste antes de CUV.")}</strong>
      <div class="rips-muted" style="margin-top:8px;">
        Guardado: ${result.stored ? "sí" : "no"} · Regenerado: ${result.regenerated ? "sí" : "no"} · Versión: ${result.version ?? "-"} · Descarga: ${EXPORT_STATUS_LABELS[exportStatus]}
      </div>
    `;

    elements.validationFindings.innerHTML = "";
    if (!findings.length) {
      elements.validationFindings.innerHTML = '<div class="rips-empty-state">No hay hallazgos registrados.</div>';
    } else {
      findings.forEach((finding) => {
        const article = document.createElement("article");
        article.className = `rips-finding rips-finding--${finding.severity}`;
        article.innerHTML = `
          <div class="rips-finding__head">
            <span class="rips-finding__code">${finding.rule_code}</span>
            <span class="rips-pill">${finding.severity === "reject" ? "Rechazo" : "Notificación"}</span>
          </div>
          <p>${finding.message}</p>
          <div class="rips-finding__meta">
            ${finding.field_path ? `<div>Campo: ${finding.field_path}</div>` : ""}
            ${finding.source_path ? `<div>Fuente: ${finding.source_path}</div>` : ""}
          </div>
        `;
        elements.validationFindings.appendChild(article);
      });
    }

    elements.payloadPreview.textContent = JSON.stringify(result.payload || {}, null, 2);
    elements.copyPayloadButton.disabled = false;

    const traceRows = Array.isArray(result.field_trace_map) ? result.field_trace_map : [];
    elements.traceCountPill.textContent = String(traceRows.length);
    if (!traceRows.length) {
      elements.traceabilityTable.className = "rips-empty-state";
      elements.traceabilityTable.textContent = "Sin trazas registradas para esta versión.";
    } else {
      elements.traceabilityTable.className = "rips-trace-table";
      const rows = traceRows
        .slice(0, 80)
        .map(
          (trace) => `
            <tr>
              <td>${trace.field_path || ""}</td>
              <td>${trace.source_path || ""}</td>
              <td>${trace.transform || ""}</td>
            </tr>`
        )
        .join("");
      elements.traceabilityTable.innerHTML = `
        <table>
          <thead>
            <tr>
              <th>Campo RIPS</th>
              <th>Fuente</th>
              <th>Transformación</th>
            </tr>
          </thead>
          <tbody>${rows}</tbody>
        </table>
      `;
    }

    elements.downloadButton.disabled = false;
    elements.downloadButton.textContent = ready ? "Descargar JSON" : "Descargar JSON preliminar";
  }

  async function runRipsAction(action) {
    if (!state.selectedCase?.case_key) {
      AppToast.show("Selecciona un caso antes de operar el RIPS.", { type: "info", duration: 2600 });
      return;
    }

    const toastId = AppToast.start(
      action === "latest" ? "Consultando última versión..." : action === "regen" ? "Regenerando RIPS..." : "Generando RIPS..."
    );

    try {
      if (action === "latest") {
        const response = await fetch(`/api/rips/cases/${encodeURIComponent(state.selectedCase.case_key)}`);
        const payload = await response.json();
        if (!response.ok) {
          throw summarizeApiError(payload.detail, "No se pudo consultar el último RIPS.");
        }
        clearOperationFeedback();
        renderResult(payload);
        AppToast.success(toastId, "Último RIPS cargado.");
        return;
      }

      persistDraft(false);
      const response = await fetch(`/api/rips/cases/${encodeURIComponent(state.selectedCase.case_key)}`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          options: buildOptionsPayload(),
          regen: action === "regen",
          persist: true,
        }),
      });
      const payload = await response.json();
      if (!response.ok) {
        throw summarizeApiError(payload.detail, "No se pudo generar el RIPS.");
      }
      clearOperationFeedback();
      renderResult(payload);
      AppToast.success(toastId, action === "regen" ? "RIPS regenerado." : "RIPS generado.");
      if (payload.export_status !== "ready") {
        AppToast.show(
          payload.export_message || "El resultado quedó en estado preliminar y requiere ajuste antes de CUV.",
          { type: "info", duration: 3200 }
        );
      }
    } catch (error) {
      const summary = normalizeErrorSummary(error, "Falló la operación RIPS.");
      renderOperationError(summary);
      const description = Array.isArray(summary.items) && summary.items.length
        ? summary.items.slice(0, 3).map((item) => item.fieldPath ? `${item.fieldPath}: ${item.message}` : item.message).join(" | ")
        : "";
      AppToast.error(toastId, summary.message || "Falló la operación RIPS.", { description, duration: 40000 });
    }
  }

  async function fetchCaseTemplate({ applyToForm, silent }) {
    if (!state.selectedCase?.case_key) return;
    const toastId = silent ? null : AppToast.start("Consultando plantilla operativa...");
    try {
      const response = await fetch(`/api/rips/cases/${encodeURIComponent(state.selectedCase.case_key)}/template`);
      const payload = await response.json();
      if (!response.ok) {
        throw summarizeApiError(payload.detail, "No se pudo consultar la plantilla.");
      }
      updateTemplateSummary(payload);
      if (applyToForm) {
        if (payload.stored && payload.options) {
          clearOperationFeedback();
          applyDraftToForm(buildDraftFromOptions(payload.options));
          persistDraft(false);
          if (toastId) AppToast.success(toastId, "Plantilla aplicada al formulario.");
        } else if (toastId) {
          AppToast.show("No existe plantilla persistida para este caso.", { type: "info", duration: 2400 });
        }
      } else if (toastId) {
        AppToast.success(toastId, "Scope operativo cargado.");
      }
    } catch (error) {
      const summary = normalizeErrorSummary(error, "Falló la consulta de plantilla.");
      renderOperationFeedback(summary, "Error consultando plantilla");
      if (toastId) {
        AppToast.error(toastId, summary.message || "Falló la consulta de plantilla.", {
          description: summary.items.slice(0, 3).map((item) => item.fieldPath ? `${item.fieldPath}: ${item.message}` : item.message).join(" | "),
          duration: 40000,
        });
      }
    }
  }

  async function saveCaseTemplate() {
    if (!state.selectedCase?.case_key) {
      AppToast.show("Selecciona un caso antes de guardar una plantilla.", { type: "info", duration: 2200 });
      return;
    }
    const toastId = AppToast.start("Guardando plantilla operativa...");
    try {
      const response = await fetch(`/api/rips/cases/${encodeURIComponent(state.selectedCase.case_key)}/template`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          scope_level: elements.templateScopeLevel.value,
          options: buildOptionsPayload(),
        }),
      });
      const payload = await response.json();
      if (!response.ok) {
        throw summarizeApiError(payload.detail, "No se pudo guardar la plantilla.");
      }
      clearOperationFeedback();
      updateTemplateSummary(payload);
      AppToast.success(toastId, "Plantilla operativa guardada.");
    } catch (error) {
      const summary = normalizeErrorSummary(error, "Falló el guardado de plantilla.");
      renderOperationError(summary);
      AppToast.error(toastId, summary.message || "Falló el guardado de plantilla.", {
        description: summary.items.slice(0, 3).map((item) => item.fieldPath ? `${item.fieldPath}: ${item.message}` : item.message).join(" | "),
        duration: 40000,
      });
    }
  }

  function toggleHospitalizationFields() {
    const disabled = !elements.hospitalizationEnabled.checked;
    elements.hospitalizationFields.querySelectorAll("input").forEach((input) => {
      input.disabled = disabled;
    });
    elements.hospitalizationFields.style.opacity = disabled ? "0.46" : "1";
  }

  function bindEvents() {
    populateCatalogSelects();
    applyDraftToForm(getFormDraft());
    toggleHospitalizationFields();

    elements.form.addEventListener("input", () => persistDraft(false));
    elements.form.addEventListener("change", () => persistDraft(false));
    elements.hospitalizationEnabled.addEventListener("change", () => {
      toggleHospitalizationFields();
      persistDraft(false);
    });

    elements.saveDraftButton.addEventListener("click", () => persistDraft(true));
    elements.applyPresetButton.addEventListener("click", () => {
      applyDraftToForm(deepClone(DEFAULT_FORM_STATE));
      persistDraft(true);
    });
    elements.loadTemplateButton.addEventListener("click", () => fetchCaseTemplate({ applyToForm: true, silent: false }));
    elements.saveTemplateButton.addEventListener("click", () => saveCaseTemplate());
    elements.dismissOperationFeedbackButton.addEventListener("click", () => clearOperationFeedback());
    elements.reloadCasesButton.addEventListener("click", () => loadCases());
    elements.loadLatestButton.addEventListener("click", () => runRipsAction("latest"));
    elements.generateButton.addEventListener("click", () => runRipsAction("generate"));
    elements.regenerateButton.addEventListener("click", () => runRipsAction("regen"));

    elements.downloadButton.addEventListener("click", () => {
      if (!state.selectedCase?.case_key || !state.latestResult) return;
      globalThis.location.assign(`/api/rips/cases/${encodeURIComponent(state.selectedCase.case_key)}/download`);
    });

    elements.copyPayloadButton.addEventListener("click", async () => {
      if (!state.latestResult?.payload) return;
      try {
        await navigator.clipboard.writeText(JSON.stringify(state.latestResult.payload, null, 2));
        AppToast.show("Payload copiado al portapapeles.", { type: "success", duration: 1800 });
      } catch (_) {
        AppToast.show("No se pudo copiar el payload.", { type: "error", duration: 2200 });
      }
    });

    document.getElementById("addMedicationRowButton").addEventListener("click", () => {
      const rows = collectFormState().medication_catalog;
      rows.push({
        match_key: "",
        cod_tecnologia_salud: "",
        tipo_medicamento: "01",
        unidad_medida: 1,
        forma_farmaceutica: "",
        unidad_min_dispensa: 1,
        dias_tratamiento: 1,
        concentracion_medicamento: 0,
        concepto_recaudo: "02",
      });
      renderMedicationRows(rows);
      persistDraft(false);
    });

    document.getElementById("addOtherServiceRowButton").addEventListener("click", () => {
      const rows = collectFormState().other_service_catalog;
      rows.push({
        source_section: "honorarios_medicos",
        match_key: "",
        tipo_os: "04",
        cod_tecnologia_salud: "",
        nom_tecnologia_salud: "",
      });
      renderOtherServiceRows(rows);
      persistDraft(false);
    });
  }

  bindEvents();
  loadCases();
})();
