(function (global) {
  const app = (global.EpicrisisApp = global.EpicrisisApp || {});

  function obtenerDescripcionProcedimiento(item) {
    if (!item || typeof item !== "object") return String(item || "").trim();
    return String(item.descripcion || item.procedimiento || item.concepto || "").trim();
  }

  function obtenerCodigoProcedimiento(item) {
    if (!item || typeof item !== "object") return "";
    return String(item.codigo_cups || item.codigo || "").trim();
  }

  function obtenerTextoProcedimiento(item) {
    const descripcion = obtenerDescripcionProcedimiento(item);
    const codigo = obtenerCodigoProcedimiento(item);
    return codigo ? `${codigo} - ${descripcion}` : descripcion;
  }

  function obtenerClaveProcedimiento(item) {
    if (item && typeof item === "object") {
      const key = String(item.key || "").trim();
      if (key) return key.toLowerCase();
      return `${obtenerCodigoProcedimiento(item)}|${obtenerDescripcionProcedimiento(item)}`.toLowerCase();
    }
    return app.utils.stripHtml(item).replace(/\s+/g, " ").trim().toLowerCase();
  }

  function deduplicarProcedimientos(items) {
    const seen = new Map();
    const out = [];
    (items || []).forEach((item) => {
      const texto = obtenerTextoProcedimiento(item);
      if (!texto) return;
      const key = obtenerClaveProcedimiento(item);
      if (!key) return;
      const normalized = item && typeof item === "object"
        ? {
          ...item,
          descripcion: obtenerDescripcionProcedimiento(item),
          codigo_cups: obtenerCodigoProcedimiento(item),
          clasificacion: item.clasificacion || "sin_clasificar",
        }
        : texto;
      if (!seen.has(key)) {
        seen.set(key, out.length);
        out.push(normalized);
        return;
      }
      const index = seen.get(key);
      if (normalized && typeof normalized === "object" && typeof out[index] !== "object") {
        out[index] = normalized;
      }
    });
    return out;
  }

  function formatearCantidadMedicamento(value) {
    const cantidad = String(value ?? "").trim();
    if (!cantidad) return "";
    if (!/^\d+(?:[.,]\d+)?$/.test(cantidad)) return cantidad;
    const numericValue = Number(cantidad.replace(",", "."));
    return `${cantidad} ${numericValue === 1 ? "unidad" : "unidades"}`;
  }

  function construirListasAgrupadas() {
    const data = app.state.data;
    const diagnosticosPrimariosDisponibles = Array.isArray(data.pdfPrimaryDiagnosticos);
    const procedimientosPrimariosDisponibles = Array.isArray(data.pdfPrimaryProcedimientos);
    const medicamentosPrimariosDisponibles = Array.isArray(data.pdfPrimaryMedicamentos);
    const ayudasPrimariasDisponibles = Array.isArray(data.pdfPrimaryAyudasDiagnosticas);
    const diagnosticosCanonicos = app.diagnosticos.normalizarDiagnosticosConsolidados(
      diagnosticosPrimariosDisponibles ? data.pdfPrimaryDiagnosticos : data.diagnosticosConsolidados
    );
    const diagnosticos = [];
    const procedimientos = [];
    const medicamentos = [];
    const ayudasDiagnosticas = [];
    const imagenesDiagnosticas = [];

    if (diagnosticosCanonicos.length > 0) {
      diagnosticos.push(...diagnosticosCanonicos);
    } else {
      const cieHistoria = app.diagnosticos.normalizarDiagnosticos(data.cieHistoria);
      const cieQx = app.diagnosticos.normalizarDiagnosticos(data.cieQx);
      [...cieHistoria, ...cieQx].forEach((item) => {
        diagnosticos.push(app.diagnosticos.formatearDiagnosticoPresentacion(item));
      });
    }

    if (procedimientosPrimariosDisponibles) {
      (data.pdfPrimaryProcedimientos || []).forEach((item) => procedimientos.push(item));
    } else {
      (data.procedimientosHC || []).forEach((item) => procedimientos.push(String(item || "").trim()));
      (data.cups || []).forEach((item) => {
        const codigo = String(item?.codigo_cups || "").trim();
        const proc = String(item?.procedimiento || "").trim();
        procedimientos.push(codigo ? `${codigo} - ${proc}` : proc);
      });
    }

    if (medicamentosPrimariosDisponibles) {
      app.medicamentos.normalizarMedicamentos(data.pdfPrimaryMedicamentos, "historia_clinica").forEach((item) => {
        medicamentos.push(item);
      });
    } else {
      app.medicamentos.normalizarMedicamentos(data.medicamentos, "historia_clinica").forEach((item) => {
        medicamentos.push(item);
      });
    }

    const facturaJson = data.facturaJson || {};
    const servicios = facturaJson.servicios_procedimientos || {};
    if (!procedimientosPrimariosDisponibles) {
      (servicios.procedimientos_quirurgicos || []).forEach((item) => {
        const codigo = String(item?.codigo_cups || "").trim();
        const descripcion = String(item?.descripcion || item?.concepto || "").trim();
        procedimientos.push(codigo ? `${codigo} - ${descripcion}` : descripcion);
      });
    }
    if (!medicamentosPrimariosDisponibles) {
      app.medicamentos.normalizarMedicamentos(servicios.medicamentos || [], "factura").forEach((item) => {
        medicamentos.push(item);
      });
    }

    (ayudasPrimariasDisponibles ? data.pdfPrimaryAyudasDiagnosticas : data.ayudasDiagnosticas || []).forEach((item) => {
      const ayuda = app.ayudasDiagnosticas.normalizarAyudaDiagnostica(item);
      if (ayuda?.nombre) ayudasDiagnosticas.push(ayuda);
    });
    const tieneAyudasEstructuradas = ayudasDiagnosticas.length > 0;
    (data.imagenesDiagnosticas || []).forEach((item) => {
      const texto = String(item || "").trim();
      imagenesDiagnosticas.push(texto);
      if (!ayudasPrimariasDisponibles && !tieneAyudasEstructuradas && texto) {
        ayudasDiagnosticas.push(app.ayudasDiagnosticas.normalizarAyudaDiagnostica(texto));
      }
    });

    if (!diagnosticosPrimariosDisponibles || !procedimientosPrimariosDisponibles) {
      app.soat.obtenerResultadosSoatCombinados().forEach((item) => {
        if (!diagnosticosPrimariosDisponibles && !diagnosticosCanonicos.length) {
          if (item?.cie10_principal) {
            diagnosticos.push(`${item.cie10_principal.codigo || ""} - ${item.cie10_principal.descripcion || ""}`);
          }
          (item?.cie10_secundarios || []).forEach((cie) => {
            diagnosticos.push(`${cie.codigo || ""} - ${cie.descripcion || ""}`);
          });
        }
        if (!procedimientosPrimariosDisponibles && item?.cups_principal) {
          procedimientos.push(`${item.cups_principal.codigo || ""} - ${item.cups_principal.descripcion || ""}`);
        }
        if (!procedimientosPrimariosDisponibles) {
          (item?.cups_alternativos || []).forEach((cups) => {
            procedimientos.push(`${cups.codigo || ""} - ${cups.descripcion || ""}`);
          });
        }
      });
    }

    return {
      diagnosticos: diagnosticosCanonicos.length > 0 ? diagnosticos : app.utils.deduplicarTextos(diagnosticos),
      procedimientos: deduplicarProcedimientos(procedimientos),
      medicamentos: app.medicamentos.deduplicarMedicamentos(medicamentos),
      ayudas_diagnosticas: app.ayudasDiagnosticas.deduplicarAyudasDiagnosticas(ayudasDiagnosticas),
      imagenes_diagnosticas: app.utils.deduplicarTextos(imagenesDiagnosticas),
    };
  }

  function renderSeccionSeleccion(seccion, items) {
    const list = document.getElementById(`${seccion}_list`);
    if (!list) return;
    app.state.pdfSelectionData[seccion] = Array.isArray(items) ? items : [];
    app.state.syncGlobals();

    const draft = app.state.data.pdfDraft || {};
    const excludedTextMap = {
      diagnosticos: new Set(Array.isArray(draft.excluded_diagnosticos) ? draft.excluded_diagnosticos : []),
      procedimientos: new Set(Array.isArray(draft.excluded_procedimientos) ? draft.excluded_procedimientos : []),
      medicamentos: new Set(Array.isArray(draft.excluded_medicamento_keys) ? draft.excluded_medicamento_keys : []),
      ayudas_diagnosticas: new Set(Array.isArray(draft.excluded_imagenes_diagnosticas) ? draft.excluded_imagenes_diagnosticas : []),
      imagenes_diagnosticas: new Set(Array.isArray(draft.excluded_imagenes_diagnosticas) ? draft.excluded_imagenes_diagnosticas : []),
    };
    const excludedMap = {
      diagnosticos: new Set(Array.isArray(draft.excluded_diagnostico_keys) ? draft.excluded_diagnostico_keys : []),
      procedimientos: new Set(Array.isArray(draft.excluded_procedimientos) ? draft.excluded_procedimientos : []),
      medicamentos: new Set(Array.isArray(draft.excluded_medicamentos) ? draft.excluded_medicamentos : []),
      ayudas_diagnosticas: new Set(Array.isArray(draft.excluded_ayudas_diagnosticas_keys) ? draft.excluded_ayudas_diagnosticas_keys : []),
      imagenes_diagnosticas: new Set(Array.isArray(draft.excluded_imagenes_diagnosticas) ? draft.excluded_imagenes_diagnosticas : []),
    };
    list.innerHTML = "";
    const aidFilter = document.getElementById("ayudas_diagnosticas_filter");
    const selectedAidType = String(aidFilter?.value || "todos");

    items.forEach((item, index) => {
      const id = `${seccion}_item_${index}`;
      const row = document.createElement("label");
      row.className = "selection-item";
      const ayuda = seccion === "ayudas_diagnosticas" ? app.ayudasDiagnosticas.normalizarAyudaDiagnostica(item) : null;
      let texto = String(item || "").trim();
      if (seccion === "medicamentos") {
        texto = app.medicamentos.formatearMedicamentoPresentacion(item);
      } else if (seccion === "diagnosticos") {
        texto = String(item?.texto_presentacion || item || "").trim();
      } else if (seccion === "ayudas_diagnosticas") {
        texto = String(ayuda?.nombre || "").trim();
      } else if (seccion === "procedimientos" && item && typeof item === "object") {
        texto = obtenerDescripcionProcedimiento(item);
      }
      const procedimientoDisplayText = seccion === "procedimientos" ? obtenerTextoProcedimiento(item) : "";

      let exclusionKey = texto;
      if (seccion === "diagnosticos") {
        exclusionKey = String(item?.key || "").trim();
      } else if (seccion === "ayudas_diagnosticas") {
        exclusionKey = String(ayuda?.key || "").trim();
      }

      let isChecked = !excludedMap[seccion].has(texto);
      if (seccion === "diagnosticos") {
        isChecked = !(excludedMap[seccion].has(exclusionKey) || excludedTextMap[seccion].has(texto));
      } else if (seccion === "ayudas_diagnosticas") {
        const ayudaDisplayText = `${texto}${ayuda?.concepto ? ` - ${ayuda.concepto}` : ""}`;
        isChecked = Boolean(
          ayuda?.exportable !== false
          && !excludedMap[seccion].has(exclusionKey)
          && !excludedTextMap[seccion].has(ayudaDisplayText)
        );
      } else if (seccion === "medicamentos") {
        const medicationKey = String(item?.key || "").trim();
        isChecked = !(
          (medicationKey && excludedMap[seccion].has(medicationKey))
          || excludedTextMap[seccion].has(texto)
        );
      } else if (seccion === "procedimientos") {
        isChecked = !(
          excludedMap[seccion].has(procedimientoDisplayText)
          || excludedMap[seccion].has(texto)
        );
      }

      if (seccion === "medicamentos") {
        const med = app.medicamentos.normalizarMedicamentoCanonico(item);
        const cantidad = formatearCantidadMedicamento(med.cantidad);
        const referenceCode = med.codigo_referencia ? `CUM/IUM ${med.codigo_referencia}` : "";
        const statuses = med.estados.length
          ? med.estados.map((status) => `<span class="medication-status medication-status--${app.utils.escapeHtml(status)}">${app.utils.escapeHtml(status.replaceAll("_", " "))}</span>`).join("")
          : "";
        const pertinenceLabels = {
          pertinente: "Pertinente",
          revisar: "Revisar",
          posible_glosa: "Posible glosa",
        };
        const pertinenceState = med.pertinencia?.estado || "";
        const pertinenceBadge = pertinenceLabels[pertinenceState]
          ? `<span class="medication-pertinence medication-pertinence--${app.utils.escapeHtml(pertinenceState)}">${pertinenceLabels[pertinenceState]}</span>`
          : "";
        const supportLabels = {
          presente: "Presente",
          ausente: "Ausente",
          no_aplica: "No aplica",
          no_evaluable: "No evaluable",
        };
        const supportChain = med.pertinencia?.cadena || {};
        const linkLabels = {
          orden: "Orden",
          administracion: "Administración",
          facturacion: "Facturación",
        };
        const supportBadges = ["orden", "administracion", "facturacion"]
          .filter((link) => supportChain[link])
          .map((link) => {
            const state = String(supportChain[link]);
            return `<span class="medication-support medication-support--${app.utils.escapeHtml(state)}">${linkLabels[link]}: ${app.utils.escapeHtml(supportLabels[state] || state)}</span>`;
          })
          .join("");
        const association = String(med.asociacion_factura || "no_evaluable").replaceAll("_", " ");
        const comparison = med.pertinencia?.comparacion_cantidad || {};
        const comparisonText = [
          comparison.cantidad_clinica != null
            ? `Clínica: ${comparison.cantidad_clinica} ${comparison.unidad_clinica || ""}`.trim()
            : "",
          comparison.cantidad_facturada != null
            ? `Facturada: ${comparison.cantidad_facturada} ${comparison.unidad_facturada || ""}`.trim()
            : "",
        ].filter(Boolean).join(" • ");
        row.classList.add("selection-item--medication");
        row.innerHTML = `
          <input type="checkbox" id="${id}" ${isChecked ? "checked" : ""} data-index="${index}" aria-label="Incluir ${app.utils.escapeHtml(med.medicamento)}">
          <span class="selection-medication-content" role="group" aria-label="Detalles de ${app.utils.escapeHtml(med.medicamento)}">
            <strong class="selection-medication-name">${app.utils.escapeHtml(med.medicamento)}</strong>
            ${med.presentacion ? `<span class="selection-medication-presentation">${app.utils.escapeHtml(med.presentacion)}</span>` : ""}
            ${referenceCode ? `<span class="selection-medication-codes">${app.utils.escapeHtml(referenceCode)}</span>` : ""}
            ${med.posologia ? `<span class="selection-medication-posology" aria-label="Posología: ${app.utils.escapeHtml(med.posologia)}">${app.utils.escapeHtml(med.posologia)}</span>` : ""}
            ${(med.dosis || cantidad) ? `<span class="selection-medication-measurements">
              ${med.dosis ? `<span class="selection-medication-dose" aria-label="Dosis: ${app.utils.escapeHtml(med.dosis)}">${app.utils.escapeHtml(med.dosis)}</span>` : ""}
              ${med.dosis && cantidad ? '<span class="selection-medication-separator" aria-hidden="true">•</span>' : ""}
              ${cantidad ? `<span class="selection-medication-quantity" aria-label="Cantidad: ${app.utils.escapeHtml(cantidad)}">${app.utils.escapeHtml(cantidad)}</span>` : ""}
            </span>` : ""}
            ${cantidad && med.discrepancia_cantidad ? '<small class="selection-medication-warning">Requiere conciliación</small>' : ""}
            ${statuses ? `<span class="medication-statuses" aria-label="Estados del medicamento">${statuses}</span>` : ""}
            ${pertinenceBadge ? `<span class="medication-pertinence-wrap" aria-label="Pertinencia del medicamento">${pertinenceBadge}</span>` : ""}
            ${pertinenceBadge ? `<span class="selection-medication-reconciliation">
              ${supportBadges ? `<span class="selection-medication-supports" aria-label="Cadena documental">${supportBadges}</span>` : ""}
              <span>Asociación con factura: ${app.utils.escapeHtml(association)}</span>
              ${comparisonText ? `<span>${app.utils.escapeHtml(comparisonText)}</span>` : ""}
            </span>` : ""}
          </span>`;
      } else if (seccion === "ayudas_diagnosticas" && ayuda) {
        row.dataset.aidType = ayuda.tipo;
        row.hidden = !(selectedAidType === "todos" || ayuda.tipo === selectedAidType);
        row.innerHTML = `
          <input type="checkbox" id="${id}" ${isChecked ? "checked" : ""} data-index="${index}">
          <span class="selection-item-content">
            <span>${app.utils.escapeHtml(texto)}</span>
            ${ayuda.concepto ? `<small>${app.utils.escapeHtml(ayuda.concepto)}</small>` : ""}
            <span class="aid-badges">${app.ayudasDiagnosticas.renderBadgesAyuda(ayuda)}</span>
          </span>
        `;
      } else if (seccion === "procedimientos" && item && typeof item === "object") {
        const labels = {
          quirurgico: "Quirúrgico",
          no_quirurgico: "No quirúrgico",
          sin_clasificar: "Sin clasificar",
        };
        row.classList.add("selection-item--procedure");
        row.innerHTML = `
          <input type="checkbox" id="${id}" ${isChecked ? "checked" : ""} data-index="${index}">
          <span class="selection-item-content">
            <span>${app.utils.escapeHtml(procedimientoDisplayText)}</span>
            <span class="procedure-meta">
              <span class="procedure-badge procedure-badge--${app.utils.escapeHtml(item.clasificacion)}">${labels[item.clasificacion] || labels.sin_clasificar}</span>
              ${item.soporte_clinico === false ? '<small class="procedure-support-warning">Soporte clínico pendiente</small>' : ""}
            </span>
          </span>
          <select class="procedure-classification" data-procedure-key="${app.utils.escapeHtml(item.key || "")}" aria-label="Clasificación de ${app.utils.escapeHtml(texto)}">
            <option value="quirurgico" ${item.clasificacion === "quirurgico" ? "selected" : ""}>Quirúrgico</option>
            <option value="no_quirurgico" ${item.clasificacion === "no_quirurgico" ? "selected" : ""}>No quirúrgico</option>
            <option value="sin_clasificar" ${item.clasificacion === "sin_clasificar" ? "selected" : ""}>Sin clasificar</option>
          </select>
        `;
      } else {
        row.innerHTML = `
          <input type="checkbox" id="${id}" ${isChecked ? "checked" : ""} data-index="${index}">
          <span>${app.utils.escapeHtml(texto)}</span>
        `;
      }
      list.appendChild(row);
    });
  }

  function hidratarDraftPdfInicial() {
    const draft = app.state.data.pdfDraft || {};
    const fieldMap = {
      diagnosticos_extra: Array.isArray(draft.manual_diagnosticos) ? draft.manual_diagnosticos.join("\n") : "",
      procedimientos_extra: Array.isArray(draft.manual_procedimientos) ? draft.manual_procedimientos.join("\n") : "",
      medicamentos_extra: Array.isArray(draft.manual_medicamentos) ? draft.manual_medicamentos.join("\n") : "",
      ayudas_diagnosticas_extra: Array.isArray(draft.manual_ayudas_diagnosticas)
        ? draft.manual_ayudas_diagnosticas.map((item) => {
          const ayuda = app.ayudasDiagnosticas.normalizarAyudaDiagnostica(item);
          if (!ayuda) return "";
          return `${ayuda.tipo} | ${ayuda.nombre}${ayuda.concepto ? ` | ${ayuda.concepto}` : ""}`;
        }).filter(Boolean).join("\n")
        : (Array.isArray(draft.manual_imagenes_diagnosticas) ? draft.manual_imagenes_diagnosticas.join("\n") : ""),
      hallazgos_extra: String(draft.hallazgos_extra || ""),
      descripcion_procedimiento_extra: String(draft.descripcion_procedimiento_extra || ""),
    };
    Object.entries(fieldMap).forEach(([id, value]) => {
      const el = document.getElementById(id);
      if (el) {
        el.value = value;
      }
    });
  }

  function inicializarSeleccionPDF() {
    const agrupadas = construirListasAgrupadas();
    renderSeccionSeleccion("diagnosticos", agrupadas.diagnosticos);
    renderSeccionSeleccion("procedimientos", agrupadas.procedimientos);
    renderSeccionSeleccion("medicamentos", agrupadas.medicamentos);
    renderSeccionSeleccion("ayudas_diagnosticas", agrupadas.ayudas_diagnosticas);
  }

  function obtenerElementosSeleccionados(seccion) {
    const list = document.getElementById(`${seccion}_list`);
    const extra = document.getElementById(`${seccion}_extra`);
    const fuente = app.state.pdfSelectionData[seccion] || [];
    const checked = list
      ? Array.from(list.querySelectorAll("input[type='checkbox']:checked"))
        .map((cb) => fuente[Number(cb.dataset.index)])
        .filter((item) => item !== undefined)
      : [];
    const extras = extra
      ? String(extra.value || "")
        .split(/\r?\n/)
        .map((line) => line.trim())
        .filter(Boolean)
      : [];
    if (seccion === "medicamentos") {
      const extrasNormalizados = extras.map((line) => app.medicamentos.normalizarMedicamentoCanonico(line, "manual"));
      return app.medicamentos.deduplicarMedicamentos([...checked, ...extrasNormalizados]);
    }
    if (seccion === "diagnosticos") {
      const checkedText = checked
        .map((item) => item && typeof item === "object"
          ? String(item.texto_presentacion || "").trim()
          : String(item || "").trim())
        .filter(Boolean);
      return app.utils.deduplicarTextos([...checkedText, ...extras]);
    }
    if (seccion === "ayudas_diagnosticas") {
      const manuales = extras
        .map((line) => app.ayudasDiagnosticas.normalizarAyudaDiagnostica(app.ayudasDiagnosticas.parseAyudaManual(line)))
        .filter(Boolean);
      return app.ayudasDiagnosticas.deduplicarAyudasDiagnosticas([
        ...checked.map((item) => app.ayudasDiagnosticas.normalizarAyudaDiagnostica(item)).filter(Boolean),
        ...manuales,
      ]).filter((item) => item.exportable !== false && !item.glosado);
    }
    if (seccion === "procedimientos") {
      return [...checked.map((item) => {
        const normalized = item && typeof item === "object" ? { ...item } : {
          descripcion: String(item || "").trim(),
          codigo_cups: "",
          codigo_soat: "",
          soporte_clinico: true,
        };
        const select = list?.querySelector(`.procedure-classification[data-procedure-key="${CSS.escape(String(normalized.key || ""))}"]`);
        normalized.clasificacion = String(select?.value || normalized.clasificacion || "sin_clasificar");
        return normalized;
      }), ...extras.map((descripcion) => ({
        descripcion,
        codigo_cups: "",
        codigo_soat: "",
        clasificacion: "sin_clasificar",
        soporte_clinico: true,
      }))];
    }
    return app.utils.deduplicarTextos([...checked, ...extras]);
  }

  function obtenerTextoAmpliacion(idCampo) {
    const el = document.getElementById(idCampo);
    return String(el?.value || "").trim();
  }

  function combinarTextoConAmpliacion(base, ampliacion) {
    const textoBase = app.utils.stripHtml(base || "").trim();
    const textoExtra = app.utils.stripHtml(ampliacion || "").trim();
    if (textoBase && textoExtra) {
      return `${textoBase}\n\nAmpliacion medica:\n${textoExtra}`;
    }
    if (textoExtra) return textoExtra;
    if (textoBase) return textoBase;
    return "";
  }

  function obtenerEpicrisisBaseIdDesdeUrl() {
    const params = new URLSearchParams(globalThis.location.search);
    return params.get("id");
  }

  function obtenerEpicrisisCaseKeyDesdeUrl() {
    if (app.state.data.caseKey) return String(app.state.data.caseKey);
    const params = new URLSearchParams(globalThis.location.search);
    const queryValue = params.get("case_key");
    if (queryValue) return queryValue;
    const match = new RegExp(/^\/epicrisis\/caso\/([^/?#]+)/).exec(globalThis.location.pathname);
    return match ? decodeURIComponent(match[1]) : "";
  }

  app.selection = {
    construirListasAgrupadas,
    renderSeccionSeleccion,
    hidratarDraftPdfInicial,
    inicializarSeleccionPDF,
    obtenerElementosSeleccionados,
    obtenerTextoAmpliacion,
    combinarTextoConAmpliacion,
    obtenerEpicrisisBaseIdDesdeUrl,
    obtenerEpicrisisCaseKeyDesdeUrl,
  };
})(globalThis);
