# ---- .parse_perc -----------------------------------------------------------

test_that(".parse_perc parses standard intervals", {
  b <- widr:::.parse_perc("p90p100")
  expect_equal(b$lo, 0.9)
  expect_equal(b$hi, 1.0)
})

test_that(".parse_perc parses decimal percentiles", {
  b <- widr:::.parse_perc("p99.9p100")
  expect_equal(b$lo, 0.999)
  expect_equal(b$hi, 1.0)
})

test_that(".parse_perc returns NULL on bad input", {
  expect_null(widr:::.parse_perc("bad"))
  expect_null(widr:::.parse_perc(""))
})

# ---- .filter_data ----------------------------------------------------------

test_that(".filter_data restricts to requested country", {
  d <- .wid(countries = c("US","FR"))
  f <- widr:::.filter_data(d, NULL, "US")
  expect_true(all(f$country == "US"))
})

test_that(".filter_data errors when no rows remain", {
  expect_error(widr:::.filter_data(.wid(), NULL, "XX"), "No data after filtering")
})

# ---- wid_gini --------------------------------------------------------------

test_that("wid_gini errors on non-wid_df", {
  expect_error(wid_gini(data.frame()), "wid_df")
})

test_that("wid_gini errors on empty wid_df", {
  expect_error(wid_gini(widr:::.wid_df()), "empty")
})

test_that("wid_gini errors on non-share series", {
  expect_error(wid_gini(.wid(type = "t")), "share")
})

test_that("wid_gini returns gini in [0,1]", {
  g <- wid_gini(.wid_dist())
  expect_true(all(g$gini >= 0 & g$gini <= 1))
  expect_named(g, c("country","year","gini"))
})

test_that("wid_gini warns and drops rows with unparseable percentile codes", {
  d              <- .wid_dist()
  d$percentile[1L] <- "bad"
  expect_warning(out <- wid_gini(d), "dropped")
  expect_true(nrow(out) >= 1L)
})

test_that("wid_gini filters by country", {
  d <- rbind(.wid_dist("US"), .wid_dist("FR"))
  g <- wid_gini(d, country = "US")
  expect_true(all(g$country == "US"))
})

test_that("wid_gini produces one row per country-year", {
  d <- rbind(.wid_dist("US", 2019L), .wid_dist("US", 2020L),
             .wid_dist("FR", 2020L))
  g <- wid_gini(d)
  expect_equal(nrow(g), 3L)
})

test_that("wid_gini returns 0 for perfectly equal distribution", {
  d <- .wid_dist()
  d$value <- rep(1/3, 3L)
  d$percentile <- c("p0p33", "p33p66", "p66p100")
  # All shares equal -> Gini should be near 0
  g <- suppressWarnings(wid_gini(d))
  expect_true(g$gini >= 0)
})

# ---- wid_top_share ---------------------------------------------------------

test_that("wid_top_share errors on non-share series", {
  expect_error(wid_top_share(.wid(type = "t")), "share")
})

test_that("wid_top_share errors when target percentile absent", {
  expect_error(wid_top_share(.wid_dist(), top = 0.001), "No percentile")
})

test_that("wid_top_share returns correct structure for top 10%", {
  d   <- .wid_dist()
  out <- wid_top_share(d, top = 0.1)
  expect_named(out, c("country","year","top","share"))
  expect_equal(out$top,   0.1)
  expect_equal(out$share, 0.4)
})

test_that("wid_top_share returns one row per country-year", {
  d <- rbind(.wid_dist("US", 2019L), .wid_dist("US", 2020L))
  expect_equal(nrow(wid_top_share(d, top = 0.1)), 2L)
})

# ---- wid_percentile_ratio --------------------------------------------------

test_that("wid_percentile_ratio errors on non-threshold series", {
  expect_error(wid_percentile_ratio(.wid(type = "s")), "threshold")
})

test_that("wid_percentile_ratio computes correct ratio", {
  r <- wid_percentile_ratio(.wid_t())   # p90 / p10 = 200000 / 10000 = 20
  expect_equal(r$ratio, 20, tolerance = 1e-9)
  expect_named(r, c("country","year","ratio"))
})

test_that("wid_percentile_ratio errors when percentiles not found", {
  d <- .wid_t(); d$percentile <- rep("p50", 3L)
  expect_error(wid_percentile_ratio(d), "No matching")
})

test_that("wid_percentile_ratio respects custom numerator/denominator", {
  r <- wid_percentile_ratio(.wid_t(), numerator = "p90", denominator = "p50")
  expect_equal(r$ratio, 200000 / 50000, tolerance = 1e-9)
})

test_that("wid_percentile_ratio returns one row per country-year", {
  d1 <- .wid_t(); d1$year <- 2020L
  d2 <- .wid_t(); d2$year <- 2021L
  d  <- rbind(d1, d2)
  expect_equal(nrow(wid_percentile_ratio(d)), 2L)
})