#!/bin/bash

# Script de Backup Otimizado para o Projeto Itens (Qt/C++)
# Versão completa com arquivos .txt consolidados

# Configurações
CONFIG_FILE="$HOME/.backup_itens_config"
PROJECT_NAME="Itens"

# Cores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m'

# Função para log colorido
log() {
    local type=$1
    shift
    case $type in
        ERROR)   echo -e "${RED}[ERRO]${NC} $*" ;;
        SUCCESS) echo -e "${GREEN}[OK]${NC} $*" ;;
        WARNING) echo -e "${YELLOW}[AVISO]${NC} $*" ;;
        INFO)    echo -e "${BLUE}[INFO]${NC} $*" ;;
        HEADER)  echo -e "${PURPLE}==>${NC} $*" ;;
        FILE)    echo -e "${CYAN}  ↳${NC} $*" ;;
    esac
}

# Verificar zenity
if ! command -v zenity &> /dev/null; then
    log INFO "Instalando zenity..."
    sudo pacman -S --noconfirm zenity || {
        log ERROR "Falha ao instalar zenity"
        exit 1
    }
fi

# Arquivos e pastas específicos para IGNORAR
IGNORE_PATTERNS=(
    "build/"
    "build.sh"
    "CMakeFiles/"
    "cmake-build-*/"
    "*.user"
    "*.user.*"
    "*.autosave"
    "*.db"
    "*.o"
    "*.so"
    "*.a"
    "*.exe"
    "*.dll"
    ".git/"
    ".idea/"
    ".vscode/"
    "__pycache__/"
    "*.pyc"
    ".DS_Store"
    "Thumbs.db"
    "*~"
    "*.swp"
    "*.swo"
    "compile_commands.json"
    "*.ninja"
    "Makefile"
    "moc_*"
    "*_autogen/"
    "Testing/"
)

# Lista de pastas para ignorar completamente
IGNORE_DIRS="build CMakeFiles .git .vs Debug Release x64 x86 .vscode .idea node_modules bin obj .cache tmp temp build.ninja Testing"

# Função para verificar se arquivo deve ser ignorado
should_ignore() {
    local file="$1"
    for pattern in "${IGNORE_PATTERNS[@]}"; do
        if [[ "$file" == *$pattern* ]]; then
            return 0
        fi
    done
    return 1
}

# Função para verificar se está em pasta ignorada
is_in_ignored_dir() {
    local file="$1"
    for dir in $IGNORE_DIRS; do
        if [[ "$file" == *"/$dir/"* ]] || [[ "$file" == *"/$dir" ]]; then
            return 0
        fi
    done
    return 1
}

# Função para verificar se arquivo é válido
is_valid_file() {
    local file="$1"
    local max_size=1048576  # 1MB máximo

    [[ ! -f "$file" ]] && return 1

    local size=$(stat -c%s "$file" 2>/dev/null || echo 0)
    [[ $size -eq 0 || $size -gt $max_size ]] && return 1

    # Verificar se é binário (exceto .ui)
    if [[ ! "$file" =~ \.ui$ ]]; then
        file -b "$file" | grep -qE "binary|executable|object" && return 1
    fi

    return 0
}

# Função para formatar tamanho
format_size() {
    local size=$1
    if (( size > 1048576 )); then
        printf "%.1f MB" $(echo "scale=1; $size/1048576" | bc)
    elif (( size > 1024 )); then
        printf "%.1f KB" $(echo "scale=1; $size/1024" | bc)
    else
        printf "%d bytes" $size
    fi
}

# Carregar configuração
load_config() {
    if [[ -f "$CONFIG_FILE" ]]; then
        source "$CONFIG_FILE"
        return 0
    fi
    return 1
}

# Salvar configuração
save_config() {
    cat > "$CONFIG_FILE" << EOF
LAST_SOURCE_DIR="$1"
LAST_BACKUP_DIR="$2"
LAST_FORMAT="$3"
LAST_USED="$(date '+%Y-%m-%d %H:%M:%S')"
EOF
}

# Interface inicial
show_welcome() {
    local config_info=""
    if load_config; then
        config_info="\n\n📁 ÚLTIMA CONFIGURAÇÃO:\nProjeto: $LAST_SOURCE_DIR\nBackup: $LAST_BACKUP_DIR\nFormato: $LAST_FORMAT\nUsado em: $LAST_USED"
    fi

    zenity --info \
        --title="Backup do Projeto $PROJECT_NAME" \
        --text="Este script fará backup inteligente do projeto:\n\n✅ Arquivos .txt consolidados por categoria\n✅ Estrutura de pastas preservada\n✅ Ignora pasta build e temporários\n✅ Suporta múltiplos formatos\n\nArquivos incluídos:\n• Código fonte (.cpp, .h)\n• Interfaces Qt (.ui)\n• CMakeLists.txt\n• Documentação (.md)\n• Recursos e ícones\n• Scripts de teste\n\n❌ Ignorados:\n• Pasta build/\n• Arquivos compilados\n• Configurações locais\n• Bancos de dados$config_info" \
        --width=600 \
        --height=500
}

# Selecionar diretórios
select_directories() {
    local source_dir=""
    local backup_dir=""

    # Carregar configuração anterior
    load_config

    # Selecionar diretório do projeto
    if [[ -n "$LAST_SOURCE_DIR" ]] && [[ -d "$LAST_SOURCE_DIR" ]]; then
        if zenity --question \
            --title="Usar diretório anterior?" \
            --text="Usar projeto anterior?\n\n📁 $LAST_SOURCE_DIR\n\nÚltimo uso: $LAST_USED" \
            --width=400; then
            source_dir="$LAST_SOURCE_DIR"
        fi
    fi

    if [[ -z "$source_dir" ]]; then
        source_dir=$(zenity --file-selection \
            --directory \
            --title="Selecione o diretório do projeto Itens" \
            --filename="${LAST_SOURCE_DIR:-$HOME/}")
    fi

    [[ -z "$source_dir" ]] && exit 1

    # Verificar se é o projeto correto
    if [[ ! -f "$source_dir/CMakeLists.txt" ]] || [[ ! -d "$source_dir/src" ]]; then
        zenity --error --text="Diretório selecionado não parece ser o projeto Itens!"
        exit 1
    fi

    # Selecionar destino do backup
    if [[ -n "$LAST_BACKUP_DIR" ]] && [[ -d "$LAST_BACKUP_DIR" ]]; then
        if zenity --question \
            --title="Usar destino anterior?" \
            --text="Usar destino anterior?\n\n💾 $LAST_BACKUP_DIR" \
            --width=400; then
            backup_dir="$LAST_BACKUP_DIR"
        fi
    fi

    if [[ -z "$backup_dir" ]]; then
        backup_dir=$(zenity --file-selection \
            --directory \
            --title="Selecione onde salvar o backup" \
            --filename="${LAST_BACKUP_DIR:-$HOME/}")
    fi

    [[ -z "$backup_dir" ]] && exit 1

    echo "$source_dir:$backup_dir"
}

# Função para processar arquivos em arquivo .txt consolidado
process_files_to_txt() {
    local source_dir="$1"
    local output_file="$2"
    local file_pattern="$3"
    local category="$4"
    local file_count=0
    local total_size=0

    # Cabeçalho do arquivo
    cat > "$output_file" << EOF
$category - BACKUP DO PROJETO $PROJECT_NAME
================================================================================
Data: $(date '+%Y-%m-%d %H:%M:%S')
Origem: $source_dir

ARQUIVOS:
================================================================================

EOF

    # Processar arquivos
    while IFS= read -r -d '' file; do
        if ! is_in_ignored_dir "$file" && is_valid_file "$file"; then
            ((file_count++))
            local size=$(stat -c%s "$file")
            ((total_size += size))
            local rel_path="${file#$source_dir/}"

            # Adicionar ao arquivo consolidado
            echo "" >> "$output_file"
            echo "════════════════════════════════════════════════════════════════════════" >> "$output_file"
            echo "ARQUIVO #$file_count: $rel_path" >> "$output_file"
            echo "Tamanho: $(format_size $size)" >> "$output_file"
            echo "Caminho completo: $file" >> "$output_file"
            echo "════════════════════════════════════════════════════════════════════════" >> "$output_file"
            echo "" >> "$output_file"

            # Adicionar conteúdo do arquivo
            cat "$file" >> "$output_file" 2>/dev/null

            echo "" >> "$output_file"
            echo "/* ─────────────── FIM DO ARQUIVO ─────────────── */" >> "$output_file"
            echo "" >> "$output_file"
        fi
    done < <(find "$source_dir" -name "$file_pattern" -type f -print0 2>/dev/null | sort -z)

    # Resumo final
    echo "" >> "$output_file"
    echo "════════════════════════════════════════════════════════════════════════" >> "$output_file"
    echo "RESUMO: $file_count arquivos, tamanho total: $(format_size $total_size)" >> "$output_file"
    echo "════════════════════════════════════════════════════════════════════════" >> "$output_file"

    echo "$file_count:$total_size"
}

# Criar backup estruturado
create_backup() {
    local source_dir="$1"
    local backup_base="$2"
    local format_choice="$3"
    local timestamp=$(date '+%Y%m%d_%H%M%S')
    local backup_dir="$backup_base/${PROJECT_NAME}_backup_$timestamp"

    mkdir -p "$backup_dir"

    # Criar subdiretórios para arquivos .txt
    mkdir -p "$backup_dir/consolidado/headers"
    mkdir -p "$backup_dir/consolidado/sources"
    mkdir -p "$backup_dir/consolidado/cmake"
    mkdir -p "$backup_dir/consolidado/qt_ui"
    mkdir -p "$backup_dir/consolidado/docs"
    mkdir -p "$backup_dir/consolidado/tests"

    # Criar cópia da estrutura se solicitado
    if [[ "$format_choice" != "apenas_txt" ]]; then
        mkdir -p "$backup_dir/estrutura"
    fi

    {
        # Progresso
        echo "10"
        echo "# Analisando projeto..."

        # Contar arquivos válidos
        local h_count=$(find "$source_dir" -name "*.h" -o -name "*.hpp" | grep -vE "/(${IGNORE_DIRS// /|})/" | wc -l)
        local cpp_count=$(find "$source_dir" -name "*.cpp" -o -name "*.c" -o -name "*.cc" | grep -vE "/(${IGNORE_DIRS// /|})/" | wc -l)
        local ui_count=$(find "$source_dir" -name "*.ui" | grep -vE "/(${IGNORE_DIRS// /|})/" | wc -l)
        local cmake_count=$(find "$source_dir" -name "CMakeLists.txt" -o -name "*.cmake" | grep -vE "/(${IGNORE_DIRS// /|})/" | wc -l)

        echo "20"
        echo "# Processando headers (.h/.hpp)..."

        # Processar headers
        local h_result=$(process_files_to_txt "$source_dir" "$backup_dir/consolidado/headers/todos_headers.txt" "*.h" "ARQUIVOS DE CABEÇALHO (.h)")
        local hpp_result=$(process_files_to_txt "$source_dir" "$backup_dir/consolidado/headers/todos_headers_hpp.txt" "*.hpp" "ARQUIVOS DE CABEÇALHO (.hpp)")

        echo "35"
        echo "# Processando sources (.cpp/.c)..."

        # Processar sources
        local cpp_result=$(process_files_to_txt "$source_dir" "$backup_dir/consolidado/sources/todos_sources.txt" "*.cpp" "ARQUIVOS DE CÓDIGO (.cpp)")
        local c_result=$(process_files_to_txt "$source_dir" "$backup_dir/consolidado/sources/todos_sources_c.txt" "*.c" "ARQUIVOS DE CÓDIGO (.c)")

        echo "50"
        echo "# Processando arquivos Qt UI..."

        # Processar UI
        local ui_result=$(process_files_to_txt "$source_dir" "$backup_dir/consolidado/qt_ui/todos_ui.txt" "*.ui" "ARQUIVOS QT UI (.ui)")

        echo "60"
        echo "# Processando CMake..."

        # Processar CMake
        local cmake_result=$(process_files_to_txt "$source_dir" "$backup_dir/consolidado/cmake/todos_cmake.txt" "CMakeLists.txt" "ARQUIVOS CMAKE")

        echo "70"
        echo "# Processando documentação..."

        # Processar documentação
        local md_result=$(process_files_to_txt "$source_dir" "$backup_dir/consolidado/docs/toda_documentacao.txt" "*.md" "DOCUMENTAÇÃO (.md)")

        echo "80"
        echo "# Criando arquivo unificado..."

        # Criar arquivo único consolidado
        local unified_file="$backup_dir/BACKUP_COMPLETO_$PROJECT_NAME.txt"
        cat > "$unified_file" << EOF
BACKUP COMPLETO DO PROJETO $PROJECT_NAME
================================================================================
Data: $(date '+%Y-%m-%d %H:%M:%S')
Origem: $source_dir
Destino: $backup_dir

ESTATÍSTICAS:
- Headers (.h/.hpp): $h_count arquivos
- Sources (.cpp/.c): $cpp_count arquivos
- Qt UI (.ui): $ui_count arquivos
- CMake: $cmake_count arquivos

FILTROS APLICADOS:
✓ Ignoradas pastas: $IGNORE_DIRS
✓ Ignorados arquivos binários
✓ Ignorados arquivos > 1MB
✓ Ignorados arquivos vazios

================================================================================

EOF

        # Adicionar todos os arquivos ao arquivo único
        for txt_file in "$backup_dir"/consolidado/*/*.txt; do
            if [[ -f "$txt_file" ]]; then
                echo "" >> "$unified_file"
                echo "╔══════════════════════════════════════════════════════════════════════╗" >> "$unified_file"
                echo "║ $(basename "$txt_file")                                              " >> "$unified_file"
                echo "╚══════════════════════════════════════════════════════════════════════╝" >> "$unified_file"
                echo "" >> "$unified_file"
                cat "$txt_file" >> "$unified_file"
            fi
        done

        echo "90"
        echo "# Copiando estrutura do projeto..."

        # Copiar estrutura se solicitado
        if [[ "$format_choice" != "apenas_txt" ]]; then
            # Copiar mantendo estrutura
            cd "$source_dir"
            find . -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.cpp" -o -name "*.c" \
                -o -name "*.ui" -o -name "CMakeLists.txt" -o -name "*.cmake" \
                -o -name "*.md" -o -name "*.qrc" -o -name "*.png" -o -name "*.svg" \) \
                | grep -vE "/(${IGNORE_DIRS// /|})/" | while read -r file; do
                if is_valid_file "$file"; then
                    dest_file="$backup_dir/estrutura/$file"
                    mkdir -p "$(dirname "$dest_file")"
                    cp "$file" "$dest_file" 2>/dev/null
                fi
            done
            cd - >/dev/null
        fi

        echo "95"
        echo "# Finalizando..."

        # Criar resumo
        local summary_file="$backup_dir/RESUMO_BACKUP.txt"
        cat > "$summary_file" << EOF
RESUMO DO BACKUP - $PROJECT_NAME
================================================================================
Data: $(date '+%Y-%m-%d %H:%M:%S')
Formato: $format_choice

CONTEÚDO DO BACKUP:

1. ARQUIVOS .TXT CONSOLIDADOS:
   - consolidado/headers/todos_headers.txt
   - consolidado/sources/todos_sources.txt
   - consolidado/cmake/todos_cmake.txt
   - consolidado/qt_ui/todos_ui.txt
   - consolidado/docs/toda_documentacao.txt

2. ARQUIVO ÚNICO:
   - BACKUP_COMPLETO_$PROJECT_NAME.txt (todos os arquivos em um só)

EOF

        if [[ "$format_choice" != "apenas_txt" ]]; then
            echo "3. ESTRUTURA ORIGINAL:" >> "$summary_file"
            echo "   - estrutura/ (cópia da estrutura de pastas original)" >> "$summary_file"
        fi

        # Compactar se solicitado
        if [[ "$format_choice" == "compactado" ]] || [[ "$format_choice" == "todos" ]]; then
            echo "99"
            echo "# Compactando..."
            cd "$backup_base"
            tar -czf "${PROJECT_NAME}_backup_$timestamp.tar.gz" \
                "$(basename "$backup_dir")" 2>/dev/null
        fi

        echo "100"
        echo "# Backup concluído!"

    } | zenity --progress \
        --title="Criando Backup do Projeto $PROJECT_NAME" \
        --text="Iniciando..." \
        --percentage=0 \
        --auto-close \
        --width=600

    # Salvar configuração
    save_config "$source_dir" "$backup_base" "$format_choice"

    # Calcular tamanho total
    local total_size=$(du -sb "$backup_dir" | cut -f1)

    # Mostrar resultado
    local result_text="✅ Backup concluído com sucesso!\n\n"
    result_text+="📁 Projeto: $PROJECT_NAME\n"
    result_text+="📂 Localização: $backup_dir\n"
    result_text+="💾 Tamanho total: $(format_size $total_size)\n\n"
    result_text+="📋 ARQUIVOS CRIADOS:\n"
    result_text+="• Arquivos .txt consolidados por categoria\n"
    result_text+="• BACKUP_COMPLETO_$PROJECT_NAME.txt (arquivo único)\n"

    if [[ "$format_choice" != "apenas_txt" ]]; then
        result_text+="• Estrutura completa do projeto\n"
    fi

    if [[ -f "$backup_base/${PROJECT_NAME}_backup_$timestamp.tar.gz" ]]; then
        result_text+="• Arquivo compactado .tar.gz\n"
    fi

    zenity --info \
        --title="Backup Concluído!" \
        --text="$result_text" \
        --width=500

    # Perguntar se quer abrir
    if zenity --question --text="Deseja abrir o diretório do backup?"; then
        xdg-open "$backup_dir"
    fi
}

# Função principal
main() {
    # Mostrar boas-vindas
    show_welcome
    [[ $? -ne 0 ]] && exit 0

    # Selecionar diretórios
    local dirs=$(select_directories)
    [[ -z "$dirs" ]] && exit 1

    local source_dir=$(echo "$dirs" | cut -d: -f1)
    local backup_dir=$(echo "$dirs" | cut -d: -f2)

    # Escolher formato
    local format_choice=""
    if load_config && [[ -n "$LAST_FORMAT" ]]; then
        format_choice=$(zenity --list \
            --title="Formato do Backup" \
            --text="Escolha o formato do backup:" \
            --radiolist \
            --column="" --column="Formato" --column="Descrição" \
            $([[ "$LAST_FORMAT" == "apenas_txt" ]] && echo "TRUE" || echo "FALSE") "apenas_txt" "Apenas arquivos .txt consolidados" \
            $([[ "$LAST_FORMAT" == "estruturado" ]] && echo "TRUE" || echo "FALSE") "estruturado" "Arquivos .txt + estrutura de pastas" \
            $([[ "$LAST_FORMAT" == "compactado" ]] && echo "TRUE" || echo "FALSE") "compactado" "Tudo compactado em .tar.gz" \
            $([[ "$LAST_FORMAT" == "todos" ]] && echo "TRUE" || echo "FALSE") "todos" "Todos os formatos" \
            --width=500 --height=250)
    else
        format_choice=$(zenity --list \
            --title="Formato do Backup" \
            --text="Escolha o formato do backup:" \
            --radiolist \
            --column="" --column="Formato" --column="Descrição" \
            FALSE "apenas_txt" "Apenas arquivos .txt consolidados" \
            TRUE "estruturado" "Arquivos .txt + estrutura de pastas" \
            FALSE "compactado" "Tudo compactado em .tar.gz" \
            FALSE "todos" "Todos os formatos" \
            --width=500 --height=250)
    fi

    [[ -z "$format_choice" ]] && exit 1

    # Criar backup
    create_backup "$source_dir" "$backup_dir" "$format_choice"
}

# Executar
main

esse codigo gera um .txt com o codigo completo do projeto selecionado, é possivel ele ter a opção de criar um .png longo com o mesmo conteudo do .txt