#!/usr/bin/env bash

prompt_read_default() {
  local label="$1"
  local default_value="${2:-}"
  local answer=""

  if [[ -n "$default_value" ]]; then
    read -r -p "$label [$default_value] : " answer
    printf '%s\n' "${answer:-$default_value}"
  else
    read -r -p "$label : " answer
    printf '%s\n' "$answer"
  fi
}

prompt_select_number() {
  local label="$1"
  local min_value="$2"
  local max_value="$3"
  local answer=""

  while true; do
    read -r -p "$label [$min_value-$max_value] : " answer
    if [[ "$answer" =~ ^[0-9]+$ ]] && (( answer >= min_value && answer <= max_value )); then
      printf '%s\n' "$answer"
      return 0
    fi
    ui_warn "Choix invalide"
  done
}

prompt_read_csv_default() {
  local label="$1"
  local default_value="$2"
  local answer=""

  read -r -p "$label [$default_value] : " answer
  printf '%s\n' "${answer:-$default_value}"
}

prompt_confirm_default() {
  local label="$1"
  local default_answer="${2:-n}"
  local answer=""
  local prompt_suffix="[y/N]"

  if [[ "$default_answer" =~ ^([Yy]|yes|YES|Yes)$ ]]; then
    prompt_suffix="[Y/n]"
  fi

  while true; do
    read -r -p "$label $prompt_suffix : " answer
    answer="${answer:-$default_answer}"

    case "$answer" in
      y|Y|yes|YES)
        printf 'yes\n'
        return 0
        ;;
      n|N|no|NO)
        printf 'no\n'
        return 0
        ;;
    esac

    ui_warn "Repondre par y ou n"
  done
}

prompt_select_from_list() {
  local label="$1"
  shift
  local options=("$@")
  local index=1
  local selection=""

  for selection in "${options[@]}"; do
    printf ' %d. %s\n' "$index" "$selection" >&2
    index=$((index + 1))
  done

  selection="$(prompt_select_number "$label" 1 "${#options[@]}")"
  printf '%s\n' "${options[$((selection - 1))]}"
}

prompt_select_described_from_list() {
  local label="$1"
  shift
  local entries=("$@")
  local entry=""
  local option=""
  local description=""
  local options=()
  local index=1
  local selection=""

  for entry in "${entries[@]}"; do
    option="${entry%%|*}"
    description="${entry#*|}"
    options+=("$option")
    printf ' %d. %s\n' "$index" "$option" >&2
    printf '    %s\n' "$description" >&2
    index=$((index + 1))
  done

  selection="$(prompt_select_number "$label" 1 "${#options[@]}")"
  printf '%s\n' "${options[$((selection - 1))]}"
}

prompt_select_multiple_from_list() {
  local label="$1"
  local default_indices="${2:-}"
  local labels_csv="$3"
  shift 3
  local values=("$@")
  local labels=()
  local answer=""
  local raw_index=""
  local selected_values=""
  local index=1

  IFS=$'\n' read -r -d '' -a labels < <(printf '%s\0' "$labels_csv")

  for raw_index in "${labels[@]}"; do
    printf ' %d. %s\n' "$index" "$raw_index" >&2
    index=$((index + 1))
  done

  read -r -p "$label [${default_indices:-aucun}] : " answer
  answer="${answer:-$default_indices}"

  if [[ -z "$answer" ]]; then
    printf '\n'
    return 0
  fi

  while IFS= read -r raw_index; do
    [[ -n "$raw_index" ]] || continue
    raw_index="$(printf '%s' "$raw_index" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
    if [[ ! "$raw_index" =~ ^[0-9]+$ ]] || (( raw_index < 1 || raw_index > ${#values[@]} )); then
      ui_warn "Index ignore : $raw_index"
      continue
    fi
    selected_values="${selected_values:+$selected_values,}${values[$((raw_index - 1))]}"
  done < <(printf '%s\n' "$answer" | tr ',' '\n')

  printf '%s\n' "$selected_values"
}
