current_dir <- normalizePath(getwd(), winslash = "/", mustWork = TRUE)
project_root <- if (basename(current_dir) == "scripts") {
  dirname(current_dir)
} else if (dir.exists(file.path(current_dir, "scripts")) &&
           dir.exists(file.path(current_dir, "data"))) {
  current_dir
} else {
  dirname(current_dir)
}
setwd(project_root)
dir.create(file.path(project_root, "data"), showWarnings = FALSE)
dir.create(file.path(project_root, "outputs"), showWarnings = FALSE)
local_lib <- file.path(project_root, "r-lib")
if (dir.exists(local_lib)) {
  .libPaths(c(local_lib, .libPaths()))
}
local_lib <- file.path(getwd(), "r-lib")
.libPaths(c(local_lib, .libPaths()))

###### Voting for democracy - coding measures

library(dplyr)
library(forcats)
library(here)


# setup
setwd(project_root)
dir.create(file.path(project_root, "data"), showWarnings = FALSE)
dir.create(file.path(project_root, "outputs"), showWarnings = FALSE)
print(getwd())
set.seed(2025) 

# read respondent-level data
us <- read.csv(file.path(project_root, "data", "democ_cultures_us.csv"))
sk <- read.csv(file.path(project_root, "data", "democ_cultures_sk.csv"))
pl <- read.csv(file.path(project_root, "data", "democ_cultures_pl.csv"))


## drop speedsters

rt_med <- median(pl$Response_duration_seconds, na.rm = TRUE)
rt_cut <- 0.40 * rt_med 
drop_ids <- pl %>%
 dplyr::filter(Response_duration_seconds < rt_cut) %>%
 dplyr::pull(RespondentID)
length(drop_ids) 
pl <- dplyr::filter(pl, !RespondentID %in% drop_ids)

rt_med <- median(sk$Response_duration_seconds, na.rm = TRUE)
rt_cut <- 0.40 * rt_med 
drop_ids <- sk %>%
 dplyr::filter(Response_duration_seconds < rt_cut) %>%
 dplyr::pull(RespondentID)
length(drop_ids) 
sk <- dplyr::filter(sk, !RespondentID %in% drop_ids)

rt_med <- median(us$Response_duration_seconds, na.rm = TRUE)
rt_cut <- 0.40 * rt_med 
drop_ids <- us %>%
 dplyr::filter(Response_duration_seconds < rt_cut) %>%
 dplyr::pull(RespondentID)
length(drop_ids) 
us <- dplyr::filter(us, !RespondentID %in% drop_ids)


#### Recode demogs----


## Add country tag
us$country <- "US"
sk$country <- "KR" 
pl$country <- "PL"

## Gender 
us$gender_male <- ifelse(us$gender == 1, 1, 0)
sk$gender_male <- ifelse(sk$gender == 1, 1, 0)
pl$gender_male <- ifelse(pl$gender == 1, 1, 0)

## Education 5-level factor 
us <- us %>%
 dplyr::mutate(educ_5f = dplyr::case_when(
 education %in% 1:4 ~ "less high school",
 education == 5 ~ "high school grad",
 education == 6 ~ "some college/2yr",
 education == 7 ~ "bachelors",
 education == 8 ~ "postgrad",
 TRUE ~ NA_character_)
 )

sk <- sk %>%
 dplyr::mutate(educ_5f = dplyr::case_when(
 education %in% 1:4 ~ "less high school",
 education == 5 ~ "high school grad",
 education == 6 ~ "some college/2yr",
 education == 7 ~ "bachelors",
 education == 8 ~ "postgrad",
 TRUE ~ NA_character_)
 )

pl <- pl %>%
 dplyr::mutate(educ_5f = dplyr::case_when(
 education %in% 1:4 ~ "less high school",
 education == 5 ~ "high school grad",
 education == 6 ~ "some college/2yr",
 education == 7 ~ "bachelors",
 education == 8 ~ "postgrad",
 TRUE ~ NA_character_)
 )

## Income: harmonize to 5 cats + Refused, per-country coding
# US: 1–5; PL: 6–10; KR: 11–15; 98 = Refused (in all)
us <- us %>%
 mutate(income_cat = case_when(
 hh_income == 1 ~ "Lowest",
 hh_income == 2 ~ "Low",
 hh_income == 3 ~ "Middle",
 hh_income == 4 ~ "High",
 hh_income == 5 ~ "Highest",
 hh_income == 98 ~ "Refused",
 TRUE ~ NA_character_))

pl <- pl %>%
 mutate(
 income_cat = case_when(
  hh_income == 6 ~ "Lowest",
  hh_income == 7 ~ "Low",
  hh_income == 8 ~ "Middle",
  hh_income == 9 ~ "High",
  hh_income == 10 ~ "Highest",
  hh_income == 98 ~ "Refused",
  TRUE ~ NA_character_
 )
 )

sk <- sk %>%
 mutate(
 income_cat = case_when(
  hh_income == 11 ~ "Lowest",
  hh_income == 12 ~ "Low",
  hh_income == 13 ~ "Middle",
  hh_income == 14 ~ "High",
  hh_income == 15 ~ "Highest",
  hh_income == 98 ~ "Refused",
  TRUE ~ NA_character_
 )
 )

## Region: use per-country region variables
us$region_pool <- us$cens_division
sk$region_pool <- sk$region_kr
pl$region_pool <- pl$region_pl

## Standardize factor levels before binding
lvl_income <- c("Lowest","Low","Middle","High","Highest","Refused")
lvl_educ <- c("less high school","high school grad","some college/2yr","bachelors","postgrad")

us$income_cat <- factor(us$income_cat, levels = lvl_income)
sk$income_cat <- factor(sk$income_cat, levels = lvl_income)
pl$income_cat <- factor(pl$income_cat, levels = lvl_income)

us$educ_5f <- factor(us$educ_5f, levels = lvl_educ)
sk$educ_5f <- factor(sk$educ_5f, levels = lvl_educ)
pl$educ_5f <- factor(pl$educ_5f, levels = lvl_educ)



#### Code indices----


## Democracy–autocracy preference

var_names <- c("sup_dem1", "sup_dem2", "sup_dem3", "sup_dem4")

pl$demaut_pref <- scale(pl$sup_dem1 + pl$sup_dem3 - (pl$sup_dem2 + pl$sup_dem4))[, 1]
sk$demaut_pref <- scale(sk$sup_dem1 + sk$sup_dem3 - (sk$sup_dem2 + sk$sup_dem4))[, 1]
us$demaut_pref <- scale(us$sup_dem1 + us$sup_dem3 - (us$sup_dem2 + us$sup_dem4))[, 1]

## Support liberal democracy

var_names <- c("sup_ld_1","sup_ld_2","sup_ld_3","sup_ld_4","sup_ld_5","sup_ld_6","sup_ld_7")
var_names_loo_media <- c("sup_ld_2","sup_ld_3","sup_ld_4","sup_ld_5","sup_ld_6","sup_ld_7")
var_names_loo_vote <- c("sup_ld_1","sup_ld_2","sup_ld_4","sup_ld_5","sup_ld_6","sup_ld_7")
var_names_loo_jud <- c("sup_ld_1","sup_ld_2","sup_ld_3","sup_ld_4","sup_ld_6","sup_ld_7")

pl$sup_ldem <- scale(rowSums(pl[, var_names]))[, 1] * -1
sk$sup_ldem <- scale(rowSums(sk[, var_names]))[, 1] * -1
us$sup_ldem <- scale(rowSums(us[, var_names]))[, 1] * -1

pl$sup_ldem_loo_media <- scale(rowSums(pl[, var_names_loo_media]))[, 1] * -1
sk$sup_ldem_loo_media <- scale(rowSums(sk[, var_names_loo_media]))[, 1] * -1
us$sup_ldem_loo_media <- scale(rowSums(us[, var_names_loo_media]))[, 1] * -1

pl$sup_ldem_loo_vote <- scale(rowSums(pl[, var_names_loo_vote]))[, 1] * -1
sk$sup_ldem_loo_vote <- scale(rowSums(sk[, var_names_loo_vote]))[, 1] * -1
us$sup_ldem_loo_vote <- scale(rowSums(us[, var_names_loo_vote]))[, 1] * -1

pl$sup_ldem_loo_jud <- scale(rowSums(pl[, var_names_loo_jud]))[, 1] * -1
sk$sup_ldem_loo_jud <- scale(rowSums(sk[, var_names_loo_jud]))[, 1] * -1
us$sup_ldem_loo_jud <- scale(rowSums(us[, var_names_loo_jud]))[, 1] * -1

## Political trust

var_names <- c("trust_leg","trust_parl","trust_civ","trust_part")

pl$inst_trust <- scale(rowSums(pl[, var_names]))[, 1]
sk$inst_trust <- scale(rowSums(sk[, var_names]))[, 1]
us$inst_trust <- scale(rowSums(us[, var_names]))[, 1]

## Political tolerance

var_names <- c("pol_tol_1","pol_tol_2","pol_tol_3")

pl$pol_tolerance <- scale(rowSums(pl[, var_names]))[, 1] * -1
sk$pol_tolerance <- scale(rowSums(sk[, var_names]))[, 1] * -1
us$pol_tolerance <- scale(rowSums(us[, var_names]))[, 1] * -1

## Conformity–autonomy values (ipsatized across the 8 items)

var_names <- c("val_conf_1","val_trad_1","val_selfd_1","val_stim_1",
    "val_conf_2","val_trad_2","val_selfd_2","val_stim_2")
ips_names <- paste0(var_names, "_ips")
conf_items <- c("val_conf_1","val_trad_1","val_conf_2","val_trad_2")
auto_items <- c("val_selfd_1","val_stim_1","val_selfd_2","val_stim_2")

# PL
res_mean_pl <- rowMeans(pl[, var_names], na.rm = TRUE)
cav_ips_pl <- sapply(pl[, var_names], function(x) x - res_mean_pl)
colnames(cav_ips_pl) <- ips_names
pl$conformity <- rowMeans(cav_ips_pl[, paste0(conf_items, "_ips"), drop = FALSE],
       na.rm = TRUE)
pl$autonomy <- rowMeans(cav_ips_pl[, paste0(auto_items, "_ips"), drop = FALSE],
       na.rm = TRUE)
pl$auth_values  <- scale(pl$conformity - pl$autonomy)[, 1]
pl$autonomy_values <- scale(pl$autonomy - pl$conformity)[, 1]

# SK
res_mean_sk <- rowMeans(sk[, var_names], na.rm = TRUE)
cav_ips_sk <- sapply(sk[, var_names], function(x) x - res_mean_sk)
colnames(cav_ips_sk) <- ips_names
sk$conformity <- rowMeans(cav_ips_sk[, paste0(conf_items, "_ips"), drop = FALSE],
       na.rm = TRUE)
sk$autonomy <- rowMeans(cav_ips_sk[, paste0(auto_items, "_ips"), drop = FALSE],
       na.rm = TRUE)
sk$auth_values  <- scale(sk$conformity - sk$autonomy)[, 1]
sk$autonomy_values <- scale(sk$autonomy - sk$conformity)[, 1]

# US
res_mean_us <- rowMeans(us[, var_names], na.rm = TRUE)
cav_ips_us <- sapply(us[, var_names], function(x) x - res_mean_us)
colnames(cav_ips_us) <- ips_names
us$conformity <- rowMeans(cav_ips_us[, paste0(conf_items, "_ips"), drop = FALSE],
       na.rm = TRUE)
us$autonomy <- rowMeans(cav_ips_us[, paste0(auto_items, "_ips"), drop = FALSE],
       na.rm = TRUE)
us$auth_values  <- scale(us$conformity - us$autonomy)[, 1]
us$autonomy_values <- scale(us$autonomy - us$conformity)[, 1]

## Emancipative values

# PL
pl$child_no_obed <- 1 - pl$child_obed
pl$autonomy_z <- as.numeric(scale(pl$child_ind + pl$child_imag + pl$child_no_obed))
pl$equality_rev <- rowMeans(pl[, c("gend_eq_1","gend_eq_2","gend_eq_3")], na.rm = TRUE)
pl$equality_z <- as.numeric(scale(6 - pl$equality_rev))
pl$choice_z  <- as.numeric(scale(pl$gay_just + pl$abort_just + pl$divorc_just))

v1_pl <- dplyr::case_when(
 (pl$post_mat_11 == 2 & pl$post_mat_12 == 4) | (pl$post_mat_11 == 4 & pl$post_mat_12 == 2) ~ 3,
 (pl$post_mat_11 == 2 & pl$post_mat_12 != 4) | (pl$post_mat_11 == 4 & pl$post_mat_12 != 2) ~ 2,
 (pl$post_mat_11 != 2 & pl$post_mat_12 == 4) | (pl$post_mat_11 != 4 & pl$post_mat_12 == 2) ~ 1,
 (pl$post_mat_11 != 2 & pl$post_mat_11 != 4) | (pl$post_mat_12 != 4 & pl$post_mat_12 != 2) ~ 0,
 TRUE ~ NA_real_
)
v2_pl <- dplyr::case_when(
 (pl$post_mat_21 == 3 & pl$post_mat_22 == 4) | (pl$post_mat_21 == 4 & pl$post_mat_22 == 3) ~ 3,
 (pl$post_mat_21 == 3 & pl$post_mat_22 != 4) | (pl$post_mat_21 == 4 & pl$post_mat_22 != 3) ~ 2,
 (pl$post_mat_21 != 3 & pl$post_mat_22 == 4) | (pl$post_mat_21 != 4 & pl$post_mat_22 == 3) ~ 1,
 (pl$post_mat_21 != 3 & pl$post_mat_21 != 4) | (pl$post_mat_22 != 4 & pl$post_mat_22 != 3) ~ 0,
 TRUE ~ NA_real_
)
pl$voice_z <- as.numeric(scale(v1_pl + v2_pl))
pl$emancip_val <- as.numeric(scale(rowMeans(
 pl[, c("autonomy_z","equality_z","choice_z","voice_z")], na.rm = TRUE
)))

# SK
sk$child_no_obed <- 1 - sk$child_obed
sk$autonomy_z <- as.numeric(scale(sk$child_ind + sk$child_imag + sk$child_no_obed))
sk$equality_rev <- rowMeans(sk[, c("gend_eq_1","gend_eq_2","gend_eq_3")], na.rm = TRUE)
sk$equality_z <- as.numeric(scale(6 - sk$equality_rev))
sk$choice_z  <- as.numeric(scale(sk$gay_just + sk$abort_just + sk$divorc_just))

v1_sk <- dplyr::case_when(
 (sk$post_mat_11 == 2 & sk$post_mat_12 == 4) | (sk$post_mat_11 == 4 & sk$post_mat_12 == 2) ~ 3,
 (sk$post_mat_11 == 2 & sk$post_mat_12 != 4) | (sk$post_mat_11 == 4 & sk$post_mat_12 != 2) ~ 2,
 (sk$post_mat_11 != 2 & sk$post_mat_12 == 4) | (sk$post_mat_11 != 4 & sk$post_mat_12 == 2) ~ 1,
 (sk$post_mat_11 != 2 & sk$post_mat_11 != 4) | (sk$post_mat_12 != 4 & sk$post_mat_12 != 2) ~ 0,
 TRUE ~ NA_real_
)
v2_sk <- dplyr::case_when(
 (sk$post_mat_21 == 3 & sk$post_mat_22 == 4) | (sk$post_mat_21 == 4 & sk$post_mat_22 == 3) ~ 3,
 (sk$post_mat_21 == 3 & sk$post_mat_22 != 4) | (sk$post_mat_21 == 4 & sk$post_mat_22 != 3) ~ 2,
 (sk$post_mat_21 != 3 & sk$post_mat_22 == 4) | (sk$post_mat_21 != 4 & sk$post_mat_22 == 3) ~ 1,
 (sk$post_mat_21 != 3 & sk$post_mat_21 != 4) | (sk$post_mat_22 != 4 & sk$post_mat_22 != 3) ~ 0,
 TRUE ~ NA_real_
)
sk$voice_z <- as.numeric(scale(v1_sk + v2_sk))
sk$emancip_val <- as.numeric(scale(rowMeans(
 sk[, c("autonomy_z","equality_z","choice_z","voice_z")], na.rm = TRUE
)))

# US
us$child_no_obed <- 1 - us$child_obed
us$autonomy_z <- as.numeric(scale(us$child_ind + us$child_imag + us$child_no_obed))
us$equality_rev <- rowMeans(us[, c("gend_eq_1","gend_eq_2","gend_eq_3")], na.rm = TRUE)
us$equality_z <- as.numeric(scale(6 - us$equality_rev))
us$choice_z  <- as.numeric(scale(us$gay_just + us$abort_just + us$divorc_just))

v1_us <- dplyr::case_when(
 (us$post_mat_11 == 2 & us$post_mat_12 == 4) | (us$post_mat_11 == 4 & us$post_mat_12 == 2) ~ 3,
 (us$post_mat_11 == 2 & us$post_mat_12 != 4) | (us$post_mat_11 == 4 & us$post_mat_12 != 2) ~ 2,
 (us$post_mat_11 != 2 & us$post_mat_12 == 4) | (us$post_mat_11 != 4 & us$post_mat_12 == 2) ~ 1,
 (us$post_mat_11 != 2 & us$post_mat_11 != 4) | (us$post_mat_12 != 4 & us$post_mat_12 != 2) ~ 0,
 TRUE ~ NA_real_
)
v2_us <- dplyr::case_when(
 (us$post_mat_21 == 3 & us$post_mat_22 == 4) | (us$post_mat_21 == 4 & us$post_mat_22 == 3) ~ 3,
 (us$post_mat_21 == 3 & us$post_mat_22 != 4) | (us$post_mat_21 == 4 & us$post_mat_22 != 3) ~ 2,
 (us$post_mat_21 != 3 & us$post_mat_22 == 4) | (us$post_mat_21 != 4 & us$post_mat_22 == 3) ~ 1,
 (us$post_mat_21 != 3 & us$post_mat_21 != 4) | (us$post_mat_22 != 4 & us$post_mat_22 != 3) ~ 0,
 TRUE ~ NA_real_
)
us$voice_z <- as.numeric(scale(v1_us + v2_us))
us$emancip_val <- as.numeric(scale(rowMeans(
 us[, c("autonomy_z","equality_z","choice_z","voice_z")], na.rm = TRUE
)))

## Ideology

# Gender-related ideology
pl$gend_pol_left <- scale(pl$gend_pol_1 + pl$gend_pol_2)[, 1]
sk$gend_pol_left <- scale(sk$gend_pol_1 + sk$gend_pol_2)[, 1]
us$gend_pol_left <- scale(us$gend_pol_1 + us$gend_pol_2)[, 1]

# Redistribution ideology
pl$redist_pol_left <- scale(pl$redist_1 + pl$redist_2)[, 1]
sk$redist_pol_left <- scale(sk$redist_1 + sk$redist_2)[, 1]
us$redist_pol_left <- scale(us$redist_1 + us$redist_2)[, 1]

## Party preferences 

party_labels <- c("US_Dem","US_Rep","KR_DPK","KR_PPP",
     "PL_PiS","PL_Kon","PL_KO","PL_Lew")

# Poland 

eval_mat_pl <- cbind(
 PL_PiS = pl$eval_pis_pl,
 PL_Kon = pl$eval_kon_pl,
 PL_KO = pl$eval_ko_pl,
 PL_Lew = pl$eval_lew_pl
)

labels_pl <- colnames(eval_mat_pl)
all_na_row <- apply(eval_mat_pl, 1, function(x) all(is.na(x)))
eps <- 1e-6
J_pl <- matrix(runif(length(eval_mat_pl), 0, eps), nrow = nrow(eval_mat_pl))

M_max_pl <- ifelse(is.na(eval_mat_pl), -Inf, eval_mat_pl + J_pl)
top_idx_pl <- max.col(M_max_pl, ties.method = "first")

M_min_pl  <- ifelse(is.na(eval_mat_pl), -Inf, -eval_mat_pl + J_pl)
bottom_idx_pl <- max.col(M_min_pl, ties.method = "first")

top_party_pl <- rep(NA_character_, nrow(pl))
bottom_party_pl <- rep(NA_character_, nrow(pl))

top_party_pl[!all_na_row] <- labels_pl[top_idx_pl[!all_na_row]]
bottom_party_pl[!all_na_row] <- labels_pl[bottom_idx_pl[!all_na_row]]

pl$top_party <- factor(top_party_pl, levels = party_labels)
pl$bottom_party <- factor(bottom_party_pl, levels = party_labels)

# South Korea 

eval_mat_sk <- cbind(
 KR_DPK = sk$eval_dpk_kr,
 KR_PPP = sk$eval_ppp_kr
)

labels_sk <- colnames(eval_mat_sk)
all_na_row <- apply(eval_mat_sk, 1, function(x) all(is.na(x)))
eps <- 1e-6
J_sk <- matrix(runif(length(eval_mat_sk), 0, eps), nrow = nrow(eval_mat_sk))

M_max_sk <- ifelse(is.na(eval_mat_sk), -Inf, eval_mat_sk + J_sk)
top_idx_sk <- max.col(M_max_sk, ties.method = "first")

M_min_sk  <- ifelse(is.na(eval_mat_sk), -Inf, -eval_mat_sk + J_sk)
bottom_idx_sk <- max.col(M_min_sk, ties.method = "first")

top_party_sk <- rep(NA_character_, nrow(sk))
bottom_party_sk <- rep(NA_character_, nrow(sk))

top_party_sk[!all_na_row] <- labels_sk[top_idx_sk[!all_na_row]]
bottom_party_sk[!all_na_row] <- labels_sk[bottom_idx_sk[!all_na_row]]

sk$top_party <- factor(top_party_sk, levels = party_labels)
sk$bottom_party <- factor(bottom_party_sk, levels = party_labels)

# United States

eval_mat_us <- cbind(
 US_Dem = us$eval_dem_us,
 US_Rep = us$eval_rep_us
)

labels_us <- colnames(eval_mat_us)
all_na_row <- apply(eval_mat_us, 1, function(x) all(is.na(x)))
eps <- 1e-6
J_us <- matrix(runif(length(eval_mat_us), 0, eps), nrow = nrow(eval_mat_us))

M_max_us <- ifelse(is.na(eval_mat_us), -Inf, eval_mat_us + J_us)
top_idx_us <- max.col(M_max_us, ties.method = "first")

M_min_us <- ifelse(is.na(eval_mat_us), -Inf, -eval_mat_us + J_us)
bottom_idx_us <- max.col(M_min_us, ties.method = "first")

top_party_us <- rep(NA_character_, nrow(us))
bottom_party_us <- rep(NA_character_, nrow(us))

top_party_us[!all_na_row] <- labels_us[top_idx_us[!all_na_row]]
bottom_party_us[!all_na_row] <- labels_us[bottom_idx_us[!all_na_row]]

us$top_party <- factor(top_party_us, levels = party_labels)
us$bottom_party <- factor(bottom_party_us, levels = party_labels)



#### Merge and save ----


# Bind rows after all recodes/indices
pool <- dplyr::bind_rows(us, sk, pl)

# Factorise country and region
pool$country <- factor(pool$country, levels = c("US", "KR", "PL"))
pool$region_pool <- fct_drop(factor(pool$region_pool))

# Ensure party factor levels aligned in pooled data
pool$top_party <- factor(pool$top_party, levels = party_labels)
pool$bottom_party <- factor(pool$bottom_party, levels = party_labels)

# Save analytical datasets
write.csv(us, file.path(project_root, "data", "us_analytic_v2.csv"), row.names = FALSE)
write.csv(sk, file.path(project_root, "data", "sk_analytic_v2.csv"), row.names = FALSE)
write.csv(pl, file.path(project_root, "data", "pl_analytic_v2.csv"), row.names = FALSE)
write.csv(pool, file.path(project_root, "data", "pool_analytic_v2.csv"), row.names = FALSE)
