#!/usr/bin/env bash

set -u

FAILED=0

STATUS_APT="not_detected"
STATUS_BREW="not_detected"
STATUS_CHEZMOI="not_detected"
STATUS_MISE="not_detected"
STATUS_NEOVIM="not_detected"

# Couleurs
BLUE='\e[00;34;49m'
GRAY='\e[02;37;49m'
RESET='\e[39;49;00m'

# Affiche un message stylisé sur la sortie standard
echo_bold() {
  printf '\e[1m%s\e[0m\n' "$*"
}

# Affiche un message informatif stylisé sur la sortie d'erreur
echo_info() {
  printf >&2 "\n${BLUE}󰋼 %s${RESET}\n\n" "$*"
}

echo_success() {
  printf >&2 "\e[00;01;32;49m %s${RESET}\n" "$*"
}

echo_failed() {
  printf >&2 "\e[00;01;31;49m✖ %s${RESET}\n" "$*"
}

echo_skipped() {
  printf >&2 "${GRAY}󰜺 %s${RESET}\n" "$*"
}

run() {
  local section="$1"
  local name="$2"
  shift 2

  local start=$SECONDS

  printf '⏳ [%s] %s...' "$section" "$name"

  if "$@"; then
    printf '\r\033[K'
    echo_success "[$section] $name ($((SECONDS - start))s)"
  else
    printf '\r\033[K'
    echo_failed "[$section] $name ($((SECONDS - start))s)"

    # Marque la section comme échouée
    eval "STATUS_${section^^}=failed"

    FAILED=1
    return 1
  fi
}

echo
echo_bold "🚀 Mise à jour quotidienne"
echo

# ----------------------------------------------------------------------
# Debian / Ubuntu
# ----------------------------------------------------------------------

if [[ -f /etc/os-release ]]; then
  . /etc/os-release

  if [[ "$ID" == "debian" || "$ID" == "ubuntu" ]]; then
    STATUS_APT="success"

    if ((EUID == 0)); then
      APT=(apt)
    else
      APT=(sudo apt)
    fi

    echo_info "APT"

    run APT "Mise à jour des paquets" \
      "${APT[@]}" update || true

    run APT "Mise à niveau des paquets" \
      "${APT[@]}" upgrade -y || true

    run APT "Suppression des paquets inutiles" \
      "${APT[@]}" autoremove -y || true

    run APT "Nettoyage du cache" \
      "${APT[@]}" autoclean || true
  fi
fi

# ----------------------------------------------------------------------
# Homebrew
# ----------------------------------------------------------------------

if command -v brew >/dev/null 2>&1; then
  STATUS_BREW="success"

  echo_info "Brew"

  run BREW "Mise à jour" \
    brew update || true

  run BREW "Mise à niveau des paquets" \
    brew upgrade || true
fi

# ----------------------------------------------------------------------
# chezmoi
# ----------------------------------------------------------------------

if command -v chezmoi >/dev/null 2>&1; then
  STATUS_CHEZMOI="success"

  echo_info "chezmoi"

  run CHEZMOI "Récupération de la configuration" \
    chezmoi git pull || true

  run CHEZMOI "Application de la configuration" \
    chezmoi apply -v || true
fi

# ----------------------------------------------------------------------
# mise
# ----------------------------------------------------------------------

if command -v mise >/dev/null 2>&1; then
  STATUS_MISE="success"

  echo_info "mise"

  run MISE "Mise à jour de mise" \
    mise self-update -y || true

  run MISE "Mise à jour des outils" \
    mise up || true
fi

# ----------------------------------------------------------------------
# Neovim / AstroNvim
# ----------------------------------------------------------------------

if command -v nvim >/dev/null 2>&1; then
  STATUS_NEOVIM="success"

  echo_info "Neovim / AstroNvim"

  run NEOVIM "Mise à jour d'AstroNvim" \
    nvim --headless \
    -c 'autocmd User AstroUpdateCompleted quitall' \
    -c 'AstroUpdate' \
    2>&1 || true
fi

# ----------------------------------------------------------------------
# Récapitulatif
# ----------------------------------------------------------------------

echo
echo_info "Récapitulatif"
echo

echo -n "  ► "
case "$STATUS_APT" in
success) echo_success "APT : réussi" ;;
failed) echo_failed "APT : échoué" ;;
not_detected) echo_skipped "APT : non détecté" ;;
esac

echo -n "  ► "
case "$STATUS_BREW" in
success) echo_success "Brew : réussi" ;;
failed) echo_failed "Brew : échoué" ;;
not_detected) echo_skipped "Brew : non détecté" ;;
esac

echo -n "  ► "
case "$STATUS_CHEZMOI" in
success) echo_success "chezmoi : réussi" ;;
failed) echo_failed "chezmoi : échoué" ;;
not_detected) echo_skipped "chezmoi : non détecté" ;;
esac

echo -n "  ► "
case "$STATUS_MISE" in
success) echo_success "mise : réussi" ;;
failed) echo_failed "mise : échoué" ;;
not_detected) echo_skipped "mise : non détecté" ;;
esac

echo -n "  ► "
case "$STATUS_NEOVIM" in
success) echo_success "Neovim : réussi" ;;
failed) echo_failed "Neovim : échoué" ;;
not_detected) echo_skipped "Neovim : non détecté" ;;
esac

echo

if ((FAILED)); then
  echo_failed "Mise à jour terminée avec des erreurs"
  exit 1
else
  echo_success "Toutes les mises à jour sont terminées"
  exit 0
fi
