# test-cie-data.R
# Pruebas para funciones de generacion de datos CIE-10

# ============================================================
# PRUEBAS parsear_cie10_minsal()
# ============================================================

test_that("parsear_cie10_minsal requiere readxl", {
  # Solo testear si readxl NO esta instalado
  skip_if(requireNamespace("readxl", quietly = TRUE),
          "readxl esta instalado")

  expect_error(
    ciecl:::parsear_cie10_minsal("test.xls"),
    "readxl"
  )
})

test_that("parsear_cie10_minsal error si archivo no existe", {
  skip_if_not_installed("readxl")

  expect_error(
    ciecl:::parsear_cie10_minsal("archivo_inexistente.xls"),
    "no encontrado"
  )
})

test_that("parsear_cie10_minsal con XLS real", {
  skip_on_cran()
  skip_if_not_installed("readxl")

  # Buscar XLSX/XLS MINSAL en rutas conocidas (formato CIE-10 correcto)
  xls_paths <- c(
    "../CIE-10 (1).xlsx",
    "CIE-10 (1).xlsx"
  )

  xls_path <- NULL
  for (path in xls_paths) {
    if (file.exists(path)) {
      xls_path <- path
      break
    }
  }

  skip_if(is.null(xls_path), "Archivo XLSX CIE-10 MINSAL no disponible")

  # Intentar parsear, skip si formato incompatible
  resultado <- tryCatch(
    ciecl:::parsear_cie10_minsal(xls_path),
    error = function(e) {
      if (grepl("columnas codigo/descripcion", e$message)) {
        skip("XLS tiene formato de columnas incompatible")
      }
      stop(e)
    }
  )

  # Verificar estructura
  expect_s3_class(resultado, "tbl_df")
  expect_true("codigo" %in% names(resultado))
  expect_true("descripcion" %in% names(resultado))
  expect_true("capitulo" %in% names(resultado))
  expect_true("es_daga" %in% names(resultado))
  expect_true("es_cruz" %in% names(resultado))

  # Verificar contenido minimo
  expect_gt(nrow(resultado), 30000)


  # Verificar tipos de datos
  expect_type(resultado$codigo, "character")
  expect_type(resultado$descripcion, "character")
  expect_type(resultado$es_daga, "logical")
  expect_type(resultado$es_cruz, "logical")
})

test_that("parsear_cie10_minsal detecta codigos daga y cruz", {
  skip_on_cran()
  skip_if_not_installed("readxl")

  # Buscar XLSX/XLS MINSAL (formato CIE-10 correcto)
  xls_paths <- c(
    "../CIE-10 (1).xlsx",
    "CIE-10 (1).xlsx"
  )


  xls_path <- NULL
  for (path in xls_paths) {
    if (file.exists(path)) {
      xls_path <- path
      break
    }
  }

  skip_if(is.null(xls_path), "Archivo XLSX CIE-10 MINSAL no disponible")

  # Intentar parsear, skip si formato incompatible
  resultado <- tryCatch(
    ciecl:::parsear_cie10_minsal(xls_path),
    error = function(e) {
      if (grepl("columnas codigo/descripcion", e$message)) {
        skip("XLS tiene formato de columnas incompatible")
      }
      stop(e)
    }
  )

  # Verificar que hay codigos con flags daga/cruz
  n_daga <- sum(resultado$es_daga, na.rm = TRUE)
  n_cruz <- sum(resultado$es_cruz, na.rm = TRUE)

  # Los flags pueden ser 0 si el archivo no tiene simbolos
  # Pero la columna debe existir y ser logica
  expect_type(resultado$es_daga, "logical")
  expect_type(resultado$es_cruz, "logical")
})

# ============================================================
# PRUEBAS ciecl:::generar_cie10_cl()
# ============================================================

test_that("generar_cie10_cl requiere usethis", {
  # Solo testear si usethis NO esta instalado
  skip_if(requireNamespace("usethis", quietly = TRUE),
          "usethis esta instalado")

  expect_error(
    ciecl:::generar_cie10_cl("test.xls"),
    "usethis"
  )
})

test_that("generar_cie10_cl error si archivo no encontrado", {
  skip_if_not_installed("usethis")
  skip_if_not_installed("readxl")

  # En directorio temporal sin archivos DEIS
  withr::with_tempdir({
    expect_error(
      ciecl:::generar_cie10_cl(),
      "no encontrado"
    )
  })
})

test_that("generar_cie10_cl acepta ruta explicita", {
  skip_on_cran()
  skip_if_not_installed("usethis")
  skip_if_not_installed("readxl")

  # Verificar que acepta argumento archivo_path
  # (fallara si archivo no existe, pero no debe dar error de argumento)
  expect_error(
    ciecl:::generar_cie10_cl(archivo_path = "ruta_explicita.xls"),
    "no encontrado"
  )
})

test_that("generar_cie10_cl detecta XLS en directorio padre", {
  skip_on_cran()
  skip_if_not_installed("usethis")
  skip_if_not_installed("readxl")
  skip_if_not_installed("writexl")

  withr::with_tempdir({
    # Crear subdirectorio
    dir.create("child")

    # Crear mock XLSX en directorio padre con formato CIE-10 correcto
    # Nota: usamos .xlsx porque writexl crea archivos xlsx
    mock_data <- data.frame(
      codigo = c("E11.0", "I50.9", "A00.0"),
      descripcion = c("Diabetes tipo 2", "Insuficiencia cardiaca", "Colera"),
      stringsAsFactors = FALSE
    )
    writexl::write_xlsx(mock_data, "mock_cie10.xlsx")

    # Verificar que el archivo existe en padre
    expect_true(file.exists("mock_cie10.xlsx"))

    # Desde child, parsear_cie10_minsal deberia poder leer archivo en padre
    withr::with_dir("child", {
      parent_path <- normalizePath("../mock_cie10.xlsx", mustWork = FALSE)
      expect_true(file.exists(parent_path))

      # Ejecutar parsear_cie10_minsal con ruta explicita padre
      resultado <- ciecl:::parsear_cie10_minsal(parent_path)
      expect_s3_class(resultado, "tbl_df")
      expect_equal(nrow(resultado), 3)
    })
  })
})

test_that("generar_cie10_cl detecta XLS en directorio actual", {
  skip_on_cran()
  skip_if_not_installed("usethis")
  skip_if_not_installed("readxl")
  skip_if_not_installed("writexl")

  withr::with_tempdir({
    # Crear mock XLSX en directorio actual con formato CIE-10 correcto
    mock_data <- data.frame(
      codigo = c("E11.0", "I50.9", "A00.0"),
      descripcion = c("Diabetes tipo 2", "Insuficiencia cardiaca", "Colera"),
      stringsAsFactors = FALSE
    )
    writexl::write_xlsx(mock_data, "mock_cie10.xlsx")

    # Verificar que el archivo existe
    expect_true(file.exists("mock_cie10.xlsx"))

    # parsear_cie10_minsal con ruta directa
    resultado <- ciecl:::parsear_cie10_minsal("mock_cie10.xlsx")
    expect_s3_class(resultado, "tbl_df")
    expect_equal(nrow(resultado), 3)
  })
})

test_that("generar_cie10_cl autodeteccion prueba todas las rutas", {
  skip_on_cran()
  skip_if_not_installed("usethis")
  skip_if_not_installed("readxl")

  # Este test verifica que la funcion intenta todas las rutas candidatas
  # cuando archivo_path es NULL y ninguna existe
  withr::with_tempdir({
    dir.create("subdir")
    withr::with_dir("subdir", {
      # Desde subdir, ninguna ruta candidata tiene el archivo
      expect_error(
        ciecl:::generar_cie10_cl(archivo_path = NULL),
        "no encontrado"
      )
    })
  })
})

# ============================================================
# PRUEBAS DATASET cie10_cl
# ============================================================

test_that("dataset cie10_cl codigos son unicos", {
  skip_on_cran()

  data("cie10_cl", package = "ciecl", envir = environment())

  # Contar duplicados
  n_total <- nrow(cie10_cl)
  n_unicos <- length(unique(cie10_cl$codigo))

  # Puede haber algunos duplicados por daga/cruz pero no deberia ser excesivo
  ratio_duplicados <- (n_total - n_unicos) / n_total
  expect_lt(ratio_duplicados, 0.1)  # < 10% duplicados
})

test_that("dataset cie10_cl carga con estructura y formato valido", {
  skip_on_cran()

  data("cie10_cl", package = "ciecl", envir = environment())

  # Carga correcta como tibble con >30k filas
  expect_s3_class(cie10_cl, "tbl_df")
  expect_gt(nrow(cie10_cl), 30000)

  # Columnas requeridas presentes
  expect_true(all(c("codigo", "descripcion") %in% names(cie10_cl)))

  # Todos los codigos deben empezar con letra
  expect_true(all(grepl("^[A-Z]", cie10_cl$codigo)))

  # Todos los codigos deben tener al menos 3 caracteres
  expect_true(all(nchar(cie10_cl$codigo) >= 3))
})

test_that("dataset cie10_cl contiene codigos de capitulos clinicos principales", {
  skip_on_cran()

  data("cie10_cl", package = "ciecl", envir = environment())

  # Verificar presencia de letras de capitulos clinicos clave
  letras_iniciales <- unique(substr(cie10_cl$codigo, 1, 1))
  expect_true("E" %in% letras_iniciales)  # Endocrinas (diabetes)
  expect_true("I" %in% letras_iniciales)  # Circulatorias (hipertension)
  expect_true("C" %in% letras_iniciales)  # Neoplasias
  expect_true("J" %in% letras_iniciales)  # Respiratorias
})

# ============================================================
# PRUEBAS DE INTEGRIDAD DE DATOS
# ============================================================

test_that("dataset cie10_cl sin valores NA en columnas criticas", {
  skip_on_cran()

  data("cie10_cl", package = "ciecl", envir = environment())

  # codigo y descripcion no deben tener NA
  expect_equal(sum(is.na(cie10_cl$codigo)), 0)
  expect_equal(sum(is.na(cie10_cl$descripcion)), 0)
})

test_that("dataset cie10_cl descripciones no vacias", {
  skip_on_cran()

  data("cie10_cl", package = "ciecl", envir = environment())

  # Todas las descripciones deben tener contenido
  expect_true(all(nchar(cie10_cl$descripcion) > 0))
})

test_that("dataset cie10_cl capitulos extraidos correctamente", {
  skip_on_cran()

  data("cie10_cl", package = "ciecl", envir = environment())

  # Si existe columna capitulo, verificar
  if ("capitulo" %in% names(cie10_cl)) {
    # Capitulos validos: A00-Z99
    capitulos_validos <- unique(cie10_cl$capitulo)
    expect_true(all(grepl("^[A-Z]\\d{1,2}$", capitulos_validos, perl = TRUE) |
                    is.na(capitulos_validos)))
  }
})

# ============================================================
# PRUEBAS ADICIONALES PARA COBERTURA
# ============================================================

test_that("parsear_cie10_minsal verifica codigos con formato correcto", {
  skip_on_cran()
  skip_if_not_installed("readxl")

  xls_paths <- c(
    "../CIE-10 (1).xlsx",
    "CIE-10 (1).xlsx"
  )

  xls_path <- NULL
  for (path in xls_paths) {
    if (file.exists(path)) {
      xls_path <- path
      break
    }
  }

  skip_if(is.null(xls_path), "Archivo XLSX CIE-10 MINSAL no disponible")

  resultado <- tryCatch(
    ciecl:::parsear_cie10_minsal(xls_path),
    error = function(e) {
      if (grepl("columnas codigo/descripcion", e$message)) {
        skip("XLS tiene formato de columnas incompatible")
      }
      stop(e)
    }
  )

  # Todos los codigos deben empezar con letra y tener minimo 3 caracteres
  expect_true(all(grepl("^[A-Z]", resultado$codigo)))
  expect_true(all(nchar(resultado$codigo) >= 3))
})

test_that("parsear_cie10_minsal extrae capitulo de codigo", {
  skip_on_cran()
  skip_if_not_installed("readxl")

  xls_paths <- c(
    "../CIE-10 (1).xlsx",
    "CIE-10 (1).xlsx"
  )


  xls_path <- NULL
  for (path in xls_paths) {
    if (file.exists(path)) {
      xls_path <- path
      break
    }
  }

  skip_if(is.null(xls_path), "Archivo XLSX CIE-10 MINSAL no disponible")

  resultado <- tryCatch(
    ciecl:::parsear_cie10_minsal(xls_path),
    error = function(e) {
      if (grepl("columnas codigo/descripcion", e$message)) {
        skip("XLS tiene formato de columnas incompatible")
      }
      stop(e)
    }
  )

  # Capitulo debe extraerse correctamente del codigo
  # E11.0 -> E11, A00 -> A00
  expect_true(all(!is.na(resultado$capitulo) | is.na(resultado$codigo)))
})

test_that("parsear_cie10_minsal limpia descripciones", {
  skip_on_cran()
  skip_if_not_installed("readxl")

  xls_paths <- c(
    "../CIE-10 (1).xlsx",
    "CIE-10 (1).xlsx"
  )

  xls_path <- NULL
  for (path in xls_paths) {
    if (file.exists(path)) {
      xls_path <- path
      break
    }
  }

  skip_if(is.null(xls_path), "Archivo XLSX CIE-10 MINSAL no disponible")

  resultado <- tryCatch(
    ciecl:::parsear_cie10_minsal(xls_path),
    error = function(e) {
      if (grepl("columnas codigo/descripcion", e$message)) {
        skip("XLS tiene formato de columnas incompatible")
      }
      stop(e)
    }
  )

  # Descripciones deben estar limpias (sin espacios extra al inicio/fin)
  expect_false(any(grepl("^\\s|\\s$", resultado$descripcion)))
})

test_that("generar_cie10_cl valida parametros y parsea XLS", {
  skip_on_cran()
  skip_if_not_installed("usethis")
  skip_if_not_installed("readxl")

  # Test 1: Error cuando no encuentra archivo
  expect_error(
    ciecl:::generar_cie10_cl(archivo_path = NULL),
    "no encontrado"
  )

  # Test 2: Error con ruta invalida
  expect_error(
    ciecl:::generar_cie10_cl(archivo_path = "archivo_inexistente.xlsx"),
    class = "error"
  )

  # Test 3: Verificar que parsear_cie10_minsal funciona con XLS real
  # (generar_cie10_cl usa internamente parsear_cie10_minsal)
  xls_paths <- c(
    "../CIE-10 (1).xlsx",
    "CIE-10 (1).xlsx"
  )

  xls_path <- NULL
  for (path in xls_paths) {
    if (file.exists(path)) {
      xls_path <- path
      break
    }
  }

  skip_if(is.null(xls_path), "Archivo XLSX CIE-10 MINSAL no disponible")

  # Testear parsear_cie10_minsal directamente (lo que generar_cie10_cl usa)
  resultado <- parsear_cie10_minsal(xls_path)

  expect_s3_class(resultado, "tbl_df")
  expect_gt(nrow(resultado), 30000)
  expect_true("codigo" %in% names(resultado))
  expect_true("descripcion" %in% names(resultado))
})


# ============================================================
# PRUEBAS parsear_cie10_minsal() CON MOCK DATA
# ============================================================

test_that("parsear_cie10_minsal con mock XLSX detecta columnas codigo/descripcion", {
  skip_on_cran()
  skip_if_not_installed("readxl")
  skip_if_not_installed("writexl")

  withr::with_tempdir({
    # Crear mock XLSX con estructura minima
    mock_data <- data.frame(
      codigo = c("E11.0", "E11.1", "I50.9", "C50.9"),
      descripcion = c(
        "Diabetes mellitus tipo 2 con coma",
        "Diabetes mellitus tipo 2 con cetoacidosis",
        "Insuficiencia cardiaca, no especificada",
        "Tumor maligno de la mama, sin especificar"
      ),
      stringsAsFactors = FALSE
    )

    mock_path <- "mock_cie10.xlsx"
    writexl::write_xlsx(mock_data, mock_path)

    resultado <- ciecl:::parsear_cie10_minsal(mock_path)

    expect_s3_class(resultado, "tbl_df")
    expect_true("codigo" %in% names(resultado))
    expect_true("descripcion" %in% names(resultado))
    expect_equal(nrow(resultado), 4)
  })
})

test_that("parsear_cie10_minsal con mock extrae capitulo correctamente", {
  skip_on_cran()
  skip_if_not_installed("readxl")
  skip_if_not_installed("writexl")

  withr::with_tempdir({
    mock_data <- data.frame(
      codigo = c("E11.0", "I50.9", "A00.0", "Z99.9"),
      descripcion = c("Desc E11", "Desc I50", "Desc A00", "Desc Z99"),
      stringsAsFactors = FALSE
    )

    mock_path <- "mock_cie10.xlsx"
    writexl::write_xlsx(mock_data, mock_path)

    resultado <- ciecl:::parsear_cie10_minsal(mock_path)

    expect_true("capitulo" %in% names(resultado))
    expect_equal(resultado$capitulo[1], "E11")
    expect_equal(resultado$capitulo[2], "I50")
    expect_equal(resultado$capitulo[3], "A00")
    expect_equal(resultado$capitulo[4], "Z99")
  })
})

test_that("parsear_cie10_minsal detecta codigo con tilde en nombre columna", {
  skip_on_cran()
  skip_if_not_installed("readxl")
  skip_if_not_installed("writexl")

  withr::with_tempdir({
    # Columna con tilde: codigo -> código
    mock_data <- data.frame(
      `código` = c("E11.0", "I50.9"),
      `descripción` = c("Diabetes", "Insuficiencia cardiaca"),
      stringsAsFactors = FALSE,
      check.names = FALSE
    )

    mock_path <- "mock_cie10.xlsx"
    writexl::write_xlsx(mock_data, mock_path)

    resultado <- ciecl:::parsear_cie10_minsal(mock_path)

    expect_s3_class(resultado, "tbl_df")
    expect_true("codigo" %in% names(resultado))
    expect_equal(nrow(resultado), 2)
  })
})

test_that("parsear_cie10_minsal detecta columna 'clave' como codigo", {
  skip_on_cran()
  skip_if_not_installed("readxl")
  skip_if_not_installed("writexl")

  withr::with_tempdir({
    mock_data <- data.frame(
      clave = c("E11.0", "I50.9"),
      titulo = c("Diabetes", "Insuficiencia cardiaca"),
      stringsAsFactors = FALSE
    )

    mock_path <- "mock_cie10.xlsx"
    writexl::write_xlsx(mock_data, mock_path)

    resultado <- ciecl:::parsear_cie10_minsal(mock_path)

    expect_s3_class(resultado, "tbl_df")
    expect_equal(nrow(resultado), 2)
  })
})

test_that("parsear_cie10_minsal filtra codigos con menos de 3 caracteres", {
  skip_on_cran()
  skip_if_not_installed("readxl")
  skip_if_not_installed("writexl")

  withr::with_tempdir({
    mock_data <- data.frame(
      codigo = c("E11.0", "AB", "I", "C50.9"),  # AB e I deben ser filtrados
      descripcion = c("Desc1", "Desc2", "Desc3", "Desc4"),
      stringsAsFactors = FALSE
    )

    mock_path <- "mock_cie10.xlsx"
    writexl::write_xlsx(mock_data, mock_path)

    resultado <- ciecl:::parsear_cie10_minsal(mock_path)

    expect_equal(nrow(resultado), 2)  # Solo E11.0 y C50.9
    expect_true(all(nchar(resultado$codigo) >= 3))
  })
})

test_that("parsear_cie10_minsal filtra filas con codigo NA", {
  skip_on_cran()
  skip_if_not_installed("readxl")
  skip_if_not_installed("writexl")

  withr::with_tempdir({
    mock_data <- data.frame(
      codigo = c("E11.0", NA, "I50.9", NA),
      descripcion = c("Desc1", "Desc2", "Desc3", "Desc4"),
      stringsAsFactors = FALSE
    )

    mock_path <- "mock_cie10.xlsx"
    writexl::write_xlsx(mock_data, mock_path)

    resultado <- ciecl:::parsear_cie10_minsal(mock_path)

    expect_equal(nrow(resultado), 2)  # Solo E11.0 e I50.9
  })
})

test_that("parsear_cie10_minsal limpia espacios en codigo y descripcion", {
  skip_on_cran()
  skip_if_not_installed("readxl")
  skip_if_not_installed("writexl")

  withr::with_tempdir({
    mock_data <- data.frame(
      codigo = c("  E11.0  ", "I50.9 "),
      descripcion = c("  Diabetes  ", " Insuficiencia "),
      stringsAsFactors = FALSE
    )

    mock_path <- "mock_cie10.xlsx"
    writexl::write_xlsx(mock_data, mock_path)

    resultado <- ciecl:::parsear_cie10_minsal(mock_path)

    expect_equal(resultado$codigo[1], "E11.0")
    expect_equal(resultado$codigo[2], "I50.9")
    expect_equal(resultado$descripcion[1], "Diabetes")
    expect_equal(resultado$descripcion[2], "Insuficiencia")
  })
})

test_that("parsear_cie10_minsal detecta simbolo daga", {
  skip_on_cran()
  skip_if_not_installed("readxl")
  skip_if_not_installed("writexl")

  withr::with_tempdir({
    mock_data <- data.frame(
      codigo = c("E11.0\u2020", "I50.9"),  # \u2020 es simbolo daga
      descripcion = c("Diabetes daga", "Insuficiencia"),
      stringsAsFactors = FALSE
    )

    mock_path <- "mock_cie10.xlsx"
    writexl::write_xlsx(mock_data, mock_path)

    resultado <- ciecl:::parsear_cie10_minsal(mock_path)

    expect_true("es_daga" %in% names(resultado))
    expect_true(resultado$es_daga[1])
    expect_false(resultado$es_daga[2])
  })
})

test_that("parsear_cie10_minsal detecta simbolo asterisco", {
  skip_on_cran()
  skip_if_not_installed("readxl")
  skip_if_not_installed("writexl")

  withr::with_tempdir({
    mock_data <- data.frame(
      codigo = c("E11.0*", "I50.9"),  # * es simbolo cruz
      descripcion = c("Diabetes cruz", "Insuficiencia"),
      stringsAsFactors = FALSE
    )

    mock_path <- "mock_cie10.xlsx"
    writexl::write_xlsx(mock_data, mock_path)

    resultado <- ciecl:::parsear_cie10_minsal(mock_path)

    expect_true("es_cruz" %in% names(resultado))
    expect_true(resultado$es_cruz[1])
    expect_false(resultado$es_cruz[2])
  })
})

test_that("parsear_cie10_minsal incluye columna categoria si existe", {
  skip_on_cran()
  skip_if_not_installed("readxl")
  skip_if_not_installed("writexl")

  withr::with_tempdir({
    mock_data <- data.frame(
      codigo = c("E11.0", "I50.9"),
      descripcion = c("Diabetes", "Insuficiencia"),
      categoria = c("Endocrinas", "Circulatorias"),
      stringsAsFactors = FALSE
    )

    mock_path <- "mock_cie10.xlsx"
    writexl::write_xlsx(mock_data, mock_path)

    resultado <- ciecl:::parsear_cie10_minsal(mock_path)

    expect_true("categoria" %in% names(resultado))
  })
})

# ============================================================
# PRUEBAS ADICIONALES PARA COVERAGE (branches faltantes)
# ============================================================

test_that("parsear_cie10_minsal funciona sin columnas opcionales", {
  skip_on_cran()
  skip_if_not_installed("readxl")
  skip_if_not_installed("writexl")

  withr::with_tempdir({
    # Solo codigo + descripcion, sin categoria/inclusion/exclusion
    df <- data.frame(
      codigo = c("A00", "A01.0", "B02.9"),
      descripcion = c("Colera", "Fiebre tifoidea", "Zoster sin complicaciones"),
      stringsAsFactors = FALSE
    )
    writexl::write_xlsx(df, "minimal.xlsx")

    resultado <- ciecl:::parsear_cie10_minsal("minimal.xlsx")

    expect_s3_class(resultado, "tbl_df")
    expect_equal(nrow(resultado), 3)
    expect_true("codigo" %in% names(resultado))
    expect_true("descripcion" %in% names(resultado))
    # Columnas opcionales no deben estar
    expect_false("categoria" %in% names(resultado))
    expect_false("inclusion" %in% names(resultado))
    expect_false("exclusion" %in% names(resultado))
  })
})

test_that("parsear_cie10_minsal maneja codigos sin match de capitulo", {
  skip_on_cran()
  skip_if_not_installed("readxl")
  skip_if_not_installed("writexl")

  withr::with_tempdir({
    df <- data.frame(
      codigo = c("A00", "ZZZ"),
      descripcion = c("Colera", "Codigo raro"),
      stringsAsFactors = FALSE
    )
    writexl::write_xlsx(df, "raro.xlsx")

    resultado <- ciecl:::parsear_cie10_minsal("raro.xlsx")

    # "ZZZ" no matchea ^[A-Z]\d{1,2} -> capitulo NA
    fila_zzz <- resultado[resultado$codigo == "ZZZ", ]
    if (nrow(fila_zzz) > 0) {
      expect_true(is.na(fila_zzz$capitulo))
    }
    # A00 si debe tener capitulo
    fila_a00 <- resultado[resultado$codigo == "A00", ]
    expect_equal(fila_a00$capitulo, "A00")
  })
})

test_that("parsear_cie10_minsal filtra filas con NA en codigo y descripcion corta", {
  skip_on_cran()
  skip_if_not_installed("readxl")
  skip_if_not_installed("writexl")

  withr::with_tempdir({
    df <- data.frame(
      codigo = c("A00", NA, "AB", "B01.0"),
      descripcion = c("Colera", NA, "Corta", "Tifoidea"),
      stringsAsFactors = FALSE
    )
    writexl::write_xlsx(df, "filtro.xlsx")

    resultado <- ciecl:::parsear_cie10_minsal("filtro.xlsx")

    # NA en codigo se filtra, "AB" (nchar < 3) se filtra
    expect_equal(nrow(resultado), 2)
    expect_true(all(resultado$codigo %in% c("A00", "B01.0")))
  })
})

test_that("generar_cie10_cl emite mensaje Parseando antes de error", {
  skip_on_cran()
  skip_if_not_installed("usethis")
  skip_if_not_installed("readxl")
  skip_if_not_installed("writexl")

  withr::with_tempdir({
    df <- data.frame(
      codigo = c("A00", "B01.0", "C02.1"),
      descripcion = c("Colera", "Tifoidea", "Tumor"),
      stringsAsFactors = FALSE
    )
    writexl::write_xlsx(df, "test_cie10.xlsx")

    # generar_cie10_cl llama usethis::use_data() que requiere estar en un paquete,
    # pero el message "Parseando" se emite antes de eso
    msgs <- character()
    tryCatch(
      withCallingHandlers(
        ciecl:::generar_cie10_cl(archivo_path = "test_cie10.xlsx"),
        message = function(m) {
          msgs <<- c(msgs, conditionMessage(m))
          invokeRestart("muffleMessage")
        }
      ),
      error = function(e) NULL
    )
    expect_true(any(grepl("Parseando", msgs)))
  })
})
