#' @title Switch ilostat codes and labels
#' @description Gets definitions/labels for ilostat codes from ilostat dictionaries.
#' @param x A character or a factor vector or a data_frame to labelled. 
#' @param dic  A string (vector) naming ilostat dictionary or dictionaries.
#'   If \code{NULL} (default) dictionary names are taken from column names of 
#'   the data_frame. A character or a factor vector or a data_frame to labelled, 
#' @param lang a character, code for language. Available are \code{"en"} (default), 
#'        \code{"fr"} and \code{"es"}. Can be set also with options(ilostat_lang = 'fr'),
#' @param code a vector of names of the column for which code columns
#'   should be retained. Set to \code{"all"}, keep all the code.  
#' @details A character or a factor vector of codes returns a corresponding vector of definitions. 
#'   \code{label_ilostat} labels also data_frames from \code{\link{get_ilostat}}. For vectors a dictionary 
#    name have to be supplied. For data_frames dictonary names are taken from column names with suffix ".label". 
#'   "time" and "values" columns are returned as they were, so you can supply data_frame from \code{\link{get_ilostat}} 
#'   and get data_frame with definitions instead of codes.
#' @author David Bescond \email{bescond@ilo.org}
#' @return a vector or a data_frame. The suffix ".label" is added to code column names.
#' @references
#' See citation("Rilostat")
#' ilostat bulk download facility user guidelines 
#' \url{https://ilostat.ilo.org/data/bulk/}
#' @examples
#' \dontrun{
#'  dat <- get_ilostat("UNE_2UNE_SEX_AGE_NB_A", cache = FALSE)
#'  dat_lab <- label_ilostat(dat)
#'  head(dat_lab)
#'
#'
#'  # add just ref_area label
#' require(tidyverse)
#'
#' dat <- get_ilostat("UNE_TUNE_SEX_AGE_NB_A") %>% 
#'		mutate(ref_area.label = ref_area %>% 
#'		label_ilostat( "ref_area", code = "all"), .after = ref_area)
#'
#'
#'
#'  clean_ilostat_cache() 
#' }
#' @export

label_ilostat <- function(	x, 
							dic = NULL, 
							code = NULL, 
							lang = getOption('ilostat_lang','en')){
  
  if (is_tibble(x)){
    
	y <- x
	
	if(!is.null(code)){
	  
	  if(code[1] %in% 'all'){
	    
		code <- ilostat_cols_ref[ilostat_cols_ref %in% names(y) & !ilostat_cols_ref %in% c('time','obs_value')] 
	  
	  } else {
	  
		code <- code[!stringr::str_detect(code, '.label')]
		}
	
	}

    mynams <- names(y)[!(names(y) %in% c("time", "obs_value")) & names(y) %in% ilostat_cols_ref]
    
	for (i in mynams){
      
	  l <- label_ilostat(y[[i]], dic = i, lang = lang)
      
	  y[[i]] <- as.vector(unlist(l))
	  
	  names(y)[names(y) == i] <- paste0(i, '.label')	
    
	}

    # Codes added if asked
    if (!is.null(code)){ 
	  
	  code_in <- code %in% str_replace(names(y), '.label', '')
	  
	  if (!all(code_in)) {
	    
		stop("code column name(s) ", shQuote(code[!code_in])," not found on x")
	  
	  }
	          
      y_code <- x[, code, drop = FALSE]            
	  
	  y <- as_tibble(cbind(y_code, y))
	  
	  ref_cols <- ilostat_cols_ref[ilostat_cols_ref %in% colnames(y)]
	  
	  order_cols <- c(ref_cols, colnames(y)[!colnames(y) %in% ref_cols])
	  
	  y <- y %>% select(all_of(order_cols))
	
    }
	
  } else {
  
    if (is.null(dic)) stop("Dictionary information is missing")

    dic_df <- get_ilostat_dic(dic, lang = lang)

	if(stringr::str_detect(dic, 'note_')){
	
		# build dictionary lookup once
		dict <- setNames(dic_df[[2]], dic_df[[1]])

		# unique values (equivalent to levels(as.factor(x)))
		ux <- unique(x)

		# compute mapped values
		mapped <- vapply(
		  str_split(ux, "_"),
		  function(z) {
			paste(dict[z], collapse = " | ")
		  },
		  character(1)
		)

		# final mapping
		lookup <- setNames(mapped, ux)

		y <- unname(lookup[x])
			
	} else {
	
      # 
     y <- dic_df[[2]][match(x, dic_df[[1]])]  

	  
    }

  }

  # Ensure the output is tibble

  if (is.data.frame(y) && length(y) > 1) {
    
	y <- as_tibble(y)
  
  }  
  
  
  y

}
 