const CASES_RENDER_HELPERS = (() => {
  const CUPS_CODE_PATTERN = /^[A-Z0-9]{6}$/i;
  const CUPS_CODE_PREFIX_PATTERN = /^\s*([A-Z0-9]{6})\s*(?:[-:–—]\s*|\s+)(.+)$/i;
  const CUPS_REVIEW_PATTERN =
    /(no se encontr[oó]|coincidencia exacta|coincidencias|pendiente|sin c[oó]digo)/i;

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

  function resolveDocumentSubtitle(document) {
    const title = normalizeText(document?.document_title);
    const typeLabel = normalizeText(document?.type_label || document?.type);
    if (!title || title.toLowerCase() === typeLabel.toLowerCase()) {
      return "";
    }
    return title;
  }

  function formatMedicationDisplay(item) {
    if (!item) return "";
    if (typeof item === "string") return normalizeText(item);

    const code = normalizeText(item.codigo || item.codigo_medicamento);
    const medication = normalizeText(item.medicamento || item.nombre || item.texto_original);
    const details = [
      normalizeText(item.dosis),
      normalizeText(item.cantidad),
      normalizeText(item.codigo_estado && item.codigo_estado !== "identificado" ? item.codigo_estado : ""),
    ].filter(Boolean);
    const description = [medication, ...details].filter(Boolean).join(" · ");
    if (!description) return "";
    return code ? `${code} · ${description}` : description;
  }

  function classifyCupsEntry(item) {
    const procedure = normalizeText(item?.procedimiento) || "-";
    const raw = normalizeText(item?.codigo_cups);
    if (!raw) {
      return { procedure, code: "Pendiente revisión", note: "Sin código generado", isReview: true };
    }

    const multiline = raw.includes("\n");
    const exactCode = CUPS_CODE_PATTERN.test(raw) ? raw.toUpperCase() : "";
    const codeWithDescription = raw.match(CUPS_CODE_PREFIX_PATTERN);
    if (multiline || CUPS_REVIEW_PATTERN.test(raw)) {
      return { procedure, code: "Pendiente revisión", note: raw, isReview: true };
    }
    if (exactCode) {
      return { procedure, code: exactCode, note: "", isReview: false };
    }
    if (codeWithDescription) {
      return {
        procedure,
        code: normalizeText(codeWithDescription[1]).toUpperCase(),
        note: normalizeText(codeWithDescription[2]),
        isReview: false,
      };
    }
    return { procedure, code: "Pendiente revisión", note: raw, isReview: true };
  }

  function buildDocumentPresentationModel(document) {
    return {
      caseNumber: normalizeText(document?.case_number),
      patientId: normalizeText(document?.patient_id),
      procedures: Array.isArray(document?.procedimientos_extraidos)
        ? document.procedimientos_extraidos.map((item) => normalizeText(item)).filter(Boolean)
        : [],
      medications: Array.isArray(document?.medicamentos_extraidos)
        ? document.medicamentos_extraidos.map((item) => formatMedicationDisplay(item)).filter(Boolean)
        : [],
      extractedDiagnoses: Array.isArray(document?.diagnosticos_extraidos)
        ? document.diagnosticos_extraidos.map((item) => normalizeText(item)).filter(Boolean)
        : [],
      cupsEntries: Array.isArray(document?.codigos_cups)
        ? document.codigos_cups.map((item) => classifyCupsEntry(item))
        : [],
    };
  }

  function toTimestamp(value) {
    const timestamp = Date.parse(String(value ?? ""));
    return Number.isNaN(timestamp) ? 0 : timestamp;
  }

  function compareSheetDocuments(left, right) {
    const timestampDelta = toTimestamp(right?.updated_at) - toTimestamp(left?.updated_at);
    if (timestampDelta !== 0) return timestampDelta;

    const typeDelta = normalizeText(left?.type_label || left?.type).localeCompare(normalizeText(right?.type_label || right?.type));
    if (typeDelta !== 0) return typeDelta;

    const nameDelta = normalizeText(left?.name).localeCompare(normalizeText(right?.name));
    if (nameDelta !== 0) return nameDelta;

    return normalizeText(left?.document_id).localeCompare(normalizeText(right?.document_id));
  }

  function buildSheetDocumentSections(groups) {
    const documents = Array.isArray(groups)
      ? groups.flatMap((group) => (Array.isArray(group?.documents) ? group.documents : []))
      : [];
    const buckets = {
      historia_clinica: [],
      factura: [],
      others: [],
    };

    documents.forEach((document) => {
      const type = normalizeText(document?.type || document?.tipo_documento || "sin_tipo");
      if (type === "historia_clinica") {
        buckets.historia_clinica.push(document);
        return;
      }
      if (type === "factura") {
        buckets.factura.push(document);
        return;
      }
      buckets.others.push(document);
    });

    return [
      {
        key: "historia_clinica",
        title: "Historia clínica",
        documents: [...buckets.historia_clinica].sort(compareSheetDocuments),
      },
      {
        key: "factura",
        title: "Factura",
        documents: [...buckets.factura].sort(compareSheetDocuments),
      },
      {
        key: "others",
        title: "Otros documentos",
        documents: [...buckets.others].sort(compareSheetDocuments),
      },
    ].filter((section) => section.documents.length > 0);
  }

  function pickPreferredSheetDocumentId(groups, preferredDocumentId = "") {
    const normalizedPreferredId = normalizeText(preferredDocumentId);
    const documents = Array.isArray(groups)
      ? groups.flatMap((group) => (Array.isArray(group?.documents) ? group.documents : []))
      : [];

    if (normalizedPreferredId && documents.some((document) => normalizeText(document?.document_id) === normalizedPreferredId)) {
      return normalizedPreferredId;
    }

    const sections = buildSheetDocumentSections(groups);
    return normalizeText(sections.flatMap((section) => section.documents)[0]?.document_id);
  }

  return {
    buildDocumentPresentationModel,
    buildSheetDocumentSections,
    classifyCupsEntry,
    formatMedicationDisplay,
    pickPreferredSheetDocumentId,
    resolveDocumentSubtitle,
  };
})();

if (typeof globalThis !== "undefined") {
  globalThis.__CASES_RENDER_HELPERS__ = CASES_RENDER_HELPERS;
}

const resolveDocumentSubtitle = CASES_RENDER_HELPERS.resolveDocumentSubtitle;

(function () {
  const appRoot = document.querySelector("[data-cases-app]");
  if (!appRoot) return;

  const RDA_ARTIFACT_TYPES = [
    { value: "patient", label: "RDA Paciente", shortLabel: "Paciente" },
    { value: "emergency", label: "RDA Urgencias", shortLabel: "Urgencias" },
  ];

  function readFiltersFromUrl() {
    const params = new URLSearchParams(globalThis.location.search);
    return {
      q: params.get("q") || "",
      epicrisis_status: params.get("epicrisis_status") || "",
      document_type: params.get("document_type") || "",
      rips_status: params.get("rips_status") || "",
      document_count_range: params.get("document_count_range") || "",
      has_epicrisis_pdf: params.get("has_epicrisis_pdf") || "",
      updated_from: params.get("updated_from") || "",
      updated_to: params.get("updated_to") || "",
      case_key: params.get("case_key") || appRoot.dataset.initialCaseKey || "",
      documento_id: params.get("documento_id") || appRoot.dataset.initialDocumentoId || "",
      panel_item: params.get("panel_item") || "",
    };
  }

  const state = {
    cases: [],
    detailPayload: null,
    selectedCaseKey: "",
    selectedDocumentId: "",
    filters: readFiltersFromUrl(),
    listAbortController: null,
    detailAbortController: null,
    documentAbortController: null,
    rdaAbortControllers: {},
    rdaRefreshTimers: {},
    rdaReviews: {},
    documentCache: {},
    searchTimer: null,
    uploadDialog: null,
    sheetOpen: false,
    sheetItemType: "",
    sheetItemKey: "",
    sheetTrigger: null,
    confirmTrigger: null,
    pendingDeletion: null,
    deletionInFlight: false,
  };

  const selectors = {
    documentType: document.querySelector("[data-cases-document-type]"),
    filterInputs: Array.from(document.querySelectorAll("[data-cases-filter]")),
    resetButton: document.querySelector("[data-cases-reset-filters]"),
    summaryFiltered: document.querySelector("[data-cases-summary-filtered]"),
    summaryDocuments: document.querySelector("[data-cases-summary-documents]"),
    summaryEpicrisis: document.querySelector("[data-cases-summary-epicrisis]"),
    summaryRips: document.querySelector("[data-cases-summary-rips]"),
    resultsMeta: document.querySelector("[data-cases-results-meta]"),
    legacyNote: document.querySelector("[data-cases-legacy-note]"),
    live: document.querySelector("[data-cases-live]"),
    count: document.querySelector("[data-cases-count]"),
    list: document.querySelector("[data-cases-list]"),
    empty: document.querySelector("[data-cases-empty]"),
    detail: document.querySelector("[data-cases-detail]"),
    detailEmpty: document.querySelector("[data-cases-detail-empty]"),
    sheet: document.querySelector("[data-cases-sheet]"),
    sheetRail: document.querySelector("[data-cases-sheet-rail]"),
    sheetContent: document.querySelector("[data-cases-sheet-content]"),
    sheetEyebrow: document.querySelector("[data-cases-sheet-eyebrow]"),
    sheetTitle: document.querySelector("[data-cases-sheet-title]"),
    sheetDescription: document.querySelector("[data-cases-sheet-description]"),
    sheetClose: document.querySelector("[data-cases-sheet-close]"),
    confirmDialog: document.querySelector("[data-cases-confirm-dialog]"),
    confirmEyebrow: document.querySelector("[data-cases-confirm-eyebrow]"),
    confirmTitle: document.querySelector("[data-cases-confirm-title]"),
    confirmDescription: document.querySelector("[data-cases-confirm-description]"),
    confirmWarning: document.querySelector("[data-cases-confirm-warning]"),
    confirmCancel: document.querySelector("[data-cases-confirm-cancel]"),
    confirmAccept: document.querySelector("[data-cases-confirm-accept]"),
  };

  function escapeHtml(value) {
    return String(value ?? "")
      .replaceAll("&", "&amp;")
      .replaceAll("<", "&lt;")
      .replaceAll(">", "&gt;")
      .replaceAll('"', "&quot;")
      .replaceAll("'", "&#39;");
  }

  function formatDate(value) {
    if (!value) return "Sin fecha";
    const parsed = new Date(value);
    if (Number.isNaN(parsed.getTime())) return "Sin fecha";
    return new Intl.DateTimeFormat("es-CO", {
      day: "2-digit",
      month: "short",
      year: "numeric",
      hour: "2-digit",
      minute: "2-digit",
    }).format(parsed);
  }

  function isAuthExpiredError(error) {
    return error?.code === "auth_expired" || error?.message === "AUTH_EXPIRED";
  }

  function closeConfirmDialog({ restoreFocus = true } = {}) {
    if (selectors.confirmDialog?.open) {
      selectors.confirmDialog.close();
    }
    if (restoreFocus && state.confirmTrigger instanceof HTMLElement) {
      state.confirmTrigger.focus();
    }
    state.confirmTrigger = null;
    state.pendingDeletion = null;
    state.deletionInFlight = false;
    if (selectors.confirmAccept) {
      selectors.confirmAccept.disabled = false;
      selectors.confirmAccept.textContent = "Eliminar";
    }
  }

  function openConfirmDialog(config, { trigger = null } = {}) {
    if (!selectors.confirmDialog || !selectors.confirmTitle || !selectors.confirmDescription) return;
    state.pendingDeletion = config;
    state.deletionInFlight = false;
    state.confirmTrigger = trigger instanceof HTMLElement ? trigger : null;

    selectors.confirmEyebrow.textContent =
      config.kind === "case" ? "Eliminar caso completo" : "Eliminar documento";
    selectors.confirmTitle.textContent =
      config.kind === "case" ? `Eliminar ${config.caseLabel}` : `Eliminar ${config.documentName}`;
    selectors.confirmDescription.textContent = config.description;
    selectors.confirmWarning.textContent = config.warning || "";
    selectors.confirmWarning.classList.toggle("ui-hidden", !config.warning);
    selectors.confirmAccept.textContent = config.kind === "case" ? "Eliminar caso" : "Eliminar documento";
    selectors.confirmAccept.disabled = false;
    selectors.confirmDialog.showModal();
  }

  function humanizeDocumentType(value) {
    const normalized = String(value || "sin_tipo").replaceAll("_", " ").trim();
    if (!normalized) return "Documento";
    return normalized.charAt(0).toUpperCase() + normalized.slice(1);
  }

  function buildPanelItemValue(artifactType) {
    return `rda:${artifactType}`;
  }

  function parsePanelItem(value) {
    const normalized = String(value || "").trim();
    if (!normalized.startsWith("rda:")) return null;
    const artifactType = normalized.slice(4);
    if (!RDA_ARTIFACT_TYPES.some((item) => item.value === artifactType)) return null;
    return { type: "rda", key: artifactType };
  }

  function getRequestedSheetItem() {
    const panelItem = parsePanelItem(state.filters.panel_item);
    if (panelItem) return panelItem;
    const documentId = String(state.filters.documento_id || "").trim();
    if (documentId) return { type: "document", key: documentId };
    return null;
  }

  function findDocumentSummary(documentId) {
    const groups = Array.isArray(state.detailPayload?.document_groups) ? state.detailPayload.document_groups : [];
    for (const group of groups) {
      const document = (group.documents || []).find((item) => item.document_id === documentId);
      if (document) return document;
    }
    return null;
  }

  function findCaseSummary(caseKey) {
    return state.cases.find((item) => item.case_key === caseKey) || null;
  }

  function normalizeRouteState() {
    state.filters.case_key = String(state.selectedCaseKey || state.filters.case_key || "").trim();
    state.filters.documento_id =
      state.sheetOpen && state.sheetItemType === "document" ? String(state.sheetItemKey || "").trim() : "";
    state.filters.panel_item =
      state.sheetOpen && state.sheetItemType === "rda" ? buildPanelItemValue(state.sheetItemKey) : "";
  }

  function syncInputsFromState() {
    selectors.filterInputs.forEach((input) => {
      const key = input.dataset.casesFilter;
      if (!key) return;
      input.value = state.filters[key] || "";
    });
  }

  function syncUrl({ push = false } = {}) {
    normalizeRouteState();
    const params = new URLSearchParams();
    Object.entries(state.filters).forEach(([key, value]) => {
      const normalized = String(value || "").trim();
      if (normalized) params.set(key, normalized);
    });
    const query = params.toString();
    const nextUrl = globalThis.location.pathname + (query ? `?${query}` : "");
    const method = push ? "pushState" : "replaceState";
    globalThis.history[method]({}, "", nextUrl);
  }

  function setLiveMessage(message) {
    selectors.live && (selectors.live.textContent = message);
  }

  function buildPill(label, tone = "info") {
    if (!label) return "";
    return `<span class="cases-pill cases-pill--${escapeHtml(tone)}">${escapeHtml(label)}</span>`;
  }

  function buildCodePill(label, tone) {
    return `<span class="cases-rda-code cases-rda-code--${escapeHtml(tone)}">${escapeHtml(label)}</span>`;
  }

  function formatJson(value) {
    try {
      return JSON.stringify(value, null, 2);
    } catch {
      return String(value ?? "");
    }
  }

  function flattenDocuments(groups) {
    return groups.flatMap((group) => group.documents || []);
  }

  function getRdaTypeMeta(artifactType) {
    return RDA_ARTIFACT_TYPES.find((item) => item.value === artifactType) || {
      value: artifactType,
      label: artifactType,
      shortLabel: artifactType,
    };
  }

  function getRdaStatusMeta(review) {
    const status = review?.status?.status || "";
    if (status === "completed") return { label: "Completado", tone: "success" };
    if (status === "processing") return { label: "Procesando", tone: "info" };
    if (status === "queued") return { label: "En cola", tone: "info" };
    if (status === "failed") return { label: "Falló", tone: "error" };
    if (review?.artifact) return { label: "Disponible", tone: "success" };
    return { label: "Sin generar", tone: "neutral" };
  }

  function getRdaValidationMeta(review) {
    if (!review?.artifact || !review?.validation) {
      return { label: "Sin validación", tone: "neutral" };
    }
    if (!review.validation.is_valid) {
      return { label: `${review.validation.error_count} error(es)`, tone: "error" };
    }
    if (review.validation.warning_count > 0) {
      return { label: `${review.validation.warning_count} advertencia(s)`, tone: "warning" };
    }
    return { label: "Válido", tone: "success" };
  }

  function getFindingTone(finding) {
    return finding?.severity === "error" ? "error" : "warning";
  }

  function clearRdaTimers() {
    Object.values(state.rdaRefreshTimers).forEach((timerId) => {
      globalThis.clearTimeout(timerId);
    });
    state.rdaRefreshTimers = {};
  }

  function abortRdaRequests() {
    Object.values(state.rdaAbortControllers).forEach((controller) => {
      controller?.abort?.();
    });
    state.rdaAbortControllers = {};
  }

  function buildActionLinks(actions) {
    if (!Array.isArray(actions) || actions.length === 0) return "";
    return actions
      .map(
        (action) =>
          `<a class="cases-action-link cases-action-link--${escapeHtml(action.variant || "secondary")}" href="${escapeHtml(
            action.href || "#"
          )}">${escapeHtml(action.label || "Abrir")}</a>`
      )
      .join("");
  }

  function renderSummary(summary) {
    const filteredCases = Number(summary.filtered_cases || 0);
    const totalCases = Number(summary.total_cases || 0);
    const filteredDocuments = Number(summary.filtered_documents || 0);
    selectors.summaryFiltered.textContent = String(filteredCases);
    selectors.summaryDocuments.textContent = String(filteredDocuments);
    selectors.summaryEpicrisis.textContent = String(summary.completed_epicrisis || 0);
    selectors.summaryRips.textContent = String(summary.rips_ready || 0);
    selectors.count.textContent = String(filteredCases);
    selectors.resultsMeta.textContent = `${filteredCases} de ${totalCases} casos visibles · ${filteredDocuments} documentos en la bandeja actual.`;

    const legacyExcluded = Number(summary.legacy_excluded_count || 0);
    selectors.legacyNote.classList.toggle("ui-hidden", legacyExcluded === 0);
    selectors.legacyNote.textContent =
      legacyExcluded > 0
        ? `${legacyExcluded} agrupaciones legacy sin case_key quedaron fuera de esta bandeja.`
        : "";
  }

  function renderDocumentTypeOptions(availableTypes) {
    if (!selectors.documentType) return;
    const currentValue = state.filters.document_type || "";
    selectors.documentType.innerHTML = [
      '<option value="">Todos</option>',
      ...availableTypes.map(
        (type) =>
          `<option value="${escapeHtml(type)}"${type === currentValue ? " selected" : ""}>${escapeHtml(
            String(type).replaceAll("_", " ")
          )}</option>`
      ),
    ].join("");
  }

  function renderCases(cases) {
    state.cases = Array.isArray(cases) ? cases : [];
    selectors.empty.classList.toggle("ui-hidden", state.cases.length > 0);
    selectors.list.classList.toggle("ui-hidden", state.cases.length === 0);
    selectors.list.innerHTML = state.cases
      .map((item, index) => {
        const selected = item.case_key === state.selectedCaseKey;
        const panelId = `cases-accordion-panel-${index}`;
        const caseLabel = item.case_number || item.case_key || "Caso";
        const ripsLabel = item.rips?.label || "Sin RIPS";
        const ripsTone =
          item.rips?.status === "rips_listo"
            ? "success"
            : item.rips?.status === "rips_con_observaciones"
              ? "warning"
              : "neutral";
        return `
          <article class="cases-accordion__item${selected ? " is-selected" : ""}">
            <h3 class="cases-accordion__heading">
              <button
                type="button"
                class="cases-accordion__trigger"
                data-case-select="${escapeHtml(item.case_key)}"
                aria-expanded="${selected ? "true" : "false"}"
                aria-controls="${panelId}"
              >
                <span class="cases-accordion__identity">
                  <strong>${escapeHtml(caseLabel)}</strong>
                  <span>${escapeHtml(item.patient_name || "Paciente sin nombre")}</span>
                </span>
                <span class="cases-accordion__meta">
                  <span>${escapeHtml(item.patient_id || "Sin cédula")}</span>
                  <span>${escapeHtml(String(item.document_count || 0))} documento(s)</span>
                </span>
              </button>
            </h3>
            <div id="${panelId}" class="cases-accordion__panel${selected ? "" : " ui-hidden"}">
              <div class="cases-accordion__pills">
                ${buildPill(item.epicrisis_status || "pendiente", item.epicrisis_status === "completado" ? "success" : "info")}
                ${buildPill(ripsLabel, ripsTone)}
              </div>
              <div class="cases-accordion__tags">
                ${(item.document_types || [])
                  .slice(0, 4)
                  .map((tag) => `<span class="cases-tag">${escapeHtml(String(tag).replaceAll("_", " "))}</span>`)
                  .join("")}
              </div>
              <span class="cases-accordion__timestamp">Actualizado ${escapeHtml(formatDate(item.updated_at))}</span>
            </div>
          </article>
        `;
      })
      .join("");
  }

  function renderSheetHeader() {
    if (!selectors.sheetTitle || !selectors.sheetEyebrow || !selectors.sheetDescription) return;
    const caseItem = state.detailPayload?.case || {};
    const patientLabel = caseItem.patient_name || "Paciente sin nombre";
    const caseLabel = caseItem.case_number || caseItem.case_key || "Caso";

    if (state.sheetItemType === "document") {
      const summary = findDocumentSummary(state.sheetItemKey) || {};
      const document = state.documentCache[state.sheetItemKey] || {};
      selectors.sheetEyebrow.textContent = summary.type_label || humanizeDocumentType(document.tipo_documento);
      const subtitle = resolveDocumentSubtitle(summary);
      if (subtitle) {
        selectors.sheetEyebrow.textContent = `${selectors.sheetEyebrow.textContent} · ${subtitle}`;
      }
      selectors.sheetTitle.textContent = summary.name || document.nombre_archivo || "Documento";
      selectors.sheetDescription.textContent = `${patientLabel} · ${caseLabel} · ${formatDate(
        summary.updated_at || document.fecha_analisis
      )}`;
      return;
    }

    if (state.sheetItemType === "rda") {
      const rdaMeta = getRdaTypeMeta(state.sheetItemKey);
      const review = state.rdaReviews[state.sheetItemKey] || null;
      const statusMeta = getRdaStatusMeta(review);
      selectors.sheetEyebrow.textContent = "Artefacto operativo";
      selectors.sheetTitle.textContent = rdaMeta.label;
      selectors.sheetDescription.textContent = `${patientLabel} · ${caseLabel} · ${statusMeta.label}`;
      return;
    }

    selectors.sheetEyebrow.textContent = "Lectura documental";
    selectors.sheetTitle.textContent = "Visor del caso";
    selectors.sheetDescription.textContent =
      "Navega entre documentos clínicos y artefactos operativos sin salir de la bandeja.";
  }

  function renderSheetRail() {
    if (!selectors.sheetRail) return;
    if (!state.detailPayload) {
      selectors.sheetRail.innerHTML = "";
      return;
    }

    const groups = Array.isArray(state.detailPayload.document_groups) ? state.detailPayload.document_groups : [];
    const sheetSections = CASES_RENDER_HELPERS.buildSheetDocumentSections(groups);
    selectors.sheetRail.innerHTML = `
      ${sheetSections
        .map(
          (section) => `
            <div class="cases-sheet__rail-section">
              <div class="cases-sheet__rail-heading">
                <p class="cases-sheet__rail-eyebrow">${escapeHtml(section.title || "Documentos")}</p>
                <span class="cases-pane__count">${escapeHtml(String(section.documents.length))}</span>
              </div>
              <div class="cases-sheet__rail-list">
                ${(section.documents || [])
                  .map(
                    (document) => `
                      <button
                        type="button"
                        class="cases-sheet__nav-item"
                        data-sheet-item-type="document"
                        data-sheet-item-key="${escapeHtml(document.document_id || "")}"
                      >
                        <span class="cases-sheet__nav-copy">
                          <strong>${escapeHtml(document.name || "Documento")}</strong>
                          <span>${escapeHtml(resolveDocumentSubtitle(document) || formatDate(document.updated_at))}</span>
                        </span>
                        <span class="cases-sheet__nav-tag">${escapeHtml(document.type_label || document.type || "")}</span>
                      </button>
                    `
                  )
                  .join("")}
              </div>
            </div>
          `
        )
        .join("")}
      <div class="cases-sheet__rail-section">
        <p class="cases-sheet__rail-eyebrow">Artefactos</p>
        <div class="cases-sheet__rail-list">
          ${RDA_ARTIFACT_TYPES.map((item) => {
            const review = state.rdaReviews[item.value] || null;
            const statusMeta = getRdaStatusMeta(review);
            return `
              <button
                type="button"
                class="cases-sheet__nav-item"
                data-sheet-item-type="rda"
                data-sheet-item-key="${escapeHtml(item.value)}"
              >
                <span class="cases-sheet__nav-copy">
                  <strong>${escapeHtml(item.label)}</strong>
                  <span>${escapeHtml(statusMeta.label)}</span>
                </span>
                ${buildPill(statusMeta.label, statusMeta.tone)}
              </button>
            `;
          }).join("")}
        </div>
      </div>
    `;
    updateSheetNavStates();
  }

  function renderSheetPlaceholder(title, copy) {
    if (!selectors.sheetContent) return;
    selectors.sheetContent.innerHTML = `
      <div class="cases-sheet__empty">
        <h3>${escapeHtml(title)}</h3>
        <p>${escapeHtml(copy)}</p>
      </div>
    `;
  }

  function buildDocumentContent(document) {
    const presentation = CASES_RENDER_HELPERS.buildDocumentPresentationModel(document);
    const analisisHtml = document.analisis_html || document.analisis || "<p>No hay análisis disponible.</p>";
    const cieRows = Array.isArray(document.codigos_cie10)
      ? document.codigos_cie10
          .map((item) => {
            const diagnostico = escapeHtml(item.diagnostico || item.descripcion || "Sin diagnóstico");
            const codigo = escapeHtml(item.codigo_asignado || item.codigo || "Pendiente");
            const descripcion = escapeHtml(item.descripcion || "-");
            return `<tr><td>${diagnostico}</td><td><strong>${codigo}</strong></td><td>${descripcion}</td></tr>`;
          })
          .join("")
      : "";
    const cupsRows = presentation.cupsEntries
      .map(
        (item) =>
          `<tr><td>${escapeHtml(item.procedure)}</td><td><strong>${escapeHtml(
            item.code
          )}</strong></td><td>${escapeHtml(item.note || "-")}</td></tr>`
      )
      .join("");
    const procedimientosExtraidos = presentation.procedures
      .map((item) => `<li>${escapeHtml(item)}</li>`)
      .join("");
    const medicamentosExtraidos = presentation.medications
      .map((item) => `<li>${escapeHtml(item)}</li>`)
      .join("");
    const diagnosticosExtraidos = presentation.extractedDiagnoses
      .map((item) => `<li>${escapeHtml(item)}</li>`)
          .join("")

    return `
      <article class="cases-sheet__card cases-sheet__card--hero">
        <div class="cases-sheet__card-head">
          <div>
            <p class="cases-pane__eyebrow">${escapeHtml(humanizeDocumentType(document.tipo_documento))}</p>
            <h3>${escapeHtml(document.nombre_archivo || "Documento")}</h3>
          </div>
          ${buildPill(formatDate(document.fecha_analisis), "neutral")}
        </div>
        <div class="cases-sheet__meta-grid">
          <div><span>Paciente</span><strong>${escapeHtml(document.nombre_paciente || "No especificado")}</strong></div>
          <div><span>Identificación</span><strong>${escapeHtml(presentation.patientId || "No especificada")}</strong></div>
          <div><span>Caso</span><strong>${escapeHtml(presentation.caseNumber || "Sin caso")}</strong></div>
          <div><span>Usuario</span><strong>${escapeHtml(document.usuario || "-")}</strong></div>
          <div><span>Tipo</span><strong>${escapeHtml(humanizeDocumentType(document.tipo_documento))}</strong></div>
          <div><span>Documento</span><strong>${escapeHtml(document._id || "-")}</strong></div>
        </div>
      </article>

      <article class="cases-sheet__card">
        <div class="cases-sheet__section-head">
          <div>
            <p class="cases-pane__eyebrow">Lectura estructurada</p>
            <h3>Análisis clínico</h3>
          </div>
        </div>
        <div class="cases-document-viewer__analysis">${analisisHtml}</div>
      </article>

      ${
        cieRows
          ? `
        <article class="cases-sheet__card">
          <div class="cases-sheet__section-head">
            <div>
              <p class="cases-pane__eyebrow">Codificación</p>
              <h3>CIE-10</h3>
            </div>
          </div>
          <div class="ui-table-wrap">
            <table>
              <thead>
                <tr>
                  <th>Diagnóstico</th>
                  <th>Código</th>
                  <th>Descripción</th>
                </tr>
              </thead>
              <tbody>${cieRows}</tbody>
            </table>
          </div>
        </article>
      `
          : ""
      }

      ${
        procedimientosExtraidos
          ? `
        <article class="cases-sheet__card">
          <div class="cases-sheet__section-head">
            <div>
              <p class="cases-pane__eyebrow">Extracción</p>
              <h3>Procedimientos extraídos</h3>
            </div>
          </div>
          <ul class="ui-list">${procedimientosExtraidos}</ul>
        </article>
      `
          : ""
      }

      ${
        medicamentosExtraidos
          ? `
        <article class="cases-sheet__card">
          <div class="cases-sheet__section-head">
            <div>
              <p class="cases-pane__eyebrow">Extracción</p>
              <h3>Medicamentos extraídos</h3>
            </div>
          </div>
          <ul class="ui-list">${medicamentosExtraidos}</ul>
        </article>
      `
          : ""
      }

      ${
        diagnosticosExtraidos
          ? `
        <article class="cases-sheet__card">
          <div class="cases-sheet__section-head">
            <div>
              <p class="cases-pane__eyebrow">Extracción</p>
              <h3>Diagnósticos detectados</h3>
            </div>
          </div>
          <ul class="ui-list">${diagnosticosExtraidos}</ul>
        </article>
      `
          : ""
      }

      ${
        cupsRows
          ? `
        <article class="cases-sheet__card">
          <div class="cases-sheet__section-head">
            <div>
              <p class="cases-pane__eyebrow">Codificación</p>
              <h3>CUPS</h3>
            </div>
          </div>
          <div class="ui-table-wrap">
            <table>
              <thead>
                <tr>
                  <th>Procedimiento</th>
                  <th>Código</th>
                  <th>Nota</th>
                </tr>
              </thead>
              <tbody>${cupsRows}</tbody>
            </table>
          </div>
        </article>
      `
          : ""
      }
    `;
  }

  function buildRdaSheetContent(artifactType, review) {
    const rdaMeta = getRdaTypeMeta(artifactType);
    const statusMeta = getRdaStatusMeta(review);
    const validationMeta = getRdaValidationMeta(review);
    const artifact = review?.artifact || null;
    const status = review?.status || null;
    const validation = review?.validation || null;
    const findingsList = Array.isArray(validation?.findings) ? validation.findings : [];
    const missingFields = Array.isArray(artifact?.missing_fields) ? artifact.missing_fields : [];
    const isPending = status?.status === "queued" || status?.status === "processing";
    const canRegenerate = Boolean(artifact) && !isPending;
    const actionBar = `
      <div class="cases-sheet__toolbar" role="toolbar" aria-label="Acciones del artefacto RDA">
        <button
          type="button"
          class="ui-button ui-button--accent"
          data-sheet-rda-generate="${escapeHtml(artifactType)}"
          data-sheet-rda-generate-force="false"
          ${isPending ? "disabled" : ""}
        >
          Generar
        </button>
        <button
          type="button"
          class="ui-button ui-button--secondary"
          data-sheet-rda-generate="${escapeHtml(artifactType)}"
          data-sheet-rda-generate-force="true"
          ${canRegenerate ? "" : "disabled"}
        >
          Regenerar
        </button>
        <button
          type="button"
          class="ui-button ui-button--ghost"
          data-sheet-rda-refresh="${escapeHtml(artifactType)}"
        >
          Refrescar
        </button>
      </div>
    `;

    if (!artifact) {
      const pendingCopy =
        status?.status === "queued" || status?.status === "processing"
          ? "El artefacto está en preparación. Usa refrescar para consultar el resultado."
          : "Todavía no existe un artefacto generado para este tipo.";
      return `
        <article class="cases-sheet__card cases-sheet__card--hero">
          <div class="cases-sheet__card-head">
            <div>
              <p class="cases-pane__eyebrow">Artefacto operativo</p>
              <h3>${escapeHtml(rdaMeta.label)}</h3>
            </div>
            <div class="cases-sheet__pill-row">
              ${buildPill(statusMeta.label, statusMeta.tone)}
              ${buildPill(validationMeta.label, validationMeta.tone)}
            </div>
          </div>
          ${actionBar}
          <p class="cases-sheet__lead">${escapeHtml(pendingCopy)}</p>
        </article>
      `;
    }

    return `
      <article class="cases-sheet__card cases-sheet__card--hero">
        <div class="cases-sheet__card-head">
          <div>
            <p class="cases-pane__eyebrow">Artefacto operativo</p>
            <h3>${escapeHtml(rdaMeta.label)}</h3>
          </div>
          <div class="cases-sheet__pill-row">
            ${buildPill(statusMeta.label, statusMeta.tone)}
            ${buildPill(validationMeta.label, validationMeta.tone)}
          </div>
        </div>
        <div class="cases-sheet__meta-grid">
          <div><span>Job</span><strong>${escapeHtml(status?.job_id || "Sin job")}</strong></div>
          <div><span>Versión</span><strong>${escapeHtml(String(artifact.version ?? status?.resolved_version ?? "-"))}</strong></div>
          <div><span>Completitud</span><strong>${escapeHtml(artifact.completeness_status || "-")}</strong></div>
          <div><span>Schema/Mapper</span><strong>${escapeHtml(
            `${artifact.schema_version || "-"} · ${artifact.mapper_version || "-"}`
          )}</strong></div>
          <div><span>Origen</span><strong>${escapeHtml(artifact.source || status?.source || "-")}</strong></div>
          <div><span>Actualizado</span><strong>${escapeHtml(formatDate(status?.updated_at || ""))}</strong></div>
        </div>
        ${
          missingFields.length
            ? `<div class="cases-rda-tags">${missingFields
                .map((item) => `<span class="cases-tag">${escapeHtml(item)}</span>`)
                .join("")}</div>`
            : ""
        }
        ${actionBar}
      </article>

      <article class="cases-sheet__card">
        <div class="cases-sheet__section-head">
          <div>
            <p class="cases-pane__eyebrow">Validación FHIR</p>
            <h3>Resumen de consistencia</h3>
          </div>
        </div>
        <div class="cases-rda-summary">
          <p><strong>Payload:</strong> ${escapeHtml(
            String(artifact.payload?.summary_type || artifact.artifact_type || "-")
          )}</p>
          <p><strong>Estado:</strong> ${escapeHtml(validationMeta.label)}</p>
        </div>
      </article>

      <article class="cases-sheet__card">
        <div class="cases-sheet__section-head">
          <div>
            <p class="cases-pane__eyebrow">Hallazgos</p>
            <h3>Errores y advertencias</h3>
          </div>
        </div>
        ${
          findingsList.length === 0
            ? `
          <div class="cases-rda-findings__empty">
            <p>No hay hallazgos estructurales registrados para este artefacto.</p>
          </div>
        `
            : findingsList
                .map(
                  (item) => `
              <article class="cases-rda-finding cases-rda-finding--${escapeHtml(getFindingTone(item))}">
                <div class="cases-rda-finding__header">
                  ${buildCodePill(item.rule_code || "-", getFindingTone(item))}
                  ${buildPill(item.severity === "error" ? "Error" : "Advertencia", getFindingTone(item))}
                </div>
                <p>${escapeHtml(item.message || "Hallazgo sin descripción.")}</p>
                <dl class="cases-rda-finding__meta">
                  <div><dt>Recurso</dt><dd>${escapeHtml(item.resource_type || "-")}</dd></div>
                  <div><dt>Path</dt><dd>${escapeHtml(item.resource_path || "-")}</dd></div>
                  <div><dt>Observado</dt><dd>${escapeHtml(formatJson(item.observed_value))}</dd></div>
                </dl>
              </article>
            `
                )
                .join("")
        }
      </article>

      <details class="cases-sheet__card cases-rda-card__json">
        <summary>Ver JSON del artefacto</summary>
        <pre>${escapeHtml(formatJson(artifact.payload || {}))}</pre>
      </details>
    `;
  }

  function renderSheetContent() {
    if (!selectors.sheetContent) return;
    renderSheetHeader();

    if (!state.sheetOpen || !state.sheetItemType || !state.sheetItemKey) {
      renderSheetPlaceholder(
        "Selecciona un ítem",
        "Abre un documento clínico o un artefacto operativo para revisar su contenido aquí."
      );
      return;
    }

    if (state.sheetItemType === "document") {
      const document = state.documentCache[state.sheetItemKey];
      if (!document) {
        renderSheetPlaceholder("Cargando documento", "Preparando el análisis del documento seleccionado.");
        return;
      }
      selectors.sheetContent.innerHTML = buildDocumentContent(document);
      return;
    }

    if (state.sheetItemType === "rda") {
      const review = state.rdaReviews[state.sheetItemKey] || null;
      if (!review) {
        renderSheetPlaceholder("Consultando artefacto", "Preparando el estado y la validación del artefacto RDA.");
        return;
      }
      selectors.sheetContent.innerHTML = buildRdaSheetContent(state.sheetItemKey, review);
      return;
    }

    renderSheetPlaceholder(
      "Selección no soportada",
      "El item solicitado no se pudo representar dentro del visor documental."
    );
  }

  function renderRdaCardLoading(artifactType, message = "Consultando artefacto RDA…") {
    const card = selectors.detail?.querySelector(`[data-rda-card="${artifactType}"]`);
    if (!card) return;
    const summary = card.querySelector("[data-rda-summary]");
    const findings = card.querySelector("[data-rda-findings]");
    const payload = card.querySelector("[data-rda-json]");
    const payloadWrap = card.querySelector("[data-rda-json-wrap]");
    summary.innerHTML = `<div class="cases-loading"><p>${escapeHtml(message)}</p></div>`;
    findings.innerHTML = "";
    payload.textContent = "";
    payloadWrap.classList.add("ui-hidden");
  }

  function renderRdaCard(artifactType, review) {
    const card = selectors.detail?.querySelector(`[data-rda-card="${artifactType}"]`);
    if (!card) return;

    const statusMeta = getRdaStatusMeta(review);
    const validationMeta = getRdaValidationMeta(review);
    const statusPill = card.querySelector("[data-rda-status-pill]");
    const validationPill = card.querySelector("[data-rda-validation-pill]");
    const meta = card.querySelector("[data-rda-meta]");
    const summary = card.querySelector("[data-rda-summary]");
    const findings = card.querySelector("[data-rda-findings]");
    const payload = card.querySelector("[data-rda-json]");
    const payloadWrap = card.querySelector("[data-rda-json-wrap]");

    statusPill.innerHTML = buildPill(statusMeta.label, statusMeta.tone);
    validationPill.innerHTML = buildPill(validationMeta.label, validationMeta.tone);

    const artifact = review?.artifact || null;
    const status = review?.status || null;
    const validation = review?.validation || null;
    const findingsList = Array.isArray(validation?.findings) ? validation.findings : [];
    const missingFields = Array.isArray(artifact?.missing_fields) ? artifact.missing_fields : [];

    meta.innerHTML = `
      <div><dt>Job</dt><dd>${escapeHtml(status?.job_id || "Sin job")}</dd></div>
      <div><dt>Versión</dt><dd>${escapeHtml(String(artifact?.version ?? status?.resolved_version ?? "-"))}</dd></div>
      <div><dt>Completitud</dt><dd>${escapeHtml(artifact?.completeness_status || "-")}</dd></div>
      <div><dt>Schema/Mapper</dt><dd>${escapeHtml(
        artifact ? `${artifact.schema_version} · ${artifact.mapper_version}` : "-"
      )}</dd></div>
      <div><dt>Origen</dt><dd>${escapeHtml(artifact?.source || status?.source || "-")}</dd></div>
      <div><dt>Actualizado</dt><dd>${escapeHtml(formatDate(status?.updated_at || ""))}</dd></div>
    `;

    if (!artifact) {
      const pendingCopy =
        status?.status === "queued" || status?.status === "processing"
          ? "El artefacto está en preparación. Usa refrescar para consultar el resultado."
          : "Todavía no existe un artefacto generado para este tipo.";
      summary.innerHTML = `
        <div class="cases-empty">
          <h3>${escapeHtml(getRdaTypeMeta(artifactType).label)}</h3>
          <p>${escapeHtml(pendingCopy)}</p>
        </div>
      `;
      findings.innerHTML = "";
      payload.textContent = "";
      payloadWrap.classList.add("ui-hidden");
      updateRdaOpenStates();
      if (state.sheetOpen && state.sheetItemType === "rda" && state.sheetItemKey === artifactType) {
        renderSheetContent();
        renderSheetRail();
      }
      return;
    }

    const summaryParts = [
      `<p><strong>Payload:</strong> ${escapeHtml(String(artifact.payload?.summary_type || artifact.artifact_type || "-"))}</p>`,
      `<p><strong>Validación:</strong> ${escapeHtml(
        validation?.is_valid
          ? validation.warning_count > 0
            ? `válido con ${validation.warning_count} advertencia(s)`
            : "válido sin hallazgos"
          : `${validation?.error_count || 0} error(es) y ${validation?.warning_count || 0} advertencia(s)`
      )}</p>`,
    ];
    if (missingFields.length > 0) {
      summaryParts.push(`
        <div class="cases-rda-tags">
          ${missingFields.map((item) => `<span class="cases-tag">${escapeHtml(item)}</span>`).join("")}
        </div>
      `);
    }
    summary.innerHTML = `<div class="cases-rda-summary">${summaryParts.join("")}</div>`;

    if (findingsList.length === 0) {
      findings.innerHTML = `
        <div class="cases-rda-findings__empty">
          <p>No hay hallazgos estructurales registrados para este artefacto.</p>
        </div>
      `;
    } else {
      findings.innerHTML = findingsList
        .map(
          (item) => `
            <article class="cases-rda-finding cases-rda-finding--${escapeHtml(getFindingTone(item))}">
              <div class="cases-rda-finding__header">
                ${buildCodePill(item.rule_code || "-", getFindingTone(item))}
                ${buildPill(item.severity === "error" ? "Error" : "Advertencia", getFindingTone(item))}
              </div>
              <p>${escapeHtml(item.message || "Hallazgo sin descripción.")}</p>
              <dl class="cases-rda-finding__meta">
                <div><dt>Recurso</dt><dd>${escapeHtml(item.resource_type || "-")}</dd></div>
                <div><dt>Path</dt><dd>${escapeHtml(item.resource_path || "-")}</dd></div>
                <div><dt>Observado</dt><dd>${escapeHtml(formatJson(item.observed_value))}</dd></div>
              </dl>
            </article>
          `
        )
        .join("");
    }

    payload.textContent = formatJson(artifact.payload || {});
    payloadWrap.classList.remove("ui-hidden");
    updateRdaOpenStates();
    if (state.sheetOpen && state.sheetItemType === "rda" && state.sheetItemKey === artifactType) {
      renderSheetContent();
      renderSheetRail();
    }
  }

  function renderRdaCardError(artifactType, message) {
    const card = selectors.detail?.querySelector(`[data-rda-card="${artifactType}"]`);
    if (!card) return;
    const summary = card.querySelector("[data-rda-summary]");
    const findings = card.querySelector("[data-rda-findings]");
    const payloadWrap = card.querySelector("[data-rda-json-wrap]");
    summary.innerHTML = `
      <div class="cases-empty">
        <h3>No fue posible cargar ${escapeHtml(artifactType)}</h3>
        <p>${escapeHtml(message)}</p>
      </div>
    `;
    findings.innerHTML = "";
    payloadWrap.classList.add("ui-hidden");
    if (state.sheetOpen && state.sheetItemType === "rda" && state.sheetItemKey === artifactType) {
      renderSheetPlaceholder("No fue posible abrir el artefacto", message);
    }
  }

  function updateDocumentButtonStates() {
    selectors.detail?.querySelectorAll("[data-document-select]").forEach((button) => {
      const selected = button.dataset.documentSelect === state.selectedDocumentId;
      button.classList.toggle("is-selected", selected);
      button.closest(".cases-document-card")?.classList.toggle("is-selected", selected);
      button.setAttribute("aria-pressed", selected ? "true" : "false");
      const status = button.querySelector("[data-document-status]");
      if (status) {
        const isActiveSheetItem =
          state.sheetOpen &&
          state.sheetItemType === "document" &&
          button.dataset.documentSelect === state.sheetItemKey;
        status.textContent = isActiveSheetItem ? "En sheet" : selected ? "Seleccionado" : "Abrir";
      }
    });
  }

  function updateRdaOpenStates() {
    selectors.detail?.querySelectorAll("[data-rda-open]").forEach((button) => {
      const selected = state.sheetOpen && state.sheetItemType === "rda" && button.dataset.rdaOpen === state.sheetItemKey;
      button.classList.toggle("is-active", selected);
      button.textContent = selected ? "En sheet" : "Abrir panel";
    });
    selectors.detail?.querySelectorAll("[data-rda-card]").forEach((card) => {
      const selected = state.sheetOpen && state.sheetItemType === "rda" && card.dataset.rdaCard === state.sheetItemKey;
      card.classList.toggle("is-active", selected);
    });
  }

  function updateSheetNavStates() {
    selectors.sheetRail?.querySelectorAll("[data-sheet-item-type]").forEach((button) => {
      const active =
        state.sheetOpen &&
        button.dataset.sheetItemType === state.sheetItemType &&
        button.dataset.sheetItemKey === state.sheetItemKey;
      button.classList.toggle("is-active", active);
      button.setAttribute("aria-current", active ? "true" : "false");
    });
  }

  function updateSelectionStates() {
    updateDocumentButtonStates();
    updateRdaOpenStates();
    updateSheetNavStates();
  }

  function rememberSheetTrigger(trigger) {
    if (trigger instanceof HTMLElement) {
      state.sheetTrigger = trigger;
    }
  }

  function restoreSheetFocus() {
    if (state.sheetTrigger instanceof HTMLElement) {
      state.sheetTrigger.focus();
    }
    state.sheetTrigger = null;
  }

  function ensureSheetVisible() {
    if (!selectors.sheet || selectors.sheet.open) return;
    selectors.sheet.showModal();
  }

  function closeSheet({ push = false, restoreFocus = true } = {}) {
    if (!state.sheetOpen && !selectors.sheet?.open) return;
    state.sheetOpen = false;
    state.sheetItemType = "";
    state.sheetItemKey = "";
    if (selectors.sheet?.open) {
      selectors.sheet.close();
    }
    renderSheetContent();
    updateSelectionStates();
    syncUrl({ push });
    if (restoreFocus) {
      restoreSheetFocus();
    }
  }

  function renderDetail(payload) {
    state.detailPayload = payload;
    const caseItem = payload.case || {};
    const groups = Array.isArray(payload.document_groups) ? payload.document_groups : [];
    const allDocuments = flattenDocuments(groups);
    const preferredDocumentId = String(state.filters.documento_id || state.selectedDocumentId || "").trim();
    const nextDocumentId = CASES_RENDER_HELPERS.pickPreferredSheetDocumentId(groups, preferredDocumentId);

    state.selectedDocumentId = nextDocumentId;

    const caseRipsTone =
      caseItem.rips?.status === "rips_listo"
        ? "success"
        : caseItem.rips?.status === "rips_con_observaciones"
          ? "warning"
          : "neutral";
    const caseActions = Array.isArray(caseItem.actions)
      ? caseItem.actions.filter((action) => action.label !== "Ver detalle")
      : [];

    selectors.detailEmpty.classList.add("ui-hidden");
    selectors.detail.classList.remove("ui-hidden");
    selectors.detail.innerHTML = `
      <header class="cases-detail__hero">
        <div class="cases-detail__hero-copy">
          <p class="cases-pane__eyebrow">Case key activo</p>
          <h3>${escapeHtml(caseItem.case_number || caseItem.case_key || "Caso")}</h3>
          <p>${escapeHtml(caseItem.patient_name || "Paciente sin nombre")} · ${escapeHtml(
            caseItem.patient_id || "Sin cédula"
          )}</p>
          <div class="cases-detail__hero-pills">
            ${buildPill(caseItem.epicrisis_status || "pendiente", caseItem.epicrisis_status === "completado" ? "success" : "info")}
            ${buildPill(caseItem.rips?.label || "Sin RIPS", caseRipsTone)}
            <span class="cases-tag">${escapeHtml(String(caseItem.document_count || 0))} documento(s)</span>
          </div>
        </div>
        <div class="cases-detail__hero-actions">
          <div class="cases-detail__action-list">
            <button
              type="button"
              class="ui-button ui-button--accent"
              data-case-upload-open="support"
              data-case-key="${escapeHtml(caseItem.case_key || "")}"
              data-case-label="${escapeHtml(caseItem.case_number || caseItem.case_key || "Caso")}"
              aria-controls="case-upload-dialog"
              aria-haspopup="dialog"
            >
              Agregar documento
            </button>
            <button
              type="button"
              class="ui-button ui-button--secondary"
              data-rda-open="${escapeHtml(RDA_ARTIFACT_TYPES[0].value)}"
            >
              Abrir interoperabilidad
            </button>
            <button
              type="button"
              class="ui-button ui-button--danger"
              data-case-delete="${escapeHtml(caseItem.case_key || "")}"
              data-case-label="${escapeHtml(caseItem.case_number || caseItem.case_key || "Caso")}"
              data-document-count="${escapeHtml(String(allDocuments.length))}"
            >
              Borrar caso
            </button>
          </div>
          <div class="cases-detail__action-list">
            ${buildActionLinks(caseActions)}
          </div>
        </div>
      </header>

      <section class="cases-detail__sections">
        <div class="cases-pane__header">
          <div>
            <p class="cases-pane__eyebrow">Biblioteca del caso</p>
            <h2>Documentos asociados</h2>
          </div>
          <span class="cases-pane__count">${escapeHtml(String(allDocuments.length))}</span>
        </div>
        ${groups
          .map(
            (group) => `
              <section class="cases-document-group">
                <header class="cases-document-group__header">
                  <div>
                    <p class="cases-pane__eyebrow">${escapeHtml(group.type_label || "Documentos")}</p>
                    <h4>${escapeHtml(group.type_label || "Documentos")}</h4>
                  </div>
                  <span class="cases-pane__count">${escapeHtml(String(group.count || 0))}</span>
                </header>
                <div class="cases-document-grid">
                  ${(group.documents || [])
                    .map(
                      (document) => `
                        <article class="cases-document-card">
                          <button
                            type="button"
                            class="cases-document-card__select"
                            data-document-select="${escapeHtml(document.document_id || "")}"
                            aria-pressed="${document.document_id === nextDocumentId ? "true" : "false"}"
                          >
                            <div class="cases-document-card__meta">
                              <strong>${escapeHtml(document.name || "Documento")}</strong>
                              <span>${escapeHtml(document.type_label || document.type || "Documento")}</span>
                              ${
                                resolveDocumentSubtitle(document)
                                  ? `<span>${escapeHtml(resolveDocumentSubtitle(document))}</span>`
                                  : ""
                              }
                            </div>
                            <span class="cases-document-card__date">${escapeHtml(formatDate(document.updated_at))}</span>
                            <div class="cases-document-card__actions">
                              <span class="cases-action-link cases-action-link--secondary" data-document-status>${
                                document.document_id === nextDocumentId ? "Seleccionado" : "Abrir"
                              }</span>
                            </div>
                          </button>
                          <div class="cases-document-card__footer">
                            <button
                              type="button"
                              class="cases-action-link cases-action-link--danger"
                              data-document-delete="${escapeHtml(document.document_id || "")}"
                              data-document-name="${escapeHtml(document.name || "Documento")}"
                              data-case-key="${escapeHtml(caseItem.case_key || "")}"
                              data-case-label="${escapeHtml(caseItem.case_number || caseItem.case_key || "Caso")}"
                            >
                              Borrar documento
                            </button>
                          </div>
                        </article>
                      `
                    )
                    .join("")}
                </div>
              </section>
            `
          )
          .join("")}
      </section>
    `;

    renderSheetRail();
    RDA_ARTIFACT_TYPES.forEach((item) => renderRdaCardLoading(item.value));
    RDA_ARTIFACT_TYPES.forEach((item) => {
      fetchRdaReview(item.value);
    });
    updateSelectionStates();

    const requestedItem = getRequestedSheetItem();
    if (requestedItem?.type === "document") {
      const requestedDocumentId = allDocuments.some((document) => document.document_id === requestedItem.key)
        ? requestedItem.key
        : nextDocumentId;
      if (requestedDocumentId) {
        openSheetItem("document", requestedDocumentId, { push: false, restoreFocus: false });
        return;
      }
    }

    if (requestedItem?.type === "rda") {
      openSheetItem(requestedItem.type, requestedItem.key, { push: false, restoreFocus: false });
      return;
    }

    if (state.sheetOpen) {
      closeSheet({ push: false, restoreFocus: false });
    } else {
      renderSheetContent();
    }
  }

  function renderDetailError(message) {
    selectors.detailEmpty.classList.add("ui-hidden");
    selectors.detail.classList.remove("ui-hidden");
    selectors.detail.innerHTML = `
      <div class="cases-empty">
        <h3>No fue posible cargar el caso</h3>
        <p>${escapeHtml(message)}</p>
      </div>
    `;
  }

  function resetDetail() {
    clearRdaTimers();
    abortRdaRequests();
    selectors.detail.innerHTML = "";
    selectors.detail.classList.add("ui-hidden");
    selectors.detailEmpty.classList.remove("ui-hidden");
    state.detailPayload = null;
    state.selectedDocumentId = "";
    state.documentCache = {};
    state.rdaReviews = {};
    renderSheetRail();
    renderSheetContent();
  }

  async function deleteDocument(documentId) {
    const normalizedDocumentId = String(documentId || "").trim();
    if (!normalizedDocumentId) return null;
    const response = await fetch(`/api/casos/documentos/${encodeURIComponent(normalizedDocumentId)}`, {
      method: "DELETE",
      headers: { Accept: "application/json" },
    });
    const payload = await response.json();
    if (!response.ok) {
      throw new Error(payload.detail || "No fue posible borrar el documento.");
    }
    return payload;
  }

  async function deleteCase(caseKey) {
    const normalizedCaseKey = String(caseKey || "").trim();
    if (!normalizedCaseKey) return null;
    const response = await fetch(`/api/casos/${encodeURIComponent(normalizedCaseKey)}`, {
      method: "DELETE",
      headers: { Accept: "application/json" },
    });
    const payload = await response.json();
    if (!response.ok) {
      throw new Error(payload.detail || "No fue posible borrar el caso.");
    }
    return payload;
  }

  async function performConfirmedDeletion() {
    const pending = state.pendingDeletion;
    if (!pending || state.deletionInFlight) return;
    state.deletionInFlight = true;
    selectors.confirmAccept.disabled = true;
    selectors.confirmAccept.textContent = pending.kind === "case" ? "Eliminando caso…" : "Eliminando documento…";

    try {
      let payload = null;
      if (pending.kind === "document") {
        payload = await deleteDocument(pending.documentId);
        if (
          state.sheetOpen &&
          state.sheetItemType === "document" &&
          state.sheetItemKey === pending.documentId
        ) {
          closeSheet({ push: false, restoreFocus: false });
        }
        if (state.selectedDocumentId === pending.documentId) {
          state.selectedDocumentId = "";
          state.filters.documento_id = "";
        }
      } else {
        payload = await deleteCase(pending.caseKey);
        if (state.sheetOpen) {
          closeSheet({ push: false, restoreFocus: false });
        }
      }

      closeConfirmDialog({ restoreFocus: false });
      await fetchCases();
      globalThis.AppToast?.show?.(payload?.message || "Elemento eliminado correctamente.", {
        type: "success",
        duration: 4200,
      });
    } catch (error) {
      if (isAuthExpiredError(error)) {
        closeConfirmDialog({ restoreFocus: false });
        return;
      }
      state.deletionInFlight = false;
      selectors.confirmAccept.disabled = false;
      selectors.confirmAccept.textContent = pending.kind === "case" ? "Eliminar caso" : "Eliminar documento";
      globalThis.AppToast?.show?.(error.message || "No fue posible completar el borrado.", {
        type: "error",
        duration: 5200,
      });
    }
  }

  async function fetchCaseDetail(caseKey) {
    const normalizedCaseKey = String(caseKey || "").trim();
    if (!normalizedCaseKey) {
      resetDetail();
      return;
    }
    if (state.detailAbortController) {
      state.detailAbortController.abort();
    }
    state.detailAbortController = new AbortController();
    selectors.detailEmpty.classList.add("ui-hidden");
    selectors.detail.classList.remove("ui-hidden");
    selectors.detail.innerHTML = '<div class="cases-loading">Cargando detalle del caso…</div>';

    try {
      const response = await fetch(`/api/casos/${encodeURIComponent(normalizedCaseKey)}`, {
        headers: { Accept: "application/json" },
        signal: state.detailAbortController.signal,
      });
      const payload = await response.json();
      if (!response.ok) {
        throw new Error(payload.detail || "No fue posible cargar el detalle del caso");
      }
      renderDetail(payload);
    } catch (error) {
      if (error.name === "AbortError") return;
      if (isAuthExpiredError(error)) return;
      renderDetailError(error.message);
      globalThis.AppToast?.show?.(error.message, { type: "error", duration: 4200 });
    }
  }

  async function fetchDocument(documentId) {
    const normalizedDocumentId = String(documentId || "").trim();
    if (!normalizedDocumentId) {
      return;
    }
    if (state.documentCache[normalizedDocumentId]) {
      if (state.sheetOpen && state.sheetItemType === "document" && state.sheetItemKey === normalizedDocumentId) {
        renderSheetContent();
      }
      return;
    }

    if (state.documentAbortController) {
      state.documentAbortController.abort();
    }
    state.documentAbortController = new AbortController();

    try {
      const response = await fetch(`/api/documentos/${encodeURIComponent(normalizedDocumentId)}`, {
        headers: { Accept: "application/json" },
        signal: state.documentAbortController.signal,
      });
      const payload = await response.json();
      if (!response.ok) {
        throw new Error(payload.detail || "No fue posible abrir el documento");
      }
      state.documentCache[normalizedDocumentId] = payload;
      if (state.sheetOpen && state.sheetItemType === "document" && state.sheetItemKey === normalizedDocumentId) {
        renderSheetContent();
      }
    } catch (error) {
      if (error.name === "AbortError") return;
      if (isAuthExpiredError(error)) return;
      if (state.sheetOpen && state.sheetItemType === "document" && state.sheetItemKey === normalizedDocumentId) {
        renderSheetPlaceholder("No fue posible abrir el documento", error.message);
      }
      globalThis.AppToast?.show?.(error.message, { type: "error", duration: 4200 });
    }
  }

  function scheduleRdaRefresh(artifactType, attempts = 8) {
    globalThis.clearTimeout(state.rdaRefreshTimers[artifactType]);
    if (attempts <= 0) return;
    state.rdaRefreshTimers[artifactType] = globalThis.setTimeout(async () => {
      await fetchRdaReview(artifactType, { silent: true });
      const status = state.rdaReviews[artifactType]?.status?.status;
      if (status === "queued" || status === "processing") {
        scheduleRdaRefresh(artifactType, attempts - 1);
      }
    }, 2500);
  }

  async function fetchRdaReview(artifactType, { silent = false } = {}) {
    const caseKey = String(state.selectedCaseKey || "").trim();
    if (!caseKey) return;
    if (state.rdaAbortControllers[artifactType]) {
      state.rdaAbortControllers[artifactType].abort();
    }
    const controller = new AbortController();
    state.rdaAbortControllers[artifactType] = controller;
    if (!silent) {
      renderRdaCardLoading(artifactType);
    }

    try {
      const response = await fetch(
        `/api/rda/cases/${encodeURIComponent(caseKey)}/${encodeURIComponent(artifactType)}/validation`,
        {
          headers: { Accept: "application/json" },
          signal: controller.signal,
        }
      );
      if (response.status === 404) {
        const review = {
          case_key: caseKey,
          artifact_type: artifactType,
          artifact: null,
          status: null,
          validation: null,
        };
        state.rdaReviews[artifactType] = review;
        renderRdaCard(artifactType, review);
        renderSheetRail();
        return;
      }
      const payload = await response.json();
      if (!response.ok) {
        throw new Error(payload.detail || "No fue posible cargar la validación RDA.");
      }
      state.rdaReviews[artifactType] = payload;
      renderRdaCard(artifactType, payload);
      renderSheetRail();
    } catch (error) {
      if (error.name === "AbortError") return;
      if (isAuthExpiredError(error)) return;
      renderRdaCardError(artifactType, error.message);
      globalThis.AppToast?.show?.(error.message, { type: "error", duration: 4200 });
    }
  }

  async function queueRdaGeneration(artifactType, { force = false } = {}) {
    const caseKey = String(state.selectedCaseKey || "").trim();
    if (!caseKey) return;
    const actionLabel = force ? "regeneración" : "generación";
    const toastId = globalThis.AppToast?.start?.(`Encolando ${actionLabel} RDA ${artifactType}…`);

    try {
      const response = await fetch(`/api/rda/cases/${encodeURIComponent(caseKey)}/${encodeURIComponent(artifactType)}`, {
        method: "POST",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ force }),
      });
      const payload = await response.json();
      if (!response.ok) {
        throw new Error(payload.detail || "No fue posible encolar la generación RDA.");
      }
      globalThis.AppToast?.success?.(
        toastId,
        `Proceso RDA ${artifactType} en cola${payload.reused ? " (reutilizado)" : ""}.`
      );
      await fetchRdaReview(artifactType, { silent: true });
      scheduleRdaRefresh(artifactType);
    } catch (error) {
      if (isAuthExpiredError(error)) return;
      globalThis.AppToast?.error?.(toastId, error.message || "No fue posible encolar el artefacto RDA.");
    }
  }

  function openSheetItem(itemType, itemKey, { push = true, restoreFocus = true, trigger = null } = {}) {
    const normalizedType = String(itemType || "").trim();
    const normalizedKey = String(itemKey || "").trim();
    if (!normalizedType || !normalizedKey || !state.detailPayload) return;

    if (trigger) {
      rememberSheetTrigger(trigger);
    } else if (!restoreFocus) {
      state.sheetTrigger = null;
    }

    state.sheetOpen = true;
    state.sheetItemType = normalizedType;
    state.sheetItemKey = normalizedKey;
    if (normalizedType === "document") {
      state.selectedDocumentId = normalizedKey;
    }

    ensureSheetVisible();
    renderSheetRail();
    renderSheetContent();
    updateSelectionStates();
    syncUrl({ push });

    if (normalizedType === "document") {
      void fetchDocument(normalizedKey);
      setLiveMessage(`Documento ${normalizedKey} cargado en el sheet documental.`);
      return;
    }

    if (!state.rdaReviews[normalizedKey]) {
      renderSheetContent();
      void fetchRdaReview(normalizedKey, { silent: false });
    }
    setLiveMessage(`Artefacto ${normalizedKey} abierto en el sheet documental.`);
  }

  function applyCaseSelection(caseKey, { push = false } = {}) {
    const normalizedCaseKey = String(caseKey || "").trim();
    const changed = normalizedCaseKey !== state.selectedCaseKey;
    state.selectedCaseKey = normalizedCaseKey;
    state.filters.case_key = normalizedCaseKey;
    if (changed) {
      clearRdaTimers();
      abortRdaRequests();
      state.rdaReviews = {};
      state.selectedDocumentId = "";
      state.documentCache = {};
      if (state.sheetOpen) {
        closeSheet({ push: false, restoreFocus: false });
      }
    }
    renderCases(state.cases);
    syncUrl({ push });
    fetchCaseDetail(state.selectedCaseKey);
  }

  async function fetchCases() {
    if (state.listAbortController) {
      state.listAbortController.abort();
    }
    state.listAbortController = new AbortController();
    const params = new URLSearchParams();
    Object.entries(state.filters).forEach(([key, value]) => {
      if (key === "case_key" || key === "documento_id" || key === "panel_item") return;
      const normalized = String(value || "").trim();
      if (normalized) params.set(key, normalized);
    });
    selectors.resultsMeta.textContent = "Actualizando bandeja de casos…";

    try {
      const response = await fetch(`/api/casos?${params.toString()}`, {
        headers: { Accept: "application/json" },
        signal: state.listAbortController.signal,
      });
      const payload = await response.json();
      if (!response.ok) {
        throw new Error(payload.detail || "No fue posible cargar la bandeja de casos");
      }

      const cases = Array.isArray(payload.cases) ? payload.cases : [];
      renderSummary(payload.summary || {});
      renderDocumentTypeOptions(payload.summary?.available_document_types || []);
      renderCases(cases);
      state.uploadDialog?.setCases(cases);

      const requestedCaseKey = String(state.filters.case_key || "").trim();
      const nextCaseKey = cases.some((item) => item.case_key === requestedCaseKey)
        ? requestedCaseKey
        : cases[0]?.case_key || "";
      if (!nextCaseKey) {
        state.selectedCaseKey = "";
        state.selectedDocumentId = "";
        if (state.sheetOpen) {
          closeSheet({ push: false, restoreFocus: false });
        }
        syncUrl();
        resetDetail();
        setLiveMessage("No hay casos visibles con los filtros actuales.");
        return;
      }

      applyCaseSelection(nextCaseKey);
      setLiveMessage(`${cases.length} casos visibles en la bandeja.`);
    } catch (error) {
      if (error.name === "AbortError") return;
      if (isAuthExpiredError(error)) return;
      selectors.empty.classList.remove("ui-hidden");
      selectors.list.classList.add("ui-hidden");
      selectors.resultsMeta.textContent = error.message;
      resetDetail();
      globalThis.AppToast?.show?.(error.message, { type: "error", duration: 4500 });
    }
  }

  function scheduleFetch() {
    globalThis.clearTimeout(state.searchTimer);
    state.searchTimer = globalThis.setTimeout(() => {
      syncUrl();
      fetchCases();
    }, 250);
  }

  function handleFilterInput(event) {
    const key = event.target.dataset.casesFilter;
    if (!key) return;
    state.filters[key] = event.target.value;
    scheduleFetch();
  }

  function handleResetFilters() {
    state.filters = {
      q: "",
      epicrisis_status: "",
      document_type: "",
      rips_status: "",
      document_count_range: "",
      has_epicrisis_pdf: "",
      updated_from: "",
      updated_to: "",
      case_key: "",
      documento_id: "",
      panel_item: "",
    };
    if (state.sheetOpen) {
      closeSheet({ push: false, restoreFocus: false });
    }
    syncInputsFromState();
    syncUrl();
    fetchCases();
  }

  function initializeUploadDialog() {
    if (!globalThis.CaseUploadDialog?.mount) return;
    state.uploadDialog = globalThis.CaseUploadDialog.mount({
      mode: "support-only",
      requireCaseSelection: true,
      onSupportSuccess() {
        fetchCases();
      },
    });
  }

  function initializeEvents() {
    selectors.filterInputs.forEach((input) => {
      input.addEventListener("input", handleFilterInput);
      input.addEventListener("change", handleFilterInput);
    });
    selectors.resetButton?.addEventListener("click", handleResetFilters);
    selectors.list?.addEventListener("click", (event) => {
      const trigger = event.target.closest("[data-case-select]");
      if (!trigger) return;
      applyCaseSelection(trigger.dataset.caseSelect, { push: true });
    });
    selectors.detail?.addEventListener("click", (event) => {
      const caseDeleteTrigger = event.target.closest("[data-case-delete]");
      if (caseDeleteTrigger) {
        openConfirmDialog(
          {
            kind: "case",
            caseKey: caseDeleteTrigger.dataset.caseDelete,
            caseLabel: caseDeleteTrigger.dataset.caseLabel || "Caso",
            description: `Se borrarán todos los documentos base asociados a este caso en la bandeja operativa.`,
            warning: `También se limpiarán los artefactos derivados del caso, incluyendo epicrisis, RIPS, RDA y estado runtime. Documentos actuales: ${caseDeleteTrigger.dataset.documentCount || "0"}.`,
          },
          { trigger: caseDeleteTrigger }
        );
        return;
      }
      const documentDeleteTrigger = event.target.closest("[data-document-delete]");
      if (documentDeleteTrigger) {
        openConfirmDialog(
          {
            kind: "document",
            documentId: documentDeleteTrigger.dataset.documentDelete,
            documentName: documentDeleteTrigger.dataset.documentName || "Documento",
            caseKey: documentDeleteTrigger.dataset.caseKey || "",
            caseLabel: documentDeleteTrigger.dataset.caseLabel || "Caso",
            description: `Vas a borrar este documento del ${documentDeleteTrigger.dataset.caseLabel || "caso seleccionado"}.`,
            warning: "",
          },
          { trigger: documentDeleteTrigger }
        );
        return;
      }
      const rdaOpenTrigger = event.target.closest("[data-rda-open]");
      if (rdaOpenTrigger) {
        openSheetItem("rda", rdaOpenTrigger.dataset.rdaOpen, { trigger: rdaOpenTrigger });
        return;
      }
      const documentTrigger = event.target.closest("[data-document-select]");
      if (!documentTrigger) return;
      openSheetItem("document", documentTrigger.dataset.documentSelect, { trigger: documentTrigger });
    });
    selectors.sheetRail?.addEventListener("click", (event) => {
      const trigger = event.target.closest("[data-sheet-item-type]");
      if (!trigger) return;
      openSheetItem(trigger.dataset.sheetItemType, trigger.dataset.sheetItemKey, {
        push: true,
        restoreFocus: false,
      });
    });
    selectors.sheetContent?.addEventListener("click", (event) => {
      const refreshTrigger = event.target.closest("[data-sheet-rda-refresh]");
      if (refreshTrigger) {
        fetchRdaReview(refreshTrigger.dataset.sheetRdaRefresh, { silent: false });
        return;
      }
      const generateTrigger = event.target.closest("[data-sheet-rda-generate]");
      if (generateTrigger) {
        queueRdaGeneration(generateTrigger.dataset.sheetRdaGenerate, {
          force: generateTrigger.dataset.sheetRdaGenerateForce === "true",
        });
      }
    });
    selectors.sheetClose?.addEventListener("click", () => {
      closeSheet({ push: true });
    });
    selectors.sheet?.addEventListener("cancel", (event) => {
      event.preventDefault();
      closeSheet({ push: true });
    });
    selectors.sheet?.addEventListener("click", (event) => {
      if (event.target === selectors.sheet) {
        closeSheet({ push: true });
      }
    });
    selectors.confirmAccept?.addEventListener("click", () => {
      performConfirmedDeletion();
    });
    selectors.confirmCancel?.addEventListener("click", () => {
      closeConfirmDialog();
    });
    selectors.confirmDialog?.addEventListener("cancel", (event) => {
      event.preventDefault();
      closeConfirmDialog();
    });
    selectors.confirmDialog?.addEventListener("click", (event) => {
      if (event.target === selectors.confirmDialog) {
        closeConfirmDialog();
      }
    });
    globalThis.addEventListener("popstate", () => {
      state.filters = readFiltersFromUrl();
      if (!getRequestedSheetItem() && state.sheetOpen) {
        closeSheet({ push: false, restoreFocus: false });
      }
      syncInputsFromState();
      fetchCases();
    });
  }

  initializeUploadDialog();
  syncInputsFromState();
  initializeEvents();
  renderSheetContent();
  fetchCases();
})();
