#!/bin/bash

# =============================================================================
# Script de sauvegarde automatique d'OpenWebUI avec interface Gum
# =============================================================================
# Ce script crée une sauvegarde du volume Docker OpenWebUI
# Interface interactive utilisant charmbracelet/gum
#
# Usage: ./backup-openwebui.sh [OPTIONS]
# Options:
#   --quiet          : Mode silencieux (pour cron)
#   --help           : Afficher cette aide
#   --env-type TYPE  : Type d'environnement (local/prod)
#   --env-file FILE  : Fichier d'environnement personnalisé
#   --backup-type TYPE : Type de sauvegarde (local/s3/both)
#   --s3-bucket BUCKET : Nom du bucket S3
#   --s3-prefix PREFIX : Préfixe S3
#   --output-dir DIR : Répertoire de destination personnalisé
#   --data-only      : Sauvegarde des données essentielles uniquement
#   --retention-period PERIOD : Période de rétention (day/week/month)
# =============================================================================

set -euo pipefail

# Vérifier que Gum est installé
if ! command -v gum &> /dev/null; then
    echo "❌ Gum n'est pas installé. Installez-le avec:"
    echo "   brew install gum  # macOS/Linux"
    echo "   ou visitez: https://github.com/charmbracelet/gum"
    exit 1
fi

# Variables
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
VOLUME_NAME=""
BACKUP_DIR="$PROJECT_ROOT/backups"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BACKUP_PREFIX="update_openwebui_"

# Chargement des variables d'environnement
load_env_file() {
    local env_file="$1"
    if [ -f "$env_file" ]; then
        gum_log "info" "Chargement des variables depuis : $env_file"
        # Exporter les variables en ignorant les commentaires et lignes vides
        while IFS= read -r line || [ -n "$line" ]; do
            # Ignorer les commentaires et lignes vides
            if [[ ! "$line" =~ ^[[:space:]]*# ]] && [[ -n "${line// }" ]]; then
                # Exporter la variable si elle n'est pas déjà définie
                local var_name="${line%%=*}"
                if [ -z "${!var_name:-}" ]; then
                    export "$line"
                fi
            fi
        done < "$env_file"
    else
        gum_log "warn" "Fichier d'environnement introuvable : $env_file"
    fi
}

# Variables par défaut
QUIET_MODE=false
BACKUP_DIR="$PROJECT_ROOT/backups"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BACKUP_PREFIX="update_openwebui_"

# Configuration interactive
CUSTOM_OUTPUT_DIR=""
SHOW_HELP=false
S3_BUCKET=""
S3_PREFIX="openwebui-backups/"
S3_ONLY=false
DATA_ONLY=false
ENV_FILE=""
ENV_TYPE=""
BACKUP_TYPE=""
RETENTION_PERIOD=""

# =============================================================================
# Fonctions utilitaires avec Gum
# =============================================================================

show_help() {
    gum format --type markdown << 'EOF'
# 💾 Script de sauvegarde OpenWebUI

## Usage
```bash
./backup-openwebui.sh [OPTIONS]
```

## Options
- `--quiet` : Mode silencieux (pour cron)
- `--help` : Afficher cette aide
- `--env-type TYPE` : Type d'environnement (local/prod)
- `--env-file FILE` : Fichier d'environnement personnalisé
- `--backup-type TYPE` : Type de sauvegarde (local/s3/both)
- `--s3-bucket BUCKET` : Nom du bucket S3
- `--s3-prefix PREFIX` : Préfixe S3 (défaut: openwebui-backups/)
- `--output-dir DIR` : Répertoire de destination personnalisé
- `--data-only` : Sauvegarde des données essentielles uniquement
- `--retention-period PERIOD` : Période de rétention (day/week/month)

## Exemples
```bash
# Sauvegarde locale complète
./backup-openwebui.sh --backup-type local

# Sauvegarde S3 avec données essentielles uniquement
./backup-openwebui.sh --backup-type s3 --s3-bucket mon-bucket --data-only

# Sauvegarde locale et S3 avec environnement de production
./backup-openwebui.sh --backup-type both --env-type prod --s3-bucket mon-bucket

# Sauvegarde quotidienne (organisée dans le répertoire day/)
./backup-openwebui.sh --backup-type local --retention-period day

# Sauvegarde hebdomadaire (organisée dans le répertoire week/)
./backup-openwebui.sh --backup-type local --retention-period week

# Sauvegarde mensuelle (organisée dans le répertoire month/)
./backup-openwebui.sh --backup-type local --retention-period month
```

## Mode interactif
Sans options, le script vous guidera interactivement pour configurer :
- Type de sauvegarde (locale, S3, ou les deux)
- Répertoire de destination personnalisé
- Configuration S3 (bucket, préfixe)
- Sauvegarde complète ou données essentielles uniquement
- Variables d'environnement (.env.local, .env.prod, ou fichier personnalisé)

## Variables d'environnement supportées
- `AWS_ACCESS_KEY_ID` : Clé d'accès AWS
- `AWS_SECRET_ACCESS_KEY` : Clé secrète AWS  
- `AWS_DEFAULT_REGION` : Région AWS par défaut
- `S3_BACKUP_BUCKET` : Nom du bucket S3
- `S3_BACKUP_PREFIX` : Préfixe S3

## Sortie
Le fichier de sauvegarde sera nommé : `${BACKUP_PREFIX}YYYYMMDD_HHMMSS.tar.gz`
EOF
}

# Fonction de logging unifiée avec Gum
gum_log() {
    local level="$1"
    local message="$2"
    
    if [ "$QUIET_MODE" = false ]; then
        case "$level" in
            "info")
                gum log --structured --level info "$message"
                ;;
            "success")
                gum style --foreground 212 --bold "✅ $message"
                ;;
            "warn")
                gum log --structured --level warn "$message"
                ;;
            "error")
                gum log --structured --level error "$message" >&2
                ;;
            *)
                echo "$message"
                ;;
        esac
    else
        echo "[$level] $message"
    fi
}

# Fonctions de logging simplifiées
log() { gum_log "info" "$1"; }
success() { gum_log "success" "$1"; }
warning() { gum_log "warn" "$1"; }
error() { gum_log "error" "$1"; }

# =============================================================================
# Interface interactive avec Gum
# =============================================================================

interactive_setup() {
    # En-tête stylisé
    gum style \
        --foreground 212 --border-foreground 212 --border double \
        --align center --width 60 --margin "1 2" --padding "2 4" \
        "💾 Sauvegarde OpenWebUI" "Configuration interactive"
    
    echo
    
    # 1. Chargement des variables d'environnement
    if gum confirm "Voulez-vous charger des variables d'environnement ?"; then
        ENV_TYPE=$(gum choose --header "Choisir le type d'environnement :" \
            "local (.env.local)" \
            "prod (.env.prod)" \
            "fichier personnalisé")
        
        case "$ENV_TYPE" in
            "local (.env.local)")
                ENV_TYPE="local"
                ENV_FILE="$PROJECT_ROOT/.env.local"
                ;;
            "prod (.env.prod)")
                ENV_TYPE="prod"
                ENV_FILE="$PROJECT_ROOT/.env.prod"
                ;;
            "fichier personnalisé")
                ENV_FILE=$(gum file --directory="$PROJECT_ROOT" --file \
                    --header "Sélectionner le fichier d'environnement :")
                ENV_TYPE=""
                ;;
        esac
        
        # Charger immédiatement les variables d'environnement
        if [ -n "$ENV_FILE" ]; then
            load_env_file "$ENV_FILE"
            gum_log "info" "Variables d'environnement chargées depuis : $ENV_FILE"
        fi
        echo
    fi
    
    # 2. Type de sauvegarde
    BACKUP_TYPE=$(gum choose --header "Type de sauvegarde :" \
        "Locale uniquement" \
        "S3 uniquement" \
        "Locale + S3")
    
    case "$BACKUP_TYPE" in
        "S3 uniquement")
            S3_ONLY=true
            ;;
        "Locale + S3")
            S3_ONLY=false
            ;;
        *)
            S3_ONLY=false
            ;;
    esac
    echo
    
    # 3. Configuration S3 si nécessaire
    if [[ "$BACKUP_TYPE" == *"S3"* ]]; then
        gum style --foreground 99 --bold "🔧 Configuration S3"
        echo
        
        # Utiliser les valeurs du fichier d'environnement si disponibles
        local default_bucket="${S3_BACKUP_BUCKET:-mon-bucket-backup}"
        local default_prefix="${S3_BACKUP_PREFIX:-openwebui-backups/}"
        
        S3_BUCKET=$(gum input --header "Nom du bucket S3 :" \
            --placeholder "$default_bucket" \
            --value "${S3_BACKUP_BUCKET:-}")
        
        S3_PREFIX=$(gum input --header "Préfixe S3 (optionnel) :" \
            --placeholder "$default_prefix" \
            --value "${S3_BACKUP_PREFIX:-openwebui-backups/}")
        
        # S'assurer que le préfixe se termine par /
        if [[ -n "$S3_PREFIX" && ! "$S3_PREFIX" =~ /$ ]]; then
            S3_PREFIX="${S3_PREFIX}/"
        fi
        echo
    fi
    
    # 4. Répertoire de destination (si sauvegarde locale)
    if [ "$S3_ONLY" = false ]; then
        if gum confirm "Utiliser un répertoire de destination personnalisé ?"; then
            CUSTOM_OUTPUT_DIR=$(gum file --directory \
                --header "Sélectionner le répertoire de destination :")
        fi
        echo
    fi
    
    # 5. Type de données à sauvegarder
    DATA_TYPE=$(gum choose --header "Données à sauvegarder :" \
        "Sauvegarde complète (tous les fichiers)" \
        "Données essentielles uniquement (exclut cache, logs, modèles)")

    if [[ "$DATA_TYPE" == *"essentielles"* ]]; then
        DATA_ONLY=true
    fi
    echo

    # 6. Période de rétention
    if gum confirm "Voulez-vous définir une période de rétention spécifique ?"; then
        RETENTION_PERIOD=$(gum choose --header "Période de rétention :" \
            "day (quotidienne)" \
            "week (hebdomadaire)" \
            "month (mensuelle)" \
            "custom (rétention automatique)")

        case "$RETENTION_PERIOD" in
            "day (quotidienne)")
                RETENTION_PERIOD="day"
                ;;
            "week (hebdomadaire)")
                RETENTION_PERIOD="week"
                ;;
            "month (mensuelle)")
                RETENTION_PERIOD="month"
                ;;
            "custom (rétention automatique)")
                RETENTION_PERIOD="custom"
                ;;
        esac
        echo
    fi
    
    # 7. Résumé de la configuration
    gum style --foreground 212 --bold "📋 Résumé de la configuration"
    echo
    
    gum format --type markdown << EOF
## Configuration choisie :

- **Type de sauvegarde** : $BACKUP_TYPE
- **Données** : $([ "$DATA_ONLY" = true ] && echo "Essentielles uniquement" || echo "Complète")
$([ -n "$ENV_TYPE" ] && echo "- **Environnement** : $ENV_TYPE")
$([ -n "$ENV_FILE" ] && echo "- **Fichier env** : $ENV_FILE")
$([ -n "$S3_BUCKET" ] && echo "- **Bucket S3** : $S3_BUCKET")
$([ -n "$S3_PREFIX" ] && echo "- **Préfixe S3** : $S3_PREFIX")
$([ -n "$CUSTOM_OUTPUT_DIR" ] && echo "- **Répertoire** : $CUSTOM_OUTPUT_DIR")
$([ -n "$RETENTION_PERIOD" ] && echo "- **Période de rétention** : $RETENTION_PERIOD")
EOF
    
    echo
    if ! gum confirm "Confirmer et démarrer la sauvegarde ?"; then
        gum style --foreground 196 "❌ Sauvegarde annulée"
        exit 0
    fi
}

# =============================================================================
# Fonctions de vérification
# =============================================================================

detect_volume_name() {
    log "Détection du volume OpenWebUI..."
    
    # Chercher le conteneur OpenWebUI en cours d'exécution
    local container_name
    container_name=$(docker ps --format "{{.Names}}" | grep -E "openwebui|open-webui" | head -n1)
    
    if [ -n "$container_name" ]; then
        log "Conteneur trouvé: $container_name"
        # Extraire le nom du volume depuis le conteneur
        VOLUME_NAME=$(docker inspect "$container_name" --format='{{range .Mounts}}{{if eq .Type "volume"}}{{.Name}}{{end}}{{end}}' | head -n1)
        if [ -n "$VOLUME_NAME" ]; then
            log "Volume détecté: $VOLUME_NAME"
            return 0
        fi
    fi
    
    # Fallback: chercher des volumes qui contiennent "open-webui" dans le nom
    VOLUME_NAME=$(docker volume ls --format "{{.Name}}" | grep "open-webui" | head -n1)
    if [ -n "$VOLUME_NAME" ]; then
        log "Volume trouvé par recherche: $VOLUME_NAME"
        return 0
    fi
    
    error "Impossible de trouver le volume OpenWebUI"
    error "Volumes disponibles contenant 'open':"
    docker volume ls --format "{{.Name}}" | grep -i open | sed 's/^/  - /' || true
    return 1
}

check_prerequisites() {
    log "Vérification des prérequis..."
    
    # Vérifier Docker
    if ! command -v docker &> /dev/null; then
        error "Docker n'est pas installé"
        exit 1
    fi
    
    if ! docker info &> /dev/null; then
        error "Docker n'est pas en cours d'exécution"
        exit 1
    fi
    
    # Détecter le nom du volume
    if ! detect_volume_name; then
        error "Assurez-vous qu'OpenWebUI a été déployé au préalable"
        exit 1
    fi
    
    # Vérifier que le volume existe
    if ! docker volume inspect "$VOLUME_NAME" &> /dev/null; then
        error "Volume Docker '$VOLUME_NAME' introuvable"
        error "Assurez-vous qu'OpenWebUI a été déployé au préalable"
        exit 1
    fi
    
    # Vérifier AWS CLI si S3 requis
    if [ -n "$S3_BUCKET" ]; then
        if ! command -v aws &> /dev/null; then
            error "AWS CLI n'est pas installé (requis pour S3)"
            error "Installation: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html"
            exit 1
        fi
        
        # Vérifier la configuration AWS
        # Si les variables d'environnement sont définies, on peut continuer
        if [ -n "${AWS_ACCESS_KEY_ID:-}" ] && [ -n "${AWS_SECRET_ACCESS_KEY:-}" ]; then
            log "Variables AWS définies dans l'environnement"
        elif ! aws sts get-caller-identity &> /dev/null; then
            error "AWS CLI n'est pas configuré correctement"
            error "Exécutez: aws configure ou définissez AWS_ACCESS_KEY_ID et AWS_SECRET_ACCESS_KEY"
            exit 1
        fi
        
        log "Configuration AWS validée"
    fi
    
    success "Prérequis validés"
}

# =============================================================================
# Fonction de sauvegarde
# =============================================================================

create_backup() {
    gum style --foreground 99 --bold "🔄 Création de la sauvegarde"
    echo
    
    # Déterminer le répertoire de sauvegarde
    local backup_dir
    if [ "$S3_ONLY" = true ]; then
        # Créer un répertoire temporaire pour S3 uniquement
        backup_dir=$(mktemp -d)
        log "Répertoire temporaire pour S3 : $backup_dir"
    elif [ -n "$CUSTOM_OUTPUT_DIR" ]; then
        backup_dir="$CUSTOM_OUTPUT_DIR"
    else
        backup_dir="$BACKUP_DIR"
    fi

    # Organiser par période de rétention si spécifiée
    if [ -n "$RETENTION_PERIOD" ] && [ "$RETENTION_PERIOD" != "custom" ] && [ "$S3_ONLY" = false ]; then
        backup_dir="$backup_dir/$RETENTION_PERIOD"
        log "Organisation par période : $RETENTION_PERIOD"
    fi
    
    # Créer le répertoire de sauvegarde si nécessaire
    mkdir -p "$backup_dir"
    
    local backup_file="$backup_dir/${BACKUP_PREFIX}${TIMESTAMP}.tar.gz"
    local backup_filename="${BACKUP_PREFIX}${TIMESTAMP}.tar.gz"
    
    if [ "$S3_ONLY" = false ]; then
        log "Destination locale : $backup_file"
    fi
    
    # Créer la sauvegarde avec spinner
    local tar_command
    if [ "$DATA_ONLY" = true ]; then
        log "Mode sauvegarde des données essentielles uniquement"
        # Exclure cache, logs, et fichiers temporaires volumineux
        tar_command="tar czf \"/backup/$backup_filename\" -C /data --exclude='cache/*' --exclude='*.log' --exclude='*.tmp' --exclude='temp/*' --exclude='logs/*' --exclude='models/*' ."
    else
        log "Mode sauvegarde complète"
        tar_command="tar czf \"/backup/$backup_filename\" -C /data ."
    fi
    
    # Exécuter la sauvegarde avec un spinner
    if gum spin --spinner dot --title "Création de l'archive en cours..." -- \
        docker run --rm \
        -v "$VOLUME_NAME:/data:ro" \
        -v "$backup_dir:/backup" \
        alpine:latest \
        sh -c "$tar_command"; then
        
        # Vérifier que le fichier a bien été créé
        if [ -f "$backup_file" ]; then
            local file_size
            file_size=$(ls -lh "$backup_file" | awk '{print $5}')
            if [ "$DATA_ONLY" = true ]; then
                success "Sauvegarde des données essentielles créée avec succès ($file_size)"
                gum style --foreground 240 "Exclusions appliquées : cache, logs, modèles, fichiers temporaires"
            else
                success "Sauvegarde complète créée avec succès ($file_size)"
            fi
            
            if [ "$S3_ONLY" = false ]; then
                gum style --foreground 99 "📁 Chemin local : $(realpath "$backup_file")"
            fi
            
            # Upload vers S3 si configuré et type de sauvegarde approprié
            if [ -n "$S3_BUCKET" ] && [[ "$BACKUP_TYPE" == *"S3"* || "$BACKUP_TYPE" == "both" || "$S3_ONLY" = true ]]; then
                upload_to_s3 "$backup_file" "$backup_filename"
            fi
            
            # Nettoyer le fichier temporaire si S3 uniquement
            if [ "$S3_ONLY" = true ]; then
                rm -f "$backup_file"
                rmdir "$backup_dir" 2>/dev/null || true
            fi
            
            return 0
        else
            error "Le fichier de sauvegarde n'a pas été créé"
            return 1
        fi
    else
        error "Échec de la création de sauvegarde"
        return 1
    fi
}

# =============================================================================
# Fonction d'upload S3
# =============================================================================

upload_to_s3() {
    local local_file="$1"
    local filename="$2"

    # Adapter le préfixe S3 selon la période de rétention
    local s3_key
    if [ -n "$RETENTION_PERIOD" ] && [ "$RETENTION_PERIOD" != "custom" ]; then
        s3_key="${S3_PREFIX}${RETENTION_PERIOD}/${filename}"
    else
        s3_key="${S3_PREFIX}${filename}"
    fi

    local s3_url="s3://${S3_BUCKET}/${s3_key}"
    
    gum style --foreground 99 --bold "☁️ Upload vers S3"
    echo
    
    log "Destination S3 : $s3_url"
    
    # Calculer le MD5 local pour vérification
    local local_md5
    if command -v md5sum &> /dev/null; then
        local_md5=$(md5sum "$local_file" | cut -d' ' -f1)
    elif command -v md5 &> /dev/null; then
        local_md5=$(md5 -q "$local_file")
    else
        local_md5=""
    fi
    
    # Upload vers S3 avec spinner
    if gum spin --spinner dot --title "Upload en cours vers S3..." -- \
        aws s3 cp "$local_file" "$s3_url" --endpoint-url https://nbg1.your-objectstorage.com --only-show-errors; then
        
        success "Upload S3 réussi : $s3_url"
        
        # Vérification optionnelle de l'intégrité
        if [ -n "$local_md5" ]; then
            gum spin --spinner dot --title "Vérification de l'intégrité..." -- sleep 1
            local s3_etag
            s3_etag=$(aws s3api head-object --bucket "$S3_BUCKET" --key "$s3_key" --endpoint-url https://nbg1.your-objectstorage.com --query 'ETag' --output text 2>/dev/null | tr -d '"')
            
            if [ "$local_md5" = "$s3_etag" ]; then
                success "Intégrité vérifiée ✓"
            else
                warning "Les checksums ne correspondent pas (peut être normal pour des fichiers volumineux)"
            fi
        fi
        
        return 0
    else
        error "Échec de l'upload S3"
        return 1
    fi
}

# =============================================================================
# Fonction de nettoyage par période de rétention
# =============================================================================

cleanup_retention_folders() {
    log "Nettoyage des anciennes sauvegardes par période de rétention..."

    # Déterminer le répertoire de base
    local base_backup_dir
    if [ "$S3_ONLY" = true ]; then
        # Pour S3 uniquement, on nettoie aussi S3
        cleanup_s3_retention_folders
        return 0
    elif [ -n "$CUSTOM_OUTPUT_DIR" ]; then
        base_backup_dir="$CUSTOM_OUTPUT_DIR"
    else
        base_backup_dir="$BACKUP_DIR"
    fi

    # Nettoyage local des 3 dossiers
    cleanup_folder_with_limit "$base_backup_dir/day" 7 "quotidiennes"
    cleanup_folder_with_limit "$base_backup_dir/week" 4 "hebdomadaires"
    cleanup_folder_with_limit "$base_backup_dir/month" 12 "mensuelles"

    # Nettoyage S3 si configuré
    if [ -n "$S3_BUCKET" ]; then
        cleanup_s3_retention_folders
    fi

    success "Nettoyage des périodes de rétention terminé"
}

# Fonction pour nettoyer un dossier avec une limite de fichiers
cleanup_folder_with_limit() {
    local folder_path="$1"
    local keep_count="$2"
    local description="$3"

    if [ ! -d "$folder_path" ]; then
        log "Dossier $folder_path introuvable, création..."
        mkdir -p "$folder_path"
        return 0
    fi

    log "Nettoyage des sauvegardes $description dans : $folder_path (conserver $keep_count)"

    # Lister les fichiers de sauvegarde triés par date (plus récents en premier)
    local backup_files
    backup_files=$(find "$folder_path" -name "${BACKUP_PREFIX}*.tar.gz" -type f | sort -r)

    if [ -z "$backup_files" ]; then
        log "Aucune sauvegarde $description trouvée"
        return 0
    fi

    local file_count
    file_count=$(echo "$backup_files" | wc -l)

    if [ "$file_count" -le "$keep_count" ]; then
        log "Seulement $file_count sauvegarde(s) $description trouvée(s), aucune suppression nécessaire"
        return 0
    fi

    # Supprimer les fichiers en excès
    local files_to_delete
    files_to_delete=$(echo "$backup_files" | tail -n +$((keep_count + 1)))

    local deleted_count=0
    while IFS= read -r file_to_delete; do
        if [ -f "$file_to_delete" ]; then
            rm "$file_to_delete"
            log "Supprimé ($description) : $(basename "$file_to_delete")"
            deleted_count=$((deleted_count + 1))
        fi
    done <<< "$files_to_delete"

    log "Supprimé $deleted_count sauvegarde(s) $description (conservé $keep_count)"
}

# Fonction pour nettoyer S3 par période de rétention
cleanup_s3_retention_folders() {
    if [ -z "$S3_BUCKET" ]; then
        return 0
    fi

    log "Nettoyage S3 par période de rétention..."

    # Nettoyer chaque préfixe S3
    cleanup_s3_prefix_with_limit "day" 7 "quotidiennes"
    cleanup_s3_prefix_with_limit "week" 4 "hebdomadaires"
    cleanup_s3_prefix_with_limit "month" 12 "mensuelles"
}

# Fonction pour nettoyer un préfixe S3 avec une limite
cleanup_s3_prefix_with_limit() {
    local period="$1"
    local keep_count="$2"
    local description="$3"

    local s3_prefix="${S3_PREFIX}${period}/"

    log "Nettoyage S3 des sauvegardes $description (préfixe: $s3_prefix, conserver $keep_count)"

    # Lister les objets S3 pour ce préfixe
    local s3_objects
    s3_objects=$(aws s3api list-objects-v2 \
        --bucket "$S3_BUCKET" \
        --prefix "${s3_prefix}${BACKUP_PREFIX}" \
        --endpoint-url https://nbg1.your-objectstorage.com \
        --query 'Contents[?Size>`0`].[Key,LastModified]' \
        --output text 2>/dev/null | \
        sort -k2 -r | \
        cut -f1)

    if [ -z "$s3_objects" ]; then
        log "Aucune sauvegarde S3 $description trouvée"
        return 0
    fi

    local object_count
    object_count=$(echo "$s3_objects" | wc -l)

    if [ "$object_count" -le "$keep_count" ]; then
        log "Seulement $object_count sauvegarde(s) S3 $description trouvée(s), aucune suppression nécessaire"
        return 0
    fi

    # Supprimer les objets en excès
    local objects_to_delete
    objects_to_delete=$(echo "$s3_objects" | tail -n +$((keep_count + 1)))

    local deleted_count=0
    while IFS= read -r s3_key; do
        if [ -n "$s3_key" ]; then
            if aws s3 rm "s3://$S3_BUCKET/$s3_key" --endpoint-url https://nbg1.your-objectstorage.com --only-show-errors; then
                log "Supprimé S3 ($description) : $(basename "$s3_key")"
                deleted_count=$((deleted_count + 1))
            fi
        fi
    done <<< "$objects_to_delete"

    log "Supprimé $deleted_count sauvegarde(s) S3 $description (conservé $keep_count)"
}

# =============================================================================
# Fonction principale
# =============================================================================

main_backup() {
    # Charger les variables d'environnement si elles n'ont pas été chargées en mode interactif
    if [ -n "$ENV_TYPE" ] && [ -z "$ENV_FILE" ]; then
        case "$ENV_TYPE" in
            "local")
                ENV_FILE="$PROJECT_ROOT/.env.local"
                log "Utilisation de l'environnement local : .env.local"
                ;;
            "prod")
                ENV_FILE="$PROJECT_ROOT/.env.prod"
                log "Utilisation de l'environnement de production : .env.prod"
                ;;
            *)
                error "Type d'environnement invalide : $ENV_TYPE (utilisez 'local' ou 'prod')"
                exit 1
                ;;
        esac
        
        load_env_file "$ENV_FILE"
        
        # Utiliser les variables d'environnement si disponibles
        if [ -z "$S3_BUCKET" ] && [ -n "${S3_BACKUP_BUCKET:-}" ]; then
            S3_BUCKET="$S3_BACKUP_BUCKET"
            log "Bucket S3 défini depuis l'environnement : $S3_BUCKET"
        fi
        
        if [ "$S3_PREFIX" = "openwebui-backups/" ] && [ -n "${S3_BACKUP_PREFIX:-}" ]; then
            S3_PREFIX="$S3_BACKUP_PREFIX"
            log "Préfixe S3 défini depuis l'environnement : $S3_PREFIX"
        fi
    fi
    
    check_prerequisites
    create_backup
    cleanup_retention_folders
    
    if [ "$QUIET_MODE" = false ]; then
        echo
        gum style \
            --foreground 212 --border-foreground 212 --border double \
            --align center --width 60 --margin "1 2" --padding "2 4" \
            "🎉 Sauvegarde terminée avec succès !"
        
        echo
        
        if [ "$S3_ONLY" = false ]; then
            gum style --foreground 99 --bold "📋 Commandes de restauration locale :"
            local backup_path
            if [ -n "$CUSTOM_OUTPUT_DIR" ]; then
                backup_path="$CUSTOM_OUTPUT_DIR"
            else
                backup_path="$BACKUP_DIR"
            fi
            
            gum format --type code << EOF
docker run --rm -v $VOLUME_NAME:/data -v $backup_path:/backup alpine \\
  tar xzf /backup/${BACKUP_PREFIX}${TIMESTAMP}.tar.gz -C /data
EOF
        fi
        
        if [ -n "$S3_BUCKET" ]; then
            echo
            gum style --foreground 99 --bold "☁️ Commandes de restauration S3 :"
            gum format --type code << EOF
# Télécharger depuis S3
aws s3 cp s3://$S3_BUCKET/${S3_PREFIX}${BACKUP_PREFIX}${TIMESTAMP}.tar.gz /tmp/

# Restaurer dans Docker
docker run --rm -v $VOLUME_NAME:/data -v /tmp:/backup alpine \\
  tar xzf /backup/${BACKUP_PREFIX}${TIMESTAMP}.tar.gz -C /data
EOF
        fi
        
        echo
        gum style --foreground 240 "Sauvegarde terminée le $(date '+%d/%m/%Y à %H:%M:%S')"
    fi
}

# =============================================================================
# Parsing des arguments
# =============================================================================

# Variables pour détecter si des arguments ont été fournis
ARGS_PROVIDED=false

while [[ $# -gt 0 ]]; do
    ARGS_PROVIDED=true
    case $1 in
        --quiet)
            QUIET_MODE=true
            shift
            ;;
        --help|-h)
            SHOW_HELP=true
            shift
            ;;
        --env-type)
            ENV_TYPE="$2"
            if [[ "$ENV_TYPE" != "local" && "$ENV_TYPE" != "prod" ]]; then
                error "Type d'environnement invalide : $ENV_TYPE (utilisez 'local' ou 'prod')"
                exit 1
            fi
            shift 2
            ;;
        --env-file)
            ENV_FILE="$2"
            if [[ ! -f "$ENV_FILE" ]]; then
                error "Fichier d'environnement introuvable : $ENV_FILE"
                exit 1
            fi
            shift 2
            ;;
        --backup-type)
            BACKUP_TYPE="$2"
            case "$BACKUP_TYPE" in
                "local")
                    S3_ONLY=false
                    ;;
                "s3")
                    S3_ONLY=true
                    ;;
                "both")
                    S3_ONLY=false
                    # Pour "both", on a besoin du bucket S3
                    ;;
                *)
                    error "Type de sauvegarde invalide : $BACKUP_TYPE (utilisez 'local', 's3' ou 'both')"
                    exit 1
                    ;;
            esac
            shift 2
            ;;
        --s3-bucket)
            S3_BUCKET="$2"
            shift 2
            ;;
        --s3-prefix)
            S3_PREFIX="$2"
            # S'assurer que le préfixe se termine par /
            if [[ -n "$S3_PREFIX" && ! "$S3_PREFIX" =~ /$ ]]; then
                S3_PREFIX="${S3_PREFIX}/"
            fi
            shift 2
            ;;
        --output-dir)
            CUSTOM_OUTPUT_DIR="$2"
            if [[ ! -d "$CUSTOM_OUTPUT_DIR" ]]; then
                error "Répertoire de destination introuvable : $CUSTOM_OUTPUT_DIR"
                exit 1
            fi
            shift 2
            ;;
        --data-only)
            DATA_ONLY=true
            shift
            ;;
        --retention-period)
            RETENTION_PERIOD="$2"
            if [[ "$RETENTION_PERIOD" != "day" && "$RETENTION_PERIOD" != "week" && "$RETENTION_PERIOD" != "month" && "$RETENTION_PERIOD" != "custom" ]]; then
                error "Période de rétention invalide : $RETENTION_PERIOD (utilisez 'day', 'week', 'month' ou 'custom')"
                exit 1
            fi
            shift 2
            ;;
        *)
            error "Option inconnue : $1"
            error "Utilisez --help pour voir les options disponibles"
            exit 1
            ;;
    esac
done

# =============================================================================
# Exécution principale
# =============================================================================

if [ "$SHOW_HELP" = true ]; then
    show_help
    exit 0
fi

# Traitement des variables d'environnement si spécifiées
if [ -n "$ENV_TYPE" ] || [ -n "$ENV_FILE" ]; then
    if [ -n "$ENV_TYPE" ] && [ -z "$ENV_FILE" ]; then
        case "$ENV_TYPE" in
            "local")
                ENV_FILE="$PROJECT_ROOT/.env.local"
                ;;
            "prod")
                ENV_FILE="$PROJECT_ROOT/.env.prod"
                ;;
        esac
    fi
    
    if [ -n "$ENV_FILE" ]; then
        load_env_file "$ENV_FILE"
        
        # Utiliser les variables d'environnement si les options ne sont pas définies
        if [ -z "$S3_BUCKET" ] && [ -n "${S3_BACKUP_BUCKET:-}" ]; then
            S3_BUCKET="$S3_BACKUP_BUCKET"
        fi
        
        if [ "$S3_PREFIX" = "openwebui-backups/" ] && [ -n "${S3_BACKUP_PREFIX:-}" ]; then
            S3_PREFIX="$S3_BACKUP_PREFIX"
        fi
    fi
fi

# Validation des options pour S3
if [[ "$BACKUP_TYPE" == "s3" ]] || [[ "$BACKUP_TYPE" == "both" ]] || [ "$S3_ONLY" = true ]; then
    if [ -z "$S3_BUCKET" ]; then
        error "Option --s3-bucket requise pour la sauvegarde S3"
        error "Utilisez --s3-bucket BUCKET ou définissez S3_BACKUP_BUCKET dans votre fichier d'environnement"
        exit 1
    fi
fi

# Si aucun argument n'est fourni et qu'on n'est pas en mode silencieux,
# lancer l'interface interactive
if [ "$ARGS_PROVIDED" = false ] && [ "$QUIET_MODE" = false ]; then
    interactive_setup
fi

main_backup 