(function () {
  const POLL_INTERVAL_MS = 1800;
  const TERMINAL_STATUSES = new Set(["completado", "cancelado", "fallido"]);
  const WAITING_STATUS = "esperando_confirmacion";

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

  function buildCaseOptionLabel(caseItem) {
    const number = String(caseItem.case_number || caseItem.case_key || "Caso").trim();
    const patientId = String(caseItem.patient_id || "").trim();
    const patientName = String(caseItem.patient_name || "Paciente sin nombre").trim();
    return [number, patientId, patientName].filter(Boolean).join(" · ");
  }

  function normalizePanelTarget(target) {
    if (target === "support" || target === "prefactura") return target;
    return "story";
  }

  function humanizeStatus(status) {
    const map = {
      precheck_en_cola: "Precheck en cola",
      precheck_procesando: "Precheck procesando",
      esperando_confirmacion: "Esperando confirmación",
      listo_para_procesar: "Listo para procesar",
      procesando: "Procesando",
      completado: "Completado",
      cancelado: "Cancelado",
      fallido: "Fallido",
    };
    return map[String(status || "").trim()] || "Pendiente";
  }

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

  function mount(config = {}) {
    const dialog = document.querySelector("[data-case-upload-dialog]");
    if (!dialog) return null;

    const state = {
      activePanel: "story",
      availableCases: [],
      filteredCases: [],
      selectedCaseKey: "",
      casesLoaded: false,
      casesLoadingPromise: null,
      trigger: null,
      mode: dialog.dataset.caseUploadMode || config.mode || "all",
      requireCaseSelection: Boolean(config.requireCaseSelection),
      trackingTimer: null,
      activeUploadId: "",
      activeBatchId: "",
      latestKnownUpload: null,
    };

    const selectors = {
      title: dialog.querySelector("[data-case-upload-title]"),
      copy: dialog.querySelector("[data-case-upload-copy]"),
      close: dialog.querySelector("[data-case-upload-close]"),
      tabs: Array.from(dialog.querySelectorAll("[data-case-upload-tab]")),
      panels: Array.from(dialog.querySelectorAll("[data-case-upload-panel]")),
      switch: dialog.querySelector("[data-case-upload-switch]"),
      storyForm: dialog.querySelector("[data-case-upload-story-form]"),
      supportForm: dialog.querySelector("[data-case-upload-support-form]"),
      prefacturaForm: dialog.querySelector("[data-case-upload-prefactura-form]"),
      feedback: dialog.querySelector("[data-case-upload-feedback]"),
      feedbackTitle: dialog.querySelector("[data-case-upload-feedback-title]"),
      feedbackBody: dialog.querySelector("[data-case-upload-feedback-body]"),
      tracker: dialog.querySelector("[data-case-upload-tracker]"),
      trackerTitle: dialog.querySelector("[data-case-upload-tracker-title]"),
      trackerStatus: dialog.querySelector("[data-case-upload-tracker-status]"),
      trackerDetail: dialog.querySelector("[data-case-upload-tracker-detail]"),
      trackerLink: dialog.querySelector("[data-case-upload-tracker-link]"),
      confirmation: dialog.querySelector("[data-case-upload-confirmation]"),
      confirmationTitle: dialog.querySelector("[data-case-upload-confirmation-title]"),
      confirmationCopy: dialog.querySelector("[data-case-upload-confirmation-copy]"),
      warningList: dialog.querySelector("[data-case-upload-warning-list]"),
      impactList: dialog.querySelector("[data-case-upload-impact-list]"),
      typeResolution: dialog.querySelector("[data-case-upload-type-resolution]"),
      detectedTypeOption: dialog.querySelector("[data-case-upload-effective-type-option='detected']"),
      selectedTypeOption: dialog.querySelector("[data-case-upload-effective-type-option='selected']"),
      detectedTypeLabel: dialog.querySelector("[data-case-upload-effective-type-label='detected']"),
      selectedTypeLabel: dialog.querySelector("[data-case-upload-effective-type-label='selected']"),
      identityFields: dialog.querySelector("[data-case-upload-identity-fields]"),
      caseNumberInput: dialog.querySelector("[data-case-upload-confirm-case-number]"),
      patientIdInput: dialog.querySelector("[data-case-upload-confirm-patient-id]"),
      patientNameInput: dialog.querySelector("[data-case-upload-confirm-patient-name]"),
      confirmAccept: dialog.querySelector("[data-case-upload-confirm-accept]"),
      confirmCancel: dialog.querySelector("[data-case-upload-confirm-cancel]"),
      casePicker: dialog.querySelector("[data-case-upload-case-picker]"),
      caseSearch: dialog.querySelector("[data-case-upload-case-search]"),
      caseSelect: dialog.querySelector("[data-case-upload-case-select]"),
      caseCaption: dialog.querySelector("[data-case-upload-case-caption]"),
      patientField: dialog.querySelector("[data-case-upload-patient-field]"),
      patientInput: dialog.querySelector("[data-case-upload-patient-input]"),
      supportHelp: dialog.querySelector("[data-case-upload-support-help]"),
    };

    function clearFeedback() {
      if (!selectors.feedback) return;
      selectors.feedback.className = "dashboard-feedback ui-alert ui-hidden";
      selectors.feedbackTitle.textContent = "";
      selectors.feedbackBody.textContent = "";
    }

    function showFeedback({ title, body, tone = "info" }) {
      if (!selectors.feedback) return;
      selectors.feedback.className = `dashboard-feedback ui-alert ui-alert--${tone}`;
      selectors.feedback.classList.remove("ui-hidden");
      selectors.feedbackTitle.textContent = title;
      selectors.feedbackBody.textContent = body;
    }

    function clearTracker() {
      selectors.tracker?.classList.add("ui-hidden");
      if (selectors.trackerTitle) selectors.trackerTitle.textContent = "";
      if (selectors.trackerStatus) selectors.trackerStatus.textContent = "";
      if (selectors.trackerDetail) selectors.trackerDetail.textContent = "";
      if (selectors.trackerLink) selectors.trackerLink.href = "/casos";
    }

    function showTracker({ title, status, detail, href }) {
      selectors.tracker?.classList.remove("ui-hidden");
      if (selectors.trackerTitle) selectors.trackerTitle.textContent = title;
      if (selectors.trackerStatus) selectors.trackerStatus.textContent = status || "";
      if (selectors.trackerDetail) {
        selectors.trackerDetail.textContent = detail || "";
        selectors.trackerDetail.classList.toggle("ui-hidden", !detail);
      }
      if (selectors.trackerLink && href) selectors.trackerLink.href = href;
    }

    function clearConfirmation() {
      selectors.confirmation?.classList.add("ui-hidden");
      selectors.warningList?.classList.add("ui-hidden");
      selectors.impactList?.classList.add("ui-hidden");
      selectors.typeResolution?.classList.add("ui-hidden");
      selectors.identityFields?.classList.add("ui-hidden");
      if (selectors.warningList) selectors.warningList.innerHTML = "";
      if (selectors.impactList) selectors.impactList.innerHTML = "";
      if (selectors.detectedTypeOption) selectors.detectedTypeOption.checked = false;
      if (selectors.selectedTypeOption) selectors.selectedTypeOption.checked = false;
      if (selectors.caseNumberInput) selectors.caseNumberInput.value = "";
      if (selectors.patientIdInput) selectors.patientIdInput.value = "";
      if (selectors.patientNameInput) selectors.patientNameInput.value = "";
    }

    function renderItems(container, items) {
      if (!container) return;
      if (!Array.isArray(items) || !items.length) {
        container.classList.add("ui-hidden");
        container.innerHTML = "";
        return;
      }
      container.innerHTML = items
        .map((item) => `<div class="dashboard-upload-confirmation__item">${escapeHtml(item)}</div>`)
        .join("");
      container.classList.remove("ui-hidden");
    }

    function showConfirmation(upload) {
      if (!selectors.confirmation) return;
      const pendingActions = Array.isArray(upload?.pending_actions) ? upload.pending_actions : [];
      const warnings = [
        ...(Array.isArray(upload?.warnings) ? upload.warnings : []),
        ...(Array.isArray(upload?.contradictions) ? upload.contradictions : []),
      ];
      selectors.confirmation.classList.remove("ui-hidden");
      selectors.confirmationTitle.textContent = "Revisa la carga antes de continuar";
      selectors.confirmationCopy.textContent = pendingActions.includes("confirm_case_identity")
        ? "Confirma o corrige la identidad provisional del caso antes de procesar la historia clínica."
        : "El documento presenta una contradicción operativa. Si continúas, se procesará bajo tu responsabilidad.";
      renderItems(selectors.warningList, warnings);
      renderItems(selectors.impactList, Array.isArray(upload?.impact_summary) ? upload.impact_summary : []);
      const selectedType = String(upload?.selected_document_type || "").trim();
      const detectedType = String(upload?.detected_document_type || "").trim();
      const effectiveType = String(upload?.effective_document_type || detectedType || selectedType || "").trim();
      const needsTypeResolution = pendingActions.includes("confirm_type_override") && selectedType && detectedType;
      selectors.typeResolution?.classList.toggle("ui-hidden", !needsTypeResolution);
      if (needsTypeResolution) {
        if (selectors.detectedTypeLabel) {
          selectors.detectedTypeLabel.textContent = `Usar tipo detectado (${detectedType.replaceAll("_", " ")})`;
        }
        if (selectors.selectedTypeLabel) {
          selectors.selectedTypeLabel.textContent = `Mantener tipo seleccionado (${selectedType.replaceAll("_", " ")})`;
        }
        if (selectors.detectedTypeOption) {
          selectors.detectedTypeOption.value = detectedType;
          selectors.detectedTypeOption.checked = effectiveType === detectedType;
        }
        if (selectors.selectedTypeOption) {
          selectors.selectedTypeOption.value = selectedType;
          selectors.selectedTypeOption.checked = effectiveType === selectedType;
        }
      }
      const needsIdentity = pendingActions.includes("confirm_case_identity");
      selectors.identityFields?.classList.toggle("ui-hidden", !needsIdentity);
      if (needsIdentity) {
        selectors.caseNumberInput.value = String(
          upload.confirmed_case_number || upload.provisional_case_number || ""
        ).trim();
        selectors.patientIdInput.value = String(
          upload.confirmed_patient_id || upload.provisional_patient_id || ""
        ).trim();
        selectors.patientNameInput.value = String(
          upload.confirmed_patient_name || upload.provisional_patient_name || ""
        ).trim();
      }
    }

    function stopTracking() {
      if (state.trackingTimer) {
        globalThis.clearTimeout(state.trackingTimer);
        state.trackingTimer = null;
      }
    }

    function shouldRequireCaseSelection() {
      return state.activePanel === "support" || state.requireCaseSelection;
    }

    function applyMode() {
      const supportOnly = state.mode === "support-only";
      selectors.switch?.classList.toggle("ui-hidden", supportOnly);
      selectors.tabs.forEach((button) => {
        if (button.dataset.caseUploadTab === "story") {
          button.disabled = supportOnly;
          button.classList.toggle("ui-hidden", supportOnly);
        }
      });
      if (supportOnly) setActivePanel("support");
    }

    function updateCaseCaption() {
      if (!selectors.caseCaption) return;
      const selected = state.availableCases.find((item) => item.case_key === state.selectedCaseKey);
      selectors.caseCaption.textContent = selected
        ? `Destino: ${buildCaseOptionLabel(selected)}`
        : "Selecciona el caso que recibirá el documento.";
    }

    function renderCaseOptions() {
      if (!selectors.caseSelect) return;
      const options = state.filteredCases.length ? state.filteredCases : state.availableCases;
      if (!options.length) {
        selectors.caseSelect.innerHTML = '<option value="">No hay casos disponibles</option>';
        selectors.caseSelect.value = "";
        state.selectedCaseKey = "";
        updateCaseCaption();
        return;
      }
      selectors.caseSelect.innerHTML = options
        .map(
          (item) =>
            `<option value="${escapeHtml(item.case_key)}">${escapeHtml(buildCaseOptionLabel(item))}</option>`
        )
        .join("");
      const preferredKey =
        state.selectedCaseKey && options.some((item) => item.case_key === state.selectedCaseKey)
          ? state.selectedCaseKey
          : options[0].case_key;
      selectors.caseSelect.value = preferredKey;
      state.selectedCaseKey = preferredKey;
      updateCaseCaption();
    }

    function syncCasePickerVisibility() {
      const visible = shouldRequireCaseSelection();
      selectors.casePicker?.classList.toggle("ui-hidden", !visible);
      selectors.patientField?.classList.toggle("ui-hidden", true);
      if (selectors.caseSelect) {
        selectors.caseSelect.disabled = !visible;
        selectors.caseSelect.required = visible;
      }
      if (selectors.caseSearch) selectors.caseSearch.disabled = !visible;
      if (selectors.patientInput) selectors.patientInput.disabled = true;
      if (selectors.supportHelp) {
        selectors.supportHelp.textContent = visible
          ? "Selecciona un caso existente para asociar el soporte al case key correcto."
          : "Solo la historia clínica puede abrir un caso nuevo.";
      }
    }

    function setCases(cases) {
      state.availableCases = Array.isArray(cases)
        ? cases
            .map((item) => ({
              case_key: String(item.case_key || "").trim(),
              case_number: String(item.case_number || "").trim(),
              patient_id: String(item.patient_id || "").trim(),
              patient_name: String(item.patient_name || "").trim(),
            }))
            .filter((item) => item.case_key)
        : [];
      state.casesLoaded = true;
      state.casesLoadingPromise = null;
      state.filteredCases = [];
      if (!state.availableCases.some((item) => item.case_key === state.selectedCaseKey)) {
        state.selectedCaseKey = state.availableCases[0]?.case_key || "";
      }
      renderCaseOptions();
      syncCasePickerVisibility();
    }

    async function ensureCasesLoaded({ force = false } = {}) {
      if (!shouldRequireCaseSelection()) return state.availableCases;
      if (!force && state.casesLoaded) return state.availableCases;
      if (state.casesLoadingPromise) return state.casesLoadingPromise;
      state.casesLoadingPromise = fetch("/api/casos", {
        headers: { Accept: "application/json" },
      })
        .then(async (response) => {
          const payload = await response.json();
          if (!response.ok) throw new Error(payload.detail || "No fue posible cargar los casos disponibles");
          setCases(Array.isArray(payload.cases) ? payload.cases : []);
          return state.availableCases;
        })
        .catch((error) => {
          state.casesLoaded = false;
          state.casesLoadingPromise = null;
          state.availableCases = [];
          state.filteredCases = [];
          state.selectedCaseKey = "";
          renderCaseOptions();
          syncCasePickerVisibility();
          showFeedback({
            title: "No fue posible cargar los casos",
            body: error.message,
            tone: "error",
          });
          throw error;
        });
      return state.casesLoadingPromise;
    }

    function filterCases(query) {
      const normalized = String(query || "").trim().toLowerCase();
      if (!normalized) {
        state.filteredCases = [];
        renderCaseOptions();
        return;
      }
      state.filteredCases = state.availableCases.filter((item) =>
        [item.case_key, item.case_number, item.patient_id, item.patient_name]
          .map((value) => String(value || "").toLowerCase())
          .some((value) => value.includes(normalized))
      );
      renderCaseOptions();
    }

    function setActivePanel(target) {
      const normalizedTarget = normalizePanelTarget(target);
      state.activePanel = normalizedTarget;
      selectors.tabs.forEach((button) => {
        const active = button.dataset.caseUploadTab === normalizedTarget;
        button.classList.toggle("is-active", active);
        button.setAttribute("aria-selected", active ? "true" : "false");
      });
      selectors.panels.forEach((panel) => {
        const active = panel.dataset.caseUploadPanel === normalizedTarget;
        panel.classList.toggle("ui-hidden", !active);
        panel.classList.toggle("is-active", active);
      });
      syncCasePickerVisibility();
      if (normalizedTarget === "support") {
        selectors.title.textContent = "Agregar documento al caso";
        selectors.copy.textContent =
          "Asocia un soporte a un caso existente y resuelve contradicciones en el mismo diálogo.";
        void ensureCasesLoaded();
      } else if (normalizedTarget === "prefactura") {
        selectors.title.textContent = "Cargue de prefactura";
        selectors.copy.textContent =
          "Sube un PDF compuesto para separar categorías y consolidar el caso por número de caso.";
      } else {
        selectors.title.textContent = "Cargue guiado de historia clínica";
        selectors.copy.textContent =
          "Sube una historia clínica, revisa la identidad provisional y materializa sin bloquear la aplicación.";
      }
    }

    async function readJsonResponse(response, fallback) {
      try {
        return await response.json();
      } catch {
        return { detail: fallback };
      }
    }

    async function fetchUploadStatus(uploadId) {
      const response = await fetch(`/api/cargue-individual/${encodeURIComponent(uploadId)}`, {
        headers: { Accept: "application/json" },
      });
      const payload = await readJsonResponse(response, "No fue posible consultar la carga individual");
      if (!response.ok) {
        throw new Error(payload.detail || "No fue posible consultar la carga individual");
      }
      return payload;
    }

    async function fetchBatchStatus(batchId) {
      const response = await fetch(`/api/lotes/${encodeURIComponent(batchId)}`, {
        headers: { Accept: "application/json" },
      });
      const payload = await readJsonResponse(response, "No fue posible consultar el lote de prefactura");
      if (!response.ok) {
        throw new Error(payload.detail || "No fue posible consultar el lote de prefactura");
      }
      return payload;
    }

    async function fetchBatchCases(batchId) {
      const response = await fetch(`/api/lotes/${encodeURIComponent(batchId)}/casos`, {
        headers: { Accept: "application/json" },
      });
      const payload = await readJsonResponse(response, "No fue posible consultar los casos del lote");
      if (!response.ok) return [];
      return Array.isArray(payload.casos) ? payload.casos : [];
    }

    async function rehydrateLatestPending() {
      try {
        const response = await fetch("/api/cargue-individual/pending-latest", {
          headers: { Accept: "application/json" },
        });
        const payload = await readJsonResponse(response, "No fue posible consultar la carga pendiente");
        if (!response.ok) return null;
        state.latestKnownUpload = payload.upload || null;
        if (!state.activeUploadId && payload.upload?.upload_id) {
          state.activeUploadId = String(payload.upload.upload_id || "").trim();
        }
        return payload.upload || null;
      } catch {
        return null;
      }
    }

    function describeUpload(upload) {
      const status = String(upload?.status || "").trim();
      const selectedType = String(upload?.selected_document_type || "documento").replaceAll("_", " ");
      const titleByStatus = {
        precheck_en_cola: "Documento recibido",
        precheck_procesando: "Precheck en curso",
        esperando_confirmacion: "Acción requerida",
        listo_para_procesar: "Listo para materializar",
        procesando: "Procesamiento clínico en curso",
        completado: "Documento procesado",
        cancelado: "Carga cancelada",
        fallido: "Carga fallida",
      };
      const detail =
        status === WAITING_STATUS
          ? "Debes revisar la identidad provisional o confirmar la contradicción detectada."
          : status === "completado"
            ? "El documento ya fue materializado y el caso quedó actualizado."
            : upload?.error || `Estado actual: ${humanizeStatus(status)}.`;
      const tone =
        status === "completado"
          ? "success"
          : status === WAITING_STATUS
            ? "warning"
            : status === "fallido"
              ? "error"
              : status === "cancelado"
                ? "info"
                : "info";
      return {
        title: titleByStatus[status] || "Seguimiento de carga",
        status: `${humanizeStatus(status)} · ${selectedType}`,
        detail,
        tone,
        waiting: status === WAITING_STATUS,
        terminal: TERMINAL_STATUSES.has(status),
      };
    }

    function onCompleted(upload) {
      state.casesLoaded = false;
      state.casesLoadingPromise = null;
      if (String(upload?.selected_document_type || "") === "historia_clinica") {
        config.onStorySuccess?.(upload);
      } else {
        config.onSupportSuccess?.(upload);
      }
    }

    async function pollUpload() {
      if (!state.activeUploadId) return;
      try {
        const upload = await fetchUploadStatus(state.activeUploadId);
        state.latestKnownUpload = upload;
        const summary = describeUpload(upload);
        showTracker({
          title: summary.title,
          status: summary.status,
          detail: summary.detail,
          href: upload?.case_key ? `/casos?case_key=${encodeURIComponent(upload.case_key)}` : "/casos",
        });
        showFeedback({
          title: summary.title,
          body: summary.detail,
          tone: summary.tone,
        });
        if (summary.waiting) {
          stopTracking();
          showConfirmation(upload);
          return;
        }
        clearConfirmation();
        if (summary.terminal) {
          stopTracking();
          if (upload?.status === "completado") onCompleted(upload);
          return;
        }
        state.trackingTimer = globalThis.setTimeout(pollUpload, POLL_INTERVAL_MS);
      } catch (error) {
        if (isAuthExpiredError(error)) {
          stopTracking();
          return;
        }
        showFeedback({
          title: "No fue posible consultar la carga",
          body: error.message,
          tone: "error",
        });
        state.trackingTimer = globalThis.setTimeout(pollUpload, POLL_INTERVAL_MS * 2);
      }
    }

    function beginTracking(payload) {
      stopTracking();
      clearConfirmation();
      state.activeBatchId = "";
      state.activeUploadId = String(payload?.upload_id || "").trim();
      if (!state.activeUploadId) throw new Error("La respuesta no incluye upload_id.");
      showTracker({
        title: "Carga aceptada",
        status: "El documento fue recibido para precheck.",
        detail: payload?.message || "",
        href: "/casos",
      });
      showFeedback({
        title: payload?.duplicate ? "Documento ya registrado" : "Carga aceptada",
        body: payload?.message || "El sistema inició el procesamiento del documento.",
        tone: payload?.duplicate ? "info" : "success",
      });
      state.trackingTimer = globalThis.setTimeout(pollUpload, 120);
    }

    function humanizeBatchStatus(status) {
      const map = {
        recibido: "Recibido",
        preparando: "Interpretando",
        procesando: "Procesando",
        completado: "Completado",
        completado_con_errores: "Completado con advertencias",
        fallido: "Fallido",
      };
      return map[String(status || "").trim()] || "Pendiente";
    }

    function describeBatch(batch) {
      const status = String(batch?.status || "").trim();
      const total = Number(batch?.total_files || 0);
      const processed = Number(batch?.processed_files || 0);
      const clinicalProcessed = Number(batch?.clinical_processed_files || 0);
      const clinicalFailed = Number(batch?.clinical_failed_files || 0);
      const titleByStatus = {
        recibido: "Prefactura recibida",
        preparando: "Interpretando PDF",
        procesando: "Clasificando y procesando soportes",
        completado: "Caso de prefactura consolidado",
        completado_con_errores: "Prefactura procesada con advertencias",
        fallido: "Prefactura fallida",
      };
      const detail =
        batch?.error ||
        `${processed}/${total} documentos interpretados · ${clinicalProcessed} clínicos completados · ${clinicalFailed} con error.`;
      const tone =
        status === "completado"
          ? "success"
          : status === "completado_con_errores"
            ? "warning"
            : status === "fallido"
              ? "error"
              : "info";
      return {
        title: titleByStatus[status] || "Seguimiento de prefactura",
        status: humanizeBatchStatus(status),
        detail,
        tone,
        terminal: ["completado", "completado_con_errores", "fallido"].includes(status),
      };
    }

    async function pollBatch() {
      if (!state.activeBatchId) return;
      try {
        const batch = await fetchBatchStatus(state.activeBatchId);
        const summary = describeBatch(batch);
        let href = "/casos";
        if (summary.terminal && batch?.status !== "fallido") {
          const cases = await fetchBatchCases(state.activeBatchId);
          const firstCaseKey = String(cases[0]?.case_key || "").trim();
          if (firstCaseKey) href = `/casos?case_key=${encodeURIComponent(firstCaseKey)}`;
        }
        showTracker({
          title: summary.title,
          status: summary.status,
          detail: summary.detail,
          href,
        });
        showFeedback({
          title: summary.title,
          body: summary.detail,
          tone: summary.tone,
        });
        if (summary.terminal) {
          stopTracking();
          config.onPrefacturaSuccess?.(batch);
          return;
        }
        state.trackingTimer = globalThis.setTimeout(pollBatch, POLL_INTERVAL_MS);
      } catch (error) {
        if (isAuthExpiredError(error)) {
          stopTracking();
          return;
        }
        showFeedback({
          title: "No fue posible consultar la prefactura",
          body: error.message,
          tone: "error",
        });
        state.trackingTimer = globalThis.setTimeout(pollBatch, POLL_INTERVAL_MS * 2);
      }
    }

    function beginBatchTracking(payload) {
      stopTracking();
      clearConfirmation();
      state.activeUploadId = "";
      state.activeBatchId = String(payload?.batch_id || "").trim();
      if (!state.activeBatchId) throw new Error("La respuesta no incluye batch_id.");
      showTracker({
        title: "Prefactura aceptada",
        status: "El PDF fue recibido para interpretación.",
        detail: "El sistema separará categorías y consolidará el caso.",
        href: "/subir_lote",
      });
      showFeedback({
        title: "Prefactura aceptada",
        body: "El sistema inició la interpretación del PDF compuesto.",
        tone: "success",
      });
      state.trackingTimer = globalThis.setTimeout(pollBatch, 120);
    }

    function restoreFocus() {
      if (state.trigger instanceof HTMLElement) state.trigger.focus();
      state.trigger = null;
    }

    async function submitStoryForm(event) {
      event.preventDefault();
      clearFeedback();
      clearConfirmation();
      const form = event.currentTarget;
      const fileInput = form.querySelector("input[type='file']");
      const submitButton = form.querySelector("button[type='submit']");
      if (!fileInput?.files?.length) {
        showFeedback({
          title: "Selecciona un archivo",
          body: "Debes elegir un PDF antes de continuar.",
          tone: "warning",
        });
        return;
      }
      const formData = new FormData(form);
      submitButton.disabled = true;
      submitButton.textContent = "Encolando historia…";
      try {
        const response = await fetch("/api/cargue-individual/historia", {
          method: "POST",
          body: formData,
        });
        const payload = await readJsonResponse(response, "No fue posible iniciar la historia clínica");
        if (!response.ok) throw new Error(payload.detail || "No fue posible iniciar la historia clínica");
        form.reset();
        beginTracking(payload);
      } catch (error) {
        showFeedback({
          title: "No fue posible iniciar la historia",
          body: error.message,
          tone: "error",
        });
      } finally {
        submitButton.disabled = false;
        submitButton.textContent = submitButton.dataset.submitLabel || "Procesar historia";
      }
    }

    async function submitSupportForm(event) {
      event.preventDefault();
      clearFeedback();
      clearConfirmation();
      const form = event.currentTarget;
      const submitButton = form.querySelector("button[type='submit']");
      try {
        await ensureCasesLoaded();
      } catch {
        selectors.caseSelect?.focus();
        return;
      }
      const selectedCaseKey = String(selectors.caseSelect?.value || state.selectedCaseKey || "").trim();
      if (!selectedCaseKey) {
        showFeedback({
          title: "Selecciona un caso",
          body: "Debes elegir un caso existente antes de agregar el documento.",
          tone: "warning",
        });
        selectors.caseSelect?.focus();
        return;
      }
      const formData = new FormData(form);
      formData.set("case_key", selectedCaseKey);
      submitButton.disabled = true;
      submitButton.textContent = "Encolando soporte…";
      try {
        const response = await fetch("/api/cargue-individual/soporte", {
          method: "POST",
          body: formData,
        });
        const payload = await readJsonResponse(response, "No fue posible iniciar el soporte");
        if (!response.ok) throw new Error(payload.detail || "No fue posible iniciar el soporte");
        form.reset();
        if (selectors.caseSearch) selectors.caseSearch.value = "";
        state.filteredCases = [];
        renderCaseOptions();
        beginTracking(payload);
      } catch (error) {
        showFeedback({
          title: "No fue posible iniciar el soporte",
          body: error.message,
          tone: "error",
        });
      } finally {
        submitButton.disabled = false;
        submitButton.textContent = submitButton.dataset.submitLabel || "Agregar soporte";
      }
    }

    async function submitPrefacturaForm(event) {
      event.preventDefault();
      clearFeedback();
      clearConfirmation();
      const form = event.currentTarget;
      const fileInput = form.querySelector("input[type='file']");
      const submitButton = form.querySelector("button[type='submit']");
      if (!fileInput?.files?.length) {
        showFeedback({
          title: "Selecciona un archivo",
          body: "Debes elegir el PDF compuesto de prefactura antes de continuar.",
          tone: "warning",
        });
        return;
      }
      const formData = new FormData(form);
      submitButton.disabled = true;
      submitButton.textContent = "Encolando prefactura...";
      try {
        const response = await fetch("/api/lotes/prefactura", {
          method: "POST",
          body: formData,
        });
        const payload = await readJsonResponse(response, "No fue posible iniciar la prefactura");
        if (!response.ok) throw new Error(payload.detail || "No fue posible iniciar la prefactura");
        form.reset();
        beginBatchTracking(payload);
      } catch (error) {
        showFeedback({
          title: "No fue posible iniciar la prefactura",
          body: error.message,
          tone: "error",
        });
      } finally {
        submitButton.disabled = false;
        submitButton.textContent = submitButton.dataset.submitLabel || "Procesar prefactura";
      }
    }

    async function confirmCurrentUpload() {
      if (!state.activeUploadId) return;
      selectors.confirmAccept.disabled = true;
      try {
        const response = await fetch(`/api/cargue-individual/${encodeURIComponent(state.activeUploadId)}/confirmar`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            case_number: String(selectors.caseNumberInput?.value || "").trim(),
            patient_id: String(selectors.patientIdInput?.value || "").trim(),
            patient_name: String(selectors.patientNameInput?.value || "").trim(),
            effective_document_type: String(
              dialog.querySelector("input[name='case-upload-effective-document-type']:checked")?.value || ""
            ).trim(),
          }),
        });
        const payload = await readJsonResponse(response, "No fue posible confirmar la carga");
        if (!response.ok) throw new Error(payload.detail || "No fue posible confirmar la carga");
        clearConfirmation();
        state.trackingTimer = globalThis.setTimeout(pollUpload, 120);
      } catch (error) {
        showFeedback({
          title: "No fue posible confirmar",
          body: error.message,
          tone: "error",
        });
      } finally {
        selectors.confirmAccept.disabled = false;
      }
    }

    async function cancelCurrentUpload() {
      if (!state.activeUploadId) return;
      selectors.confirmCancel.disabled = true;
      try {
        const response = await fetch(`/api/cargue-individual/${encodeURIComponent(state.activeUploadId)}/cancelar`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ reason: "cancelled_from_dialog" }),
        });
        const payload = await readJsonResponse(response, "No fue posible cancelar la carga");
        if (!response.ok) throw new Error(payload.detail || "No fue posible cancelar la carga");
        clearConfirmation();
        state.trackingTimer = globalThis.setTimeout(pollUpload, 120);
      } catch (error) {
        showFeedback({
          title: "No fue posible cancelar",
          body: error.message,
          tone: "error",
        });
      } finally {
        selectors.confirmCancel.disabled = false;
      }
    }

    async function open(target = "support", trigger = null, context = null) {
      state.trigger = trigger || document.activeElement;
      if (context?.caseKey) state.selectedCaseKey = String(context.caseKey || "").trim();
      clearFeedback();
      if (!dialog.open) dialog.showModal();
      applyMode();
      setActivePanel(state.mode === "support-only" ? "support" : normalizePanelTarget(target));
      if (state.activePanel !== "prefactura") {
        await rehydrateLatestPending();
      }
      if (state.activeUploadId && state.activePanel !== "prefactura") {
        state.trackingTimer = globalThis.setTimeout(pollUpload, 120);
      } else {
        clearTracker();
        clearConfirmation();
      }
      globalThis.requestAnimationFrame(() => {
        const focusTarget =
          state.activeUploadId && selectors.confirmation && !selectors.confirmation.classList.contains("ui-hidden")
            ? selectors.confirmAccept
            : dialog.querySelector(
                state.activePanel === "support"
                  ? "[data-case-upload-support-form] input[type='file']"
                  : state.activePanel === "prefactura"
                    ? "[data-case-upload-prefactura-form] input[type='file']"
                    : "[data-case-upload-story-form] input[type='file']"
              );
        focusTarget?.focus();
      });
    }

    function close() {
      if (!dialog.open) return;
      dialog.close();
    }

    function initializeEvents() {
      selectors.tabs.forEach((button) => {
        button.addEventListener("click", () => setActivePanel(button.dataset.caseUploadTab));
      });
      selectors.storyForm?.addEventListener("submit", submitStoryForm);
      selectors.supportForm?.addEventListener("submit", submitSupportForm);
      selectors.prefacturaForm?.addEventListener("submit", submitPrefacturaForm);
      selectors.caseSearch?.addEventListener("input", (event) => filterCases(event.target.value));
      selectors.caseSelect?.addEventListener("change", (event) => {
        state.selectedCaseKey = String(event.target.value || "").trim();
        updateCaseCaption();
      });
      selectors.confirmAccept?.addEventListener("click", confirmCurrentUpload);
      selectors.confirmCancel?.addEventListener("click", cancelCurrentUpload);
      selectors.close?.addEventListener("click", close);
      dialog.addEventListener("close", restoreFocus);
      dialog.addEventListener("click", (event) => {
        if (event.target === dialog) close();
      });
      document.addEventListener("click", (event) => {
        const trigger = event.target.closest("[data-case-upload-open]");
        if (!trigger) return;
        event.preventDefault();
        open(trigger.dataset.caseUploadOpen, trigger, {
          caseKey: trigger.dataset.caseKey || "",
        });
      });
    }

    initializeEvents();
    applyMode();
    renderCaseOptions();
    syncCasePickerVisibility();
    clearTracker();
    clearConfirmation();
    void rehydrateLatestPending();

    return {
      open,
      close,
      setCases,
      setMode(nextMode) {
        state.mode = nextMode || "all";
        applyMode();
      },
    };
  }

  globalThis.CaseUploadDialog = { mount };
})();
