#!/bin/bash

# Цвета
C_RESET='\033[0m'
C_RED='\033[0;31m'
C_GREEN='\033[0;32m'
C_YELLOW='\033[0;33m'
C_BLUE='\033[0;34m'
C_CYAN='\033[0;36m'

# Файл для сохранения состояния
CONFIG_FILE=".btrfs_setup.conf"

# --- Функции Помощники ---

info() { echo -e "${C_CYAN}INFO:${C_RESET} $1"; }
warn() { echo -e "${C_YELLOW}WARN:${C_RESET} $1"; }
error() { echo -e "${C_RED}ERROR:${C_RESET} $1"; }
success() { echo -e "${C_GREEN}SUCCESS:${C_RESET} $1"; }
cmd() { echo -e "${C_BLUE}CMD:${C_RESET} $1"; }

ask_confirm() {
    while true; do
        read -p "$(echo -e "${C_YELLOW}CONFIRM:${C_RESET} $1 (y/n): ")" yn
        case $yn in
            [Yy]* ) return 0;;
            [Nn]* ) return 1;;
            * ) echo "Ответьте 'y' или 'n'.";;
        esac
    done
}

# --- Управление Конфигурацией ---

# Загрузка переменных из файла
load_config() {
    if [ -f "$CONFIG_FILE" ]; then
        source "$CONFIG_FILE"
    fi
}

# Сохранение переменной в файл
save_config() {
    local key=$1
    local value=$2
    # Удаляем старую запись, если она есть
    sed -i "/^${key}=/d" "$CONFIG_FILE"
    # Добавляем новую
    echo "${key}='${value}'" >> "$CONFIG_FILE"
}

# --- Главы Установки ---

# Глава 0: Проверка Live-среды
step0_check_live() {
    info "--- Глава 0: Проверка Live-среды ---"
    info "Проверяю наличие 'btrfs-progs'..."
    if ! pacman -S --needed --noconfirm btrfs-progs; then
        error "Не удалось установить 'btrfs-progs'. Проверьте интернет."
        return 1
    fi
    success "Live-среда готова."
}

# Глава 1: Форматирование
step1_format() {
    info "--- Глава 1: Форматирование ---"
    read -p "EFI раздел [${DEFAULT_EFI_PART:-/dev/sda1}]: " EFI_PART
    EFI_PART=${EFI_PART:-${DEFAULT_EFI_PART:-/dev/sda1}}
    
    read -p "BTRFS раздел [${DEFAULT_BTRFS_PART:-/dev/sda2}]: " BTRFS_PART
    BTRFS_PART=${BTRFS_PART:-${DEFAULT_BTRFS_PART:-/dev/sda2}}

    if [ -z "$EFI_PART" ] || [ -z "$BTRFS_PART" ]; then
        error "Разделы не могут быть пустыми."; return 1;
    fi

    warn "!! ВНИМАНИЕ !! Это действие необратимо."
    if ask_confirm "Отформатировать $EFI_PART (fat32) и $BTRFS_PART (btrfs)?"; then
        cmd "mkfs.fat -F 32 $EFI_PART"
        mkfs.fat -F 32 "$EFI_PART" || { error "Ошибка форматирования EFI."; return 1; }
        
        cmd "mkfs.btrfs -f $BTRFS_PART"
        mkfs.btrfs -f "$BTRFS_PART" || { error "Ошибка форматирования Btrfs."; return 1; }
        
        save_config "DEFAULT_EFI_PART" "$EFI_PART"
        save_config "DEFAULT_BTRFS_PART" "$BTRFS_PART"
        success "Форматирование завершено."
    else
        info "Форматирование отменено."; return 1;
    fi
}

# Глава 2: Создание подтомов
step2_create_subvols() {
    info "--- Глава 2: Создание подтомов ---"
    if [ -z "$DEFAULT_BTRFS_PART" ]; then
        error "Сначала выполните Главу 1 (Форматирование)."; return 1;
    fi

    cmd "mount -o compress=zstd:1 $DEFAULT_BTRFS_PART /mnt"
    mount -o compress=zstd:1 "$DEFAULT_BTRFS_PART" /mnt || { error "Не удалось смонтировать /mnt."; return 1; }

    local default_vols=("@" "@home" "@srv" "@logs" "@cache" "@snapshots" "@swap")
    local SUBVOLS_RAW=${DEFAULT_SUBVOLS:-${default_vols[*]}}
    
    info "Текущий список подтомов: $SUBVOLS_RAW"
    if ask_confirm "Хотите настроить список подтомов?"; then
        read -p "Введите новый список (через пробел): " SUBVOLS_RAW
    fi

    local SUBVOLS_LIST=($SUBVOLS_RAW)
    info "Создаю подтома: ${SUBVOLS_LIST[*]}"
    for vol in "${SUBVOLS_LIST[@]}"; do
        cmd "btrfs subvolume create /mnt/$vol"
        btrfs subvolume create "/mnt/$vol"
    done
    
    save_config "DEFAULT_SUBVOLS" "$SUBVOLS_RAW"
    success "Подтома созданы."
    cmd "umount /mnt"
    umount /mnt
}

# Глава 3: Монтирование подтомов
step3_mount_all() {
    info "--- Глава 3: Монтирование подтомов ---"
    if [ -z "$DEFAULT_BTRFS_PART" ] || [ -z "$DEFAULT_SUBVOLS" ]; then
        error "Сначала выполните Главы 1 и 2."; return 1;
    fi

    local SUBVOLS_LIST=($DEFAULT_SUBVOLS)
    declare -A MOUNT_MAP
    MOUNT_MAP["@"]="/mnt"
    MOUNT_MAP["@home"]="/mnt/home"
    MOUNT_MAP["@srv"]="/mnt/srv"
    MOUNT_MAP["@logs"]="/mnt/var/log"
    MOUNT_MAP["@cache"]="/mnt/var/cache"
    MOUNT_MAP["@snapshots"]="/mnt/.snapshots"
    MOUNT_MAP["@swap"]="/mnt/swap"

    # Добавляем кастомные, если они были
    for vol in "${SUBVOLS_LIST[@]}"; do
        if [[ -z "${MOUNT_MAP[$vol]}" ]]; then
            read -p "Введите точку монтирования для '$vol' (e.g., /mnt/custom): " custom_mount
            MOUNT_MAP["$vol"]="$custom_mount"
        fi
    done

    read -p "Уровень сжатия по умолчанию [zstd:3]: " DEFAULT_COMPRESS
    DEFAULT_COMPRESS=${DEFAULT_COMPRESS:-zstd:3}
    
    info "Монтирование корня (@)..."
    local root_opts="defaults,compress=$DEFAULT_COMPRESS"
    if [[ " ${SUBVOLS_LIST[*]} " =~ " @cache " ]]; then # Корень не должен иметь noatime
        root_opts="defaults,compress=$DEFAULT_COMPRESS"
    fi
    mkdir -p "${MOUNT_MAP['@']}"
    cmd "mount -o $root_opts,subvol=@ $DEFAULT_BTRFS_PART ${MOUNT_MAP['@']}"
    mount -o "$root_opts,subvol=@" "$DEFAULT_BTRFS_PART" "${MOUNT_MAP['@']}" || { error "Ошибка монтирования корня."; return 1; }

    # Монтируем все остальное
    for vol in "${SUBVOLS_LIST[@]}"; do
        if [[ "$vol" == "@" ]]; then continue; fi
        
        local mount_point="${MOUNT_MAP[$vol]}"
        local default_opts="defaults,compress=$DEFAULT_COMPRESS"
        
        if [[ "$vol" == "@cache" || "$vol" == "@swap" ]]; then
            default_opts="defaults,noatime"
        fi
        
        read -p "Опции для '$vol' [${default_opts}]: " custom_opts
        local opts=${custom_opts:-$default_opts}
        
        info "Монтирование '$vol' в '$mount_point'..."
        mkdir -p "$mount_point"
        cmd "mount -o $opts,subvol=$vol $DEFAULT_BTRFS_PART $mount_point"
        mount -o "$opts,subvol=$vol" "$DEFAULT_BTRFS_PART" "$mount_point" || warn "Не удалось смонтировать $vol."
    done

    info "Монтирование EFI..."
    mkdir -p /mnt/efi
    cmd "mount $DEFAULT_EFI_PART /mnt/efi"
    mount "$DEFAULT_EFI_PART" /mnt/efi || { error "Ошибка монтирования EFI."; return 1; }

    success "Все подтома смонтированы."
}

# Глава 4: Swap-файл
step4_swapfile() {
    info "--- Глава 4: Swap-файл ---"
    if [[ ! " $DEFAULT_SUBVOLS " =~ " @swap " ]]; then
        warn "Подтом '@swap' не найден, пропускаю."; return 0;
    fi
    
    read -p "Размер swap-файла [4G]: " SWAP_SIZE
    SWAP_SIZE=${SWAP_SIZE:-4G}
    
    info "Создаю swap-файл /mnt/swap/swapfile..."
    cmd "btrfs filesystem mkswapfile --size $SWAP_SIZE --uuid clear /mnt/swap/swapfile"
    btrfs filesystem mkswapfile --size "$SWAP_SIZE" --uuid clear /mnt/swap/swapfile
    
    cmd "swapon /mnt/swap/swapfile"
    swapon /mnt/swap/swapfile
    save_config "SWAP_SIZE" "$SWAP_SIZE"
    success "Swap-файл создан и активирован."
}

# Глава 5: Pacstrap
step5_pacstrap() {
    info "--- Глава 5: Установка (pacstrap) ---"
    
    # Предлагаем "умный" список
    local BASE_PKGS="base linux linux-firmware nano"
    local BTRFS_UTILS=""
    if [[ " $DEFAULT_SUBVOLS " =~ " @snapshots " ]]; then
        BTRFS_UTILS="btrfs-progs grub efibootmgr snapper grub-btrfs snap-pac inotify-tools"
    else
        BTRFS_UTILS="btrfs-progs grub efibootmgr"
    fi
    
    local DEFAULT_PACKAGES="${BASE_PKGS} ${BTRFS_UTILS}"
    info "Рекомендуемый список пакетов:"
    info "$DEFAULT_PACKAGES"
    
    read -p "Введите список пакетов (Enter = принять): " PACKAGES
    PACKAGES=${PACKAGES:-$DEFAULT_PACKAGES}
    
    info "Запуск pacstrap (это займет время)..."
    cmd "pacstrap -K /mnt $PACKAGES"
    if pacstrap -K /mnt $PACKAGES; then
        save_config "INSTALLED_PACKAGES" "$PACKAGES"
        success "Базовая система установлена."
    else
        error "Ошибка pacstrap!"; return 1;
    fi
}

# Глава 6: Fstab
step6_fstab() {
    info "--- Глава 6: Fstab ---"
    info "Генерирую fstab..."
    cmd "genfstab -U /mnt >> /mnt/etc/fstab"
    genfstab -U /mnt >> /mnt/etc/fstab

    if [ -n "$SWAP_SIZE" ]; then
        info "Добавляю swap-файл в fstab..."
        cmd "echo '/swap/swapfile none swap defaults 0 0' >> /mnt/etc/fstab"
        echo "/swap/swapfile none swap defaults 0 0" >> /mnt/etc/fstab
    fi

    warn "ВАЖНО: genfstab мог 'забыть' опции сжатия."
    if ask_confirm "Открыть /mnt/etc/fstab в nano для ручной проверки?"; then
        nano /mnt/etc/fstab
    fi
    success "Fstab готов."
}

# Глава 7: Шпаргалка (Chroot)
step7_show_helper() {
    info "--- Глава 7: Шпаргалка по настройке (внутри chroot) ---"
    if [ -z "$INSTALLED_PACKAGES" ]; then
        warn "Пакеты еще не установлены (Глава 5). Шпаргалка может быть неполной."
    fi
    
    echo -e "${C_CYAN}==========================================================="
    echo "           Дальнейшие шаги (выполнять в 'arch-chroot /mnt')           "
    echo "===========================================================${C_RESET}"
    echo ""
    echo "Не забудьте про: passwd, ln -sf /usr/share/zoneinfo/..., hwclock, locale.gen, hostname, hosts"
    echo ""

    # --- Динамическая секция Snapper ---
    if [[ "$INSTALLED_PACKAGES" == *"snapper"* ]]; then
        echo -e "${C_YELLOW}### 1. Настройка Snapper ###${C_RESET}"
        warn "Рекомендация: этот шаг лучше делать ПОСЛЕ первой загрузки, а не в chroot."
        echo "cmd: snapper -c root create-config /"
        echo "cmd: rm -fdir /.snapshots"
        echo "cmd: mkdir /.snapshots"
        echo "cmd: mount -a"
        echo "cmd: nano /etc/snapper/configs/root"
        echo "     > Измени: TIMELINE_CREATE=\"no\""
        echo ""
    fi

    # --- Динамическая секция GRUB ---
    if [[ "$INSTALLED_PACKAGES" == *"grub"* ]]; then
        echo -e "${C_YELLOW}### 2. Настройка GRUB ###${C_RESET}"
        echo "cmd: grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=Arch"
        
        if [[ "$INSTALLED_PACKAGES" == *"grub-btrfs"* ]]; then
            echo "info: Добавляем поддержку снимков в GRUB..."
            echo "cmd: nano /etc/default/grub"
            echo "     > Добавь/раскомментируй: GRUB_BTRFS_SNAPSHOT_BOOT=true"
        fi
        
        echo "cmd: grub-mkconfig -o /boot/grub/grub.cfg"
        echo ""
    fi

    # --- Динамическая секция Сервисов ---
    if [[ "$INSTALLED_PACKAGES" == *"snapper"* || "$INSTALLED_PACKAGES" == *"grub-btrfs"* ]]; then
        echo -e "${C_YELLOW}### 3. Включение сервисов ###${C_RESET}"
        if [[ "$INSTALLED_PACKAGES" == *"snapper"* ]]; then
            echo "cmd: systemctl enable snapper-timeline.timer"
            echo "cmd: systemctl enable snapper-cleanup.timer"
        fi
        if [[ "$INSTALLED_PACKAGES" == *"grub-btrfs"* ]]; then
            echo "cmd: systemctl enable grub-btrfsd.service"
        fi
        echo ""
    fi
    echo -e "${C_CYAN}===========================================================${C_RESET}"
}

# --- Главное Меню ---

main_menu() {
    while true; do
        clear
        load_config # Загружаем состояние при каждом показе меню
        
        echo -e "${C_GREEN}--- Интерактивный Btrfs-помощник (v2.0) ---${C_RESET}"
        echo "Файл состояния: $CONFIG_FILE"
        echo ""
        echo -e "  ${C_CYAN}Разделы:${C_RESET} ${DEFAULT_EFI_PART:-Не задан} | ${DEFAULT_BTRFS_PART:-Не задан}"
        echo -e "  ${C_CYAN}Подтома:${C_RESET} ${DEFAULT_SUBVOLS:-Не заданы}"
        echo -e "  ${C_CYAN}Пакеты:${C_RESET}  ${INSTALLED_PACKAGES:-Не установлены}"
        echo ""
        echo "Выберите главу:"
        echo "-----------------------------------"
        echo " 0. Проверить Live-среду (pacman)"
        echo " 1. Форматирование разделов"
        echo " 2. Создание подтомов Btrfs"
        echo " 3. Монтирование подтомов"
        echo " 4. Создание Swap-файла"
        echo "-----------------------------------"
        echo " 5. Установка системы (pacstrap)"
        echo " 6. Генерация Fstab"
        echo " 7. Показать шпаргалку (Chroot)"
        echo "-----------------------------------"
        echo " q. Выход"
        echo ""
        
        read -p "Ваш выбор: " choice
        
        # Переменная для паузы
        local pause=true
        
        case $choice in
            0) step0_check_live ;;
            1) step1_format ;;
            2) step2_create_subvols ;;
            3) step3_mount_all ;;
            4. | 4) step4_swapfile ;;
            5) step5_pacstrap ;;
            6) step6_fstab ;;
            7) step7_show_helper ;;
            q|Q) break ;;
            *) warn "Неверный выбор." ;;
        esac
        
        if [ "$pause" = true ]; then
            echo ""
            read -p "Нажмите Enter для возврата в меню..."
        fi
    done
    info "Готово. Удачи!"
}

# --- Запуск ---
main_menu
