#!/bin/bash
#=============================================================================
# Armbian 磁盘挂载管理脚本 v1.1
# 适用: Armbian 系统 (系统盘 /dev/mmcblk2)
# 功能: SD卡挂载 / USB磁盘挂载 / LVM双盘合并挂载 / 卸载管理
# 使用: sudo bash mount_manager.sh
#=============================================================================

#========================= 颜色定义 =========================
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'

#========================= 全局配置（可按需修改） =========================
SYSTEM_DISK="/dev/mmcblk2"        # 系统盘 - 绝对不能动
SD_CARD="/dev/mmcblk0"            # SD卡
USB_DISK1="/dev/sda"              # USB磁盘1
USB_DISK2="/dev/sdb"              # USB磁盘2

DEFAULT_MOUNT_PATH="/data"           # 默认挂载目录
MOUNT_LOG="/tmp/disk_mount.log"   # 操作日志

#========================= 工具函数 =========================

print_title() {
    echo -e "${CYAN}${BOLD}"
    echo "+------------------------------------------------------+"
    echo "|        Armbian 磁盘挂载管理脚本 v1.1                |"
    echo "+------------------------------------------------------+"
    echo -e "${NC}"
}

print_step() { echo -e "\n${BLUE}${BOLD}[步骤]${NC} $1"; }
print_ok()   { echo -e "  ${GREEN}[OK]${NC} $1"; }
print_warn() { echo -e "  ${YELLOW}[!!]${NC} $1"; }
print_error(){ echo -e "  ${RED}[ER]${NC} $1"; }
print_info() { echo -e "  ${CYAN}[*]${NC} $1"; }

confirm() {
    local prompt="$1"
    local danger="${2:-no}"
    echo ""
    if [ "$danger" = "yes" ]; then
        echo -ne "${RED}${BOLD}$prompt (输入 YES 确认): ${NC}"
        read -r answer
        if [ "$answer" != "YES" ]; then
            echo -e "${YELLOW}已取消操作。${NC}"
            return 1
        fi
    else
        echo -ne "${YELLOW}$prompt (y/n): ${NC}"
        read -r answer
        if [ "$answer" != "y" ] && [ "$answer" != "Y" ]; then
            echo -e "${YELLOW}已取消操作。${NC}"
            return 1
        fi
    fi
    return 0
}

log_action() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$MOUNT_LOG"
}

#========================= 检查函数 =========================

check_root() {
    if [ "$(id -u)" -ne 0 ]; then
        echo -e "${RED}${BOLD}错误: 此脚本必须以 root 权限运行！${NC}"
        echo -e "请使用: ${YELLOW}sudo bash $0${NC}"
        exit 1
    fi
}

check_disk_exists() {
    [ -b "$1" ]
}

get_disk_size() {
    local disk="$1"
    if check_disk_exists "$disk"; then
        lsblk -ndo SIZE "$disk" 2>/dev/null || echo "未知"
    else
        echo "不存在"
    fi
}

get_disk_model() {
    local disk="$1"
    if check_disk_exists "$disk"; then
        lsblk -ndo MODEL "$disk" 2>/dev/null | sed 's/^[[:space:]]*$/(无型号)/' || echo "未知"
    else
        echo "-"
    fi
}

# 获取磁盘及其分区列表（包含磁盘自身和所有子分区）
get_all_children() {
    local disk="$1"
    if check_disk_exists "$disk"; then
        lsblk -lnpo NAME,SIZE,FSTYPE,MOUNTPOINT "$disk" 2>/dev/null
    fi
}

# 仅获取分区（排除磁盘自身）
get_partitions() {
    local disk="$1"
    if check_disk_exists "$disk"; then
        lsblk -lnpo NAME,SIZE,FSTYPE,MOUNTPOINT "$disk" 2>/dev/null | tail -n +2
    fi
}

is_mounted() {
    local part="$1"
    local mp
    mp=$(lsblk -no MOUNTPOINT "$part" 2>/dev/null)
    if [ -n "$mp" ]; then
        echo "$mp"
        return 0
    fi
    return 1
}

# 检查磁盘自身（非分区）是否有文件系统（无分区表直接格式化的场景）
disk_has_fs_directly() {
    local disk="$1"
    local fstype
    fstype=$(lsblk -ndo FSTYPE "$disk" 2>/dev/null)
    if [ -n "$fstype" ] && [ "$fstype" != "null" ]; then
        echo "$fstype"
        return 0
    fi
    return 1
}

check_lvm() {
    local has_lvm=0
    for cmd in pvcreate vgcreate lvcreate; do
        if ! command -v "$cmd" &>/dev/null && [ ! -x "/usr/sbin/$cmd" ] && [ ! -x "/sbin/$cmd" ]; then
            has_lvm=1
            break
        fi
    done
    if [ $has_lvm -eq 1 ]; then
        print_warn "未检测到 LVM 工具，正在安装..."
        apt-get update -qq && apt-get install -y -qq lvm2
        if [ $? -eq 0 ]; then
            print_ok "LVM 工具安装完成！"
        else
            print_error "LVM 工具安装失败，请手动执行: apt-get install lvm2"
            return 1
        fi
    fi
    return 0
}

#========================= 磁盘信息展示 =========================

# 展示单个磁盘分区信息
show_single_disk_info() {
    local label="$1"
    local disk="$2"

    echo -e "  ${GREEN}【${label}】${NC}"
    if check_disk_exists "$disk"; then
        echo -e "    设备: ${BOLD}$disk${NC}  |  大小: $(get_disk_size "$disk")  |  型号: $(get_disk_model "$disk")"
        local parts=$(get_partitions "$disk")
        if [ -n "$parts" ]; then
            echo "$parts" | while read -r line; do
                local name=$(echo "$line" | awk '{print $1}')
                local size=$(echo "$line" | awk '{print $2}')
                local fstype=$(echo "$line" | awk '{print $3}')
                local mp=$(echo "$line" | awk '{print $4}')
                local status=""
                [ -n "$mp" ] && status=" ${GREEN}→ 已挂载到: $mp${NC}"
                echo -e "        - ${name}  ${size}  ${fstype:-无文件系统}${status}"
            done
        else
            # 检查磁盘自身是否有文件系统（无分区表直接格式化）
            local raw_fs=$(disk_has_fs_directly "$disk")
            if [ -n "$raw_fs" ]; then
                local raw_mp=$(lsblk -ndo MOUNTPOINT "$disk" 2>/dev/null)
                local raw_status=""
                [ -n "$raw_mp" ] && raw_status=" ${GREEN}→ 已挂载到: $raw_mp${NC}"
                echo -e "        - ${disk}  $(get_disk_size "$disk")  ${raw_fs}${raw_status} ${YELLOW}(无分区表，直接格式化)${NC}"
            else
                echo -e "      └─ 无分区（可能未格式化）"
            fi
        fi
    else
        echo -e "    ${YELLOW}未检测到设备${NC}"
    fi
}

show_disk_info() {
    echo ""
    echo -e "${BOLD}================== 系统磁盘概况 ==================${NC}"
    echo ""

    echo -e "  ${RED}【系统盘 - 受保护，不可操作】${NC}"
    if check_disk_exists "$SYSTEM_DISK"; then
        echo -e "    设备: ${BOLD}$SYSTEM_DISK${NC}  |  大小: $(get_disk_size "$SYSTEM_DISK")  |  型号: $(get_disk_model "$SYSTEM_DISK")"
    else
        echo -e "    设备: $SYSTEM_DISK (未检测到? 请检查)"
    fi

    echo ""
    show_single_disk_info "SD 卡" "$SD_CARD"

    echo ""
    show_single_disk_info "USB 磁盘 1" "$USB_DISK1"

    echo ""
    show_single_disk_info "USB 磁盘 2" "$USB_DISK2"

    echo ""
    echo -e "${BOLD}====================================================${NC}"
}

#========================= 挂载目录选择 =========================

choose_mount_point() {
    local default_path="$DEFAULT_MOUNT_PATH"
    local mount_path="" choice

    # UI 交互全部输出到 stderr，避免被 $(...) 捕获污染返回值
    {
        echo ""
        echo -e "  ${BOLD}请选择挂载目录:${NC}"
        echo -e "    1) 默认目录: ${CYAN}$default_path${NC}"
        echo -e "    2) 自定义目录（手动输入）"

        echo -ne "  ${YELLOW}请输入选项 [1-2] (默认: 1): ${NC}"
        read -r choice
        choice=${choice:-1}

        case $choice in
            1)
                mount_path="$default_path"
                ;;
            2)
                while true; do
                    echo -ne "  ${YELLOW}请输入挂载目录的绝对路径 (如 /mnt/my_data): ${NC}"
                    read -r mount_path
                    if [ -z "$mount_path" ]; then
                        print_warn "路径不能为空，请重新输入。"
                        continue
                    fi
                    if [[ "$mount_path" != /* ]]; then
                        print_warn "请使用绝对路径（以 / 开头）。"
                        continue
                    fi
                    case "$mount_path" in
                        /|/bin|/boot|/dev|/etc|/lib|/lib64|/proc|/root|/run|/sbin|/sys|/usr|/var)
                            print_error "不能使用系统关键目录作为挂载点！"
                            continue
                            ;;
                    esac
                    break
                done
                ;;
            *)
                mount_path="$default_path"
                ;;
        esac

        if [ -d "$mount_path" ] && [ "$(ls -A "$mount_path" 2>/dev/null)" ]; then
            print_warn "目录 '$mount_path' 已存在且不为空。"
            print_info "挂载后原有内容将被隐藏（卸载后会恢复）。"
            if ! confirm "是否继续？"; then
                return 1
            fi
        fi

        if [ ! -d "$mount_path" ]; then
            mkdir -p "$mount_path"
            print_ok "已创建目录: $mount_path"
        fi
    } >&2

    echo "$mount_path"
}

#========================= 通用挂载执行 =========================

do_mount_device() {
    local part="$1"
    local mount_path="$2"
    local fstype="$3"

    print_step "正在挂载 $part → $mount_path ..."

    # 如果挂载目录已被占用，先卸载
    if mountpoint -q "$mount_path" 2>/dev/null; then
        print_warn "$mount_path 已被占用，正在卸载..."
        umount "$mount_path" 2>/dev/null || true
    fi

    local mount_rc=0 mount_err
    local retry=0

    while [ $retry -lt 3 ]; do
        # 尝试挂载（不指定 -t，让内核自动检测）
        mount_err=$(mount -o defaults "$part" "$mount_path" 2>&1)
        mount_rc=$?

        if [ $mount_rc -eq 0 ]; then
            return 0
        fi

        retry=$((retry + 1))
        [ $retry -ge 3 ] && break

        print_warn "挂载失败 (第${retry}次)，正在重试..."

        # 根据设备类型采取不同的刷新策略
        local parent_disk="${part%[0-9]*}"
        parent_disk="${parent_disk%p}"

        if [[ "$parent_disk" == *mmcblk* ]]; then
            # mmcblk SD卡设备：通过 sysfs 重新扫描卡片
            local mmc_dev="${parent_disk##*/}"
            if [ -f "/sys/block/${mmc_dev}/device/rescan" ]; then
                echo 1 > "/sys/block/${mmc_dev}/device/rescan" 2>/dev/null || true
            fi
        else
            blockdev --rereadpt "$parent_disk" 2>/dev/null || true
        fi

        partprobe "$parent_disk" 2>/dev/null || true
        udevadm settle 2>/dev/null || true
        sync
        sleep 3
    done

    # 三次尝试都失败，输出诊断信息
    echo -e "  ${RED}mount 错误:${NC} $mount_err" >&2
    echo -e "  ${YELLOW}内核日志 (dmesg):${NC}" >&2
    dmesg 2>/dev/null | tail -n 5 | while read -r line; do echo -e "    $line" >&2; done

    return 1
}

#========================= 挂载流程 =========================

mount_partition() {
    local disk_name="$1"
    local disk_dev="$2"
    local part="$3"

    echo ""
    echo -e "${BOLD}========== 挂载 $disk_name ==========${NC}"

    # 检查是否已挂载
    local existing_mp
    existing_mp=$(is_mounted "$part")
    if [ $? -eq 0 ]; then
        print_warn "设备 $part 已经挂载在: $existing_mp"
        if ! confirm "是否卸载后重新挂载？"; then
            return 0
        fi
        umount "$part" 2>/dev/null
        print_ok "已卸载: $part"
    fi

    # 获取文件系统类型，没有则自动格式化
    local fstype
    fstype=$(lsblk -no FSTYPE "$part" 2>/dev/null)
    if [ -z "$fstype" ] || [ "$fstype" = "null" ]; then
        print_warn "设备 $part 没有文件系统，正在自动格式化为 ext4..."
        print_info "大小: $(lsblk -no SIZE "$part" 2>/dev/null)"
        mkfs.ext4 -F "$part"
        if [ $? -ne 0 ]; then
            print_error "格式化失败！"
            return 1
        fi
        print_ok "格式化完成 (ext4)"
        fstype="ext4"
    fi

    print_info "设备: $part  |  文件系统: $fstype  |  大小: $(lsblk -no SIZE "$part" 2>/dev/null)"

    # 选择挂载目录
    local mount_path
    mount_path=$(choose_mount_point)
    if [ $? -ne 0 ] || [ -z "$mount_path" ]; then
        return 1
    fi

    # 执行挂载
    if do_mount_device "$part" "$mount_path" "$fstype"; then
        print_ok "挂载成功！"
        df -h "$mount_path" 2>/dev/null | tail -1 | awk '{printf "  使用: %s / %s (已用 %s%%)\n", $3, $2, $5}'

        echo ""
        if confirm "是否添加到 /etc/fstab 实现开机自动挂载？"; then
            local fstab_entry="$part $mount_path $fstype defaults,nofail 0 0"
            if grep -q "$part" /etc/fstab 2>/dev/null; then
                print_warn "/etc/fstab 中已存在 $part 的记录，跳过添加。"
            else
                cp /etc/fstab /etc/fstab.bak.$(date +%Y%m%d%H%M%S)
                echo "$fstab_entry" >> /etc/fstab
                print_ok "已添加到 /etc/fstab（备份已保存）"
            fi
        fi

        log_action "挂载 $part → $mount_path ($fstype)"
    else
        print_error "挂载失败！请检查设备是否正常。"
        return 1
    fi
}

# 清空磁盘所有分区并全新格式化挂载
wipe_and_fresh_mount() {
    local disk_name="$1"
    local disk_dev="$2"

    echo ""
    echo -e "${RED}${BOLD}========== !! 危险操作 ==========${NC}"
    echo ""
    echo -e "  ${RED}即将对 $disk_name ($disk_dev) 执行全新格式化！${NC}"
    echo -e "  ${RED}磁盘大小: $(get_disk_size "$disk_dev")${NC}"
    echo ""
    echo -e "  ${YELLOW}此操作将:${NC}"
    echo -e "    1. 清除磁盘上所有分区表"
    echo -e "    2. 删除磁盘上所有数据（不可恢复！）"
    echo -e "    3. 创建一个 ext4 分区（使用全部空间）"
    echo -e "    4. 挂载到指定目录"
    echo ""

    if ! confirm "确认清空 $disk_dev 所有数据并全新格式化？"; then
        return 1
    fi

    # 检查是否已挂载
    local mp
    mp=$(lsblk -no MOUNTPOINT "$disk_dev" 2>/dev/null | head -1)
    if [ -n "$mp" ]; then
        print_step "正在卸载已挂载的分区..."
        umount "$disk_dev"* 2>/dev/null || true
        print_ok "已卸载。"
    fi

    # 清除分区表
    print_step "正在清除分区表..."
    wipefs -a "$disk_dev" 2>/dev/null
    # 也清除分区上的文件系统签名
    for p in ${disk_dev}*; do
        [ -b "$p" ] && [ "$p" != "$disk_dev" ] && wipefs -a "$p" 2>/dev/null
    done
    print_ok "分区表已清除。"

    # 创建 GPT 分区表 + 单个分区
    print_step "正在创建分区（使用全部空间）..."
    parted -s "$disk_dev" mklabel gpt 2>/dev/null
    parted -s "$disk_dev" mkpart primary ext4 0% 100% 2>/dev/null
    print_ok "分区创建完成。"

    # 刷新内核分区表（mmcblk 设备必须用 sysfs rescan）
    print_step "等待内核加载分区表..."
    if [[ "$disk_dev" == *mmcblk* ]]; then
        local mmc_dev="${disk_dev##*/}"
        if [ -f "/sys/block/${mmc_dev}/device/rescan" ]; then
            echo 1 > "/sys/block/${mmc_dev}/device/rescan" 2>/dev/null || true
            sleep 3
        fi
    fi
    partprobe "$disk_dev" 2>/dev/null || true
    blockdev --rereadpt "$disk_dev" 2>/dev/null || true
    udevadm settle 2>/dev/null || true
    sleep 2

    # 获取新分区名
    local new_part
    if [[ "$disk_dev" == *mmcblk* ]]; then
        new_part="${disk_dev}p1"
    else
        new_part="${disk_dev}1"
    fi

    if [ ! -b "$new_part" ]; then
        print_warn "分区设备 $new_part 未出现，尝试重新探测..."
        if [[ "$disk_dev" == *mmcblk* ]]; then
            local mmc_dev="${disk_dev##*/}"
            if [ -f "/sys/block/${mmc_dev}/device/rescan" ]; then
                echo 1 > "/sys/block/${mmc_dev}/device/rescan" 2>/dev/null || true
                sleep 3
            fi
        fi
        partprobe "$disk_dev" 2>/dev/null || true
        blockdev --rereadpt "$disk_dev" 2>/dev/null || true
        udevadm settle 2>/dev/null || true
        sleep 3
        new_part=$(lsblk -lnpo NAME "$disk_dev" 2>/dev/null | tail -n +2 | head -1)
        if [ -z "$new_part" ] || [ ! -b "$new_part" ]; then
            print_error "无法找到新分区，请手动检查。"
            return 1
        fi
    fi

    print_info "新分区: $new_part"

    # 格式化（此时分区表已被内核正确识别）
    print_step "正在格式化 $new_part 为 ext4..."
    mkfs.ext4 -F "$new_part"
    sync
    print_ok "格式化完成。"

    # 挂载
    mount_partition "$disk_name" "$disk_dev" "$new_part"
}

# 在已有分区表的磁盘上新建一个分区（使用剩余空间）
create_new_partition_on_disk() {
    local disk_name="$1"
    local disk_dev="$2"

    echo ""
    echo -e "${BOLD}========== 在 $disk_name 上创建新分区 ==========${NC}"
    echo ""

    # 获取下一个分区编号
    local next_num
    next_num=$(parted -s "$disk_dev" print 2>/dev/null | awk '/^ [0-9]/ {last=$1} END {print last+1}')
    [ -z "$next_num" ] && next_num=1

    # 获取剩余空间
    local free_end
    free_end=$(parted -s "$disk_dev" unit GB print free 2>/dev/null | grep "Free Space" | tail -1 | awk '{print $3}' | sed 's/GB//')
    if [ -z "$free_end" ]; then
        print_error "磁盘上没有剩余空间！"
        return 1
    fi

    print_info "剩余空间约: ${free_end}GB"

    # 让用户输入分区名称（作为挂载子目录）
    local part_name=""
    while true; do
        echo -ne "  ${YELLOW}请输入新分区的名称（作为挂载目录名，如 backup）: ${NC}"
        read -r part_name
        if [ -z "$part_name" ]; then
            print_warn "名称不能为空。"
            continue
        fi
        # 只允许字母、数字、下划线、短横线
        if ! [[ "$part_name" =~ ^[a-zA-Z0-9_-]+$ ]]; then
            print_warn "名称只能包含字母、数字、下划线和短横线。"
            continue
        fi
        break
    done

    local mount_path="$DEFAULT_MOUNT_PATH/$part_name"

    # 构建新分区设备名
    local new_part
    if [[ "$disk_dev" == *mmcblk* ]]; then
        new_part="${disk_dev}p${next_num}"
    else
        new_part="${disk_dev}${next_num}"
    fi

    echo ""
    echo -e "  ${BOLD}即将创建分区:${NC}"
    echo -e "    磁盘: $disk_dev"
    echo -e "    新分区: $new_part"
    echo -e "    编号: 第 ${next_num} 个分区"
    echo -e "    挂载到: $mount_path"
    echo ""

    if ! confirm "确认创建新分区并格式化为 ext4？"; then
        return 1
    fi

    # 创建分区
    print_step "正在创建分区 $next_num ..."
    local last_part_end
    last_part_end=$(parted -s "$disk_dev" unit GB print 2>/dev/null | awk '/^ [0-9]/ {last=$2} END {print last}' | sed 's/GB//')
    if [ -z "$last_part_end" ]; then
        last_part_end=0
    fi
    parted -s "$disk_dev" mkpart primary ext4 "${last_part_end}GB" "100%" 2>/dev/null
    print_ok "分区创建完成。"

    # 刷新内核分区表（mmcblk 设备必须用 sysfs rescan）
    print_step "等待内核加载分区表..."
    if [[ "$disk_dev" == *mmcblk* ]]; then
        local mmc_dev="${disk_dev##*/}"
        if [ -f "/sys/block/${mmc_dev}/device/rescan" ]; then
            echo 1 > "/sys/block/${mmc_dev}/device/rescan" 2>/dev/null || true
            sleep 3
        fi
    fi
    partprobe "$disk_dev" 2>/dev/null || true
    blockdev --rereadpt "$disk_dev" 2>/dev/null || true
    udevadm settle 2>/dev/null || true
    sleep 2

    if [ ! -b "$new_part" ]; then
        if [[ "$disk_dev" == *mmcblk* ]]; then
            local mmc_dev="${disk_dev##*/}"
            if [ -f "/sys/block/${mmc_dev}/device/rescan" ]; then
                echo 1 > "/sys/block/${mmc_dev}/device/rescan" 2>/dev/null || true
                sleep 3
            fi
        fi
        partprobe "$disk_dev" 2>/dev/null || true
        blockdev --rereadpt "$disk_dev" 2>/dev/null || true
        udevadm settle 2>/dev/null || true
        sleep 3
        new_part=$(lsblk -lnpo NAME "$disk_dev" 2>/dev/null | tail -1)
        if [ -z "$new_part" ] || [ ! -b "$new_part" ]; then
            print_error "无法找到新创建的分区。"
            return 1
        fi
    fi

    # 格式化并挂载
    mkfs.ext4 -F "$new_part"
    sync
    print_ok "已格式化 $new_part 为 ext4。"

    # 挂载
    sleep 1

    mkdir -p "$mount_path"
    local mount_err
    if mount_err=$(mount "$new_part" "$mount_path" 2>&1); then
        print_ok "挂载成功！ $new_part → $mount_path"
        df -h "$mount_path" 2>/dev/null | tail -1 | awk '{printf "  使用: %s / %s (已用 %s%%)\n", $3, $2, $5}'

        if confirm "是否添加到 /etc/fstab 实现开机自动挂载？"; then
            local fstab_entry="$new_part $mount_path ext4 defaults,nofail 0 0"
            if ! grep -q "$new_part" /etc/fstab 2>/dev/null; then
                cp /etc/fstab /etc/fstab.bak.$(date +%Y%m%d%H%M%S)
                echo "$fstab_entry" >> /etc/fstab
                print_ok "已添加到 /etc/fstab"
            fi
        fi

        log_action "新建分区挂载: $disk_dev → $new_part → $mount_path"
    else
        echo -e "  ${RED}mount 错误信息:${NC} $mount_err" >&2
        print_error "挂载失败！"
        return 1
    fi
}

# 选择设备（支持分区和无分区表的设备）
select_and_mount_device() {
    local disk_name="$1"
    local disk_dev="$2"

    if ! check_disk_exists "$disk_dev"; then
        print_error "$disk_name ($disk_dev) 不存在，请确认设备已插入。"
        return 1
    fi

    local parts
    parts=$(get_partitions "$disk_dev")
    local raw_fs
    raw_fs=$(disk_has_fs_directly "$disk_dev")

    # 判断磁盘状态
    local has_partitions=0
    [ -n "$parts" ] && has_partitions=1

    local has_raw_fs=0
    [ -n "$raw_fs" ] && has_raw_fs=1

    echo ""
    echo -e "${BOLD}========== $disk_name ($disk_dev) ==========${NC}"
    echo -e "  大小: $(get_disk_size "$disk_dev")  |  型号: $(get_disk_model "$disk_dev")"
    echo ""

    # 如果磁盘上有分区或直接格式化的数据，首先提示全新格式化选项
    if [ $has_partitions -eq 1 ] || [ $has_raw_fs -eq 1 ]; then
        echo -e "  ${RED}${BOLD}!! 检测到此磁盘上有已有分区/数据！${NC}"
        echo ""

        # 列出已有的分区
        if [ $has_partitions -eq 1 ]; then
            echo -e "  ${BOLD}已有分区:${NC}"
            echo "$parts" | while read -r line; do
                local pname=$(echo "$line" | awk '{print $1}')
                local psize=$(echo "$line" | awk '{print $2}')
                local pfstype=$(echo "$line" | awk '{print $3}')
                local pmp=$(echo "$line" | awk '{print $4}')
                local mp_info=""
                [ -n "$pmp" ] && mp_info=" ${GREEN}→ $pmp${NC}"
                echo -e "    ${pname}  ${psize}  ${pfstype:-无文件系统}${mp_info}"
            done
        elif [ $has_raw_fs -eq 1 ]; then
            echo -e "  ${BOLD}已有文件系统（无分区表）:${NC}"
            echo -e "    ${disk_dev}  $(get_disk_size "$disk_dev")  ${raw_fs}"
        fi

        echo ""
        echo -e "  ${BOLD}请选择操作:${NC}"
        echo -e "    ${BOLD}0)${NC} ${RED}${BOLD}清空所有分区/数据，全新格式化挂载${NC}"
        echo -e "    ${BOLD}1)${NC} 保留现有数据，直接挂载已有分区"
        echo -e "    ${BOLD}2)${NC} 在剩余空间创建新分区并挂载"
        echo ""

        echo -ne "  ${YELLOW}请输入选项 [0-2] (默认: 0): ${NC}"
        read -r action
        action=${action:-0}

        case $action in
            0)
                wipe_and_fresh_mount "$disk_name" "$disk_dev"
                return $?
                ;;
            1)
                # 继续到下面的分区选择逻辑
                ;;
            2)
                create_new_partition_on_disk "$disk_name" "$disk_dev"
                return $?
                ;;
            *)
                print_error "无效的选择。"
                return 1
                ;;
        esac
    fi

    # 选择已有分区
    echo ""
    echo -e "  ${BOLD}选择要挂载的已有分区:${NC}"
    echo ""
    local i=1
    local dev_array=()

    if [ -n "$parts" ]; then
        while IFS= read -r line; do
            local pname=$(echo "$line" | awk '{print $1}')
            local psize=$(echo "$line" | awk '{print $2}')
            local pfstype=$(echo "$line" | awk '{print $3}')
            local pmp=$(echo "$line" | awk '{print $4}')
            local mp_info=""
            [ -n "$pmp" ] && mp_info=" ${GREEN}(已挂载: $pmp)${NC}"
            echo -e "  ${BOLD}$i)${NC} $pname  |  $psize  |  ${pfstype:-无文件系统}${mp_info}"
            dev_array+=("$pname")
            ((i++))
        done <<< "$parts"
    fi

    if [ -n "$raw_fs" ]; then
        local raw_mp=$(lsblk -ndo MOUNTPOINT "$disk_dev" 2>/dev/null)
        local raw_mp_info=""
        [ -n "$raw_mp" ] && raw_mp_info=" ${GREEN}(已挂载: $raw_mp)${NC}"
        echo -e "  ${BOLD}$i)${NC} $disk_dev (整盘)  |  $(get_disk_size "$disk_dev")  |  ${raw_fs}${raw_mp_info}"
        dev_array+=("$disk_dev")
        ((i++))
    fi

    # 始终提供「新建分区」选项
    echo -e "  ${BOLD}$i)${NC} ${CYAN}创建新分区（使用剩余空间）${NC}"
    local new_part_option=$i

    if [ ${#dev_array[@]} -eq 0 ]; then
        echo ""
        echo -e "  ${YELLOW}该磁盘没有任何可用的文件系统。${NC}"
        echo ""
        echo -ne "  ${YELLOW}请选择 [${new_part_option}=新建分区]: ${NC}"
        read -r choice
        if [ "$choice" = "$new_part_option" ]; then
            create_new_partition_on_disk "$disk_name" "$disk_dev"
        else
            print_error "无效的选择。"
        fi
        return $?
    fi

    echo ""
    echo -e "  ${YELLOW}请选择 [1-${#dev_array[@]}=已有分区, ${new_part_option}=新建分区]: ${NC}"
    read -r choice
    if [ "$choice" = "$new_part_option" ]; then
        create_new_partition_on_disk "$disk_name" "$disk_dev"
        return $?
    fi
    if ! [[ "$choice" =~ ^[0-9]+$ ]] || [ "$choice" -lt 1 ] || [ "$choice" -gt "${#dev_array[@]}" ]; then
        print_error "无效的选择。"
        return 1
    fi

    local selected="${dev_array[$((choice-1))]}"
    mount_partition "$disk_name" "$disk_dev" "$selected"
}

#========================= LVM 双盘合并 =========================

lvm_merge_usb_disks() {
    echo ""
    echo -e "${BOLD}========== LVM 双盘合并挂载 ==========${NC}"
    echo ""
    echo -e "  ${CYAN}功能说明:${NC}"
    echo -e "  将两个 USB 磁盘通过 LVM 合并为一个大卷。"
    echo -e "  两个物理磁盘的空间将合并成一个逻辑分区。"
    echo ""
    echo -e "  ${RED}${BOLD}!! 警告: 此操作会清除两个磁盘上的所有数据！${NC}"
    echo ""

    if ! check_disk_exists "$USB_DISK1"; then
        print_error "USB 磁盘 1 ($USB_DISK1) 不存在，请确认已插入。"
        return 1
    fi
    if ! check_disk_exists "$USB_DISK2"; then
        print_error "USB 磁盘 2 ($USB_DISK2) 不存在，请确认已插入。"
        return 1
    fi

    # 检查是否已挂载
    local m1 m2
    m1=$(lsblk -no MOUNTPOINT "$USB_DISK1" 2>/dev/null | head -1)
    m2=$(lsblk -no MOUNTPOINT "$USB_DISK2" 2>/dev/null | head -1)
    if [ -n "$m1" ] || [ -n "$m2" ]; then
        print_error "磁盘当前已挂载，请先用菜单 5 卸载后再操作。"
        echo -e "  已挂载: $USB_DISK1 → ${m1:-(无)}"
        echo -e "  已挂载: $USB_DISK2 → ${m2:-(无)}"
        return 1
    fi

    echo -e "  ${BOLD}将要合并的磁盘:${NC}"
    echo -e "    $USB_DISK1  |  $(get_disk_size "$USB_DISK1")  |  $(get_disk_model "$USB_DISK1")"
    echo -e "    $USB_DISK2  |  $(get_disk_size "$USB_DISK2")  |  $(get_disk_model "$USB_DISK2")"
    echo ""

    if ! confirm "确认清除以上 2 个磁盘的所有数据并合并为 LVM 卷？"; then
        return 1
    fi

    check_lvm || return 1

    local mount_path
    mount_path=$(choose_mount_point)
    if [ $? -ne 0 ] || [ -z "$mount_path" ]; then
        return 1
    fi

    local vg_name="vg_usbdata"
    local lv_name="lv_usbdata"
    local lv_path="/dev/$vg_name/$lv_name"

    print_step "1/5 清除磁盘分区表..."
    wipefs -a "$USB_DISK1" 2>/dev/null
    wipefs -a "$USB_DISK2" 2>/dev/null
    print_ok "分区表已清除。"

    print_step "2/5 创建物理卷 (PV)..."
    pvcreate -y "$USB_DISK1" && pvcreate -y "$USB_DISK2"
    print_ok "物理卷创建完成。"

    print_step "3/5 创建卷组 (VG)..."
    vgcreate "$vg_name" "$USB_DISK1" "$USB_DISK2"
    print_ok "卷组 '$vg_name' 创建完成。"

    print_step "4/5 创建逻辑卷 (LV，使用全部空间)..."
    lvcreate -l 100%FREE -n "$lv_name" "$vg_name"
    print_ok "逻辑卷 '$lv_name' 创建完成。"
    print_info "LVM 卷大小: $(lvdisplay -C --noheadings -o LV_SIZE "$lv_path" 2>/dev/null | tr -d ' ')"

    print_step "5/5 格式化逻辑卷为 ext4..."
    mkfs.ext4 -F "$lv_path"
    print_ok "格式化完成。"

    print_step "正在挂载 $lv_path → $mount_path ..."
    if mount "$lv_path" "$mount_path"; then
        print_ok "LVM 卷挂载成功！"
        df -h "$mount_path" 2>/dev/null | tail -1 | awk '{printf "  使用: %s / %s (已用 %s%%)\n", $3, $2, $5}'

        echo ""
        if confirm "是否添加到 /etc/fstab 实现开机自动挂载？"; then
            local fstab_entry="$lv_path $mount_path ext4 defaults,nofail 0 0"
            if ! grep -q "$lv_path" /etc/fstab 2>/dev/null; then
                cp /etc/fstab /etc/fstab.bak.$(date +%Y%m%d%H%M%S)
                echo "$fstab_entry" >> /etc/fstab
                print_ok "已添加到 /etc/fstab"
            else
                print_warn "/etc/fstab 中已存在该记录。"
            fi
        fi

        log_action "LVM合并挂载: $USB_DISK1 + $USB_DISK2 → $lv_path → $mount_path"
    else
        print_error "挂载失败！"
        return 1
    fi

    echo ""
    echo -e "${GREEN}${BOLD}LVM 双盘合并挂载完成！${NC}"
    echo -e "  LVM 路径: ${CYAN}$lv_path${NC}"
    echo -e "  挂载目录: ${CYAN}$mount_path${NC}"
}

#========================= 卸载功能 =========================

unmount_disk() {
    echo ""
    echo -e "${BOLD}========== 卸载磁盘 ==========${NC}"
    echo ""

    # 列出所有非系统挂载（含 LVM /dev/mapper/*）
    echo -e "  ${BOLD}当前挂载列表（已排除系统关键挂载）:${NC}"
    echo ""

    local mounts
    mounts=$(mount | grep -E "^/dev/(sd[a-z]|mmcblk0|mapper/)" | grep -v "$SYSTEM_DISK" | sort)

    if [ -z "$mounts" ]; then
        echo -e "  ${YELLOW}没有可卸载的非系统磁盘挂载。${NC}"
        return 0
    fi

    echo "$mounts" | awk '{printf "  %s) %s → %s  (%s)\n", NR, $1, $3, $5}'

    echo ""
    echo -e "  ${BOLD}选择卸载方式:${NC}"
    echo -e "    0) 返回主菜单"
    echo -e "    1) 卸载单个挂载"
    echo -e "    2) 卸载所有非系统挂载"

    echo -ne "  ${YELLOW}请输入选项: ${NC}"
    read -r choice

    case $choice in
        0) return 0 ;;
        1)
            local count=$(echo "$mounts" | wc -l)
            echo -ne "  ${YELLOW}请输入要卸载的编号 [1-$count]: ${NC}"
            read -r num
            local target
            target=$(echo "$mounts" | sed -n "${num}p" | awk '{print $1}')
            if [ -z "$target" ]; then
                print_error "无效的选择。"
                return 1
            fi
            if umount "$target" 2>/dev/null; then
                print_ok "已卸载: $target"
            else
                print_error "卸载失败，可能设备正忙。"
                print_info "提示: 可用 'lsof $target' 或 'fuser -m $target' 查看占用进程。"
            fi
            ;;
        2)
            if confirm "确认卸载所有非系统磁盘？"; then
                echo "$mounts" | awk '{print $1}' | while read -r dev; do
                    print_step "正在卸载: $dev ..."
                    umount "$dev" 2>/dev/null && print_ok "已卸载" || print_warn "卸载失败"
                done
            fi
            ;;
        *) print_error "无效的选择。" ;;
    esac
}

#========================= 查看挂载状态 =========================

show_mount_status() {
    echo ""
    echo -e "${BOLD}========== 当前挂载状态 ==========${NC}"
    echo ""
    df -h | grep -E "^Filesystem|^/dev/" | grep -v -E "tmpfs|devtmpfs|overlay" | \
        awk '{printf "  %-30s %6s  %6s  %6s  %s%%  %s\n", $1, $2, $3, $4, $5, $6}'

    echo ""
    echo -e "${BOLD}========== LVM 状态 ==========${NC}"
    if command -v lvs &>/dev/null; then
        echo ""
        vgs 2>/dev/null | head -10
        echo ""
        lvs 2>/dev/null | head -10
    else
        echo -e "  ${YELLOW}未安装 LVM 工具${NC}"
    fi
}

#========================= 设置默认挂载目录 =========================

set_default_mount_path() {
    echo ""
    echo -e "${BOLD}========== 设置默认挂载目录 ==========${NC}"
    echo -e "  当前默认挂载目录: ${CYAN}$DEFAULT_MOUNT_PATH${NC}"
    echo -ne "  ${YELLOW}请输入新的默认挂载目录 (留空保持不变): ${NC}"
    read -r new_path
    if [ -n "$new_path" ]; then
        if [[ "$new_path" != /* ]]; then
            print_warn "请使用绝对路径（以 / 开头）。未做更改。"
        else
            DEFAULT_MOUNT_PATH="$new_path"
            echo -e "  ${GREEN}默认挂载目录已更新为: $DEFAULT_MOUNT_PATH${NC}"
        fi
    fi
}

#========================= 主菜单 =========================

main_menu() {
    while true; do
        clear 2>/dev/null || true
        print_title
        show_disk_info

        # 检查各磁盘是否存在
        local sd_ok=0 usb1_ok=0 usb2_ok=0
        check_disk_exists "$SD_CARD" && sd_ok=1
        check_disk_exists "$USB_DISK1" && usb1_ok=1
        check_disk_exists "$USB_DISK2" && usb2_ok=1
        local any_ok=$((sd_ok + usb1_ok + usb2_ok))

        echo ""
        echo -e "${BOLD}============== 操作菜单 ==============${NC}"
        echo ""

        # 如果没有任何可挂载的磁盘
        if [ $any_ok -eq 0 ]; then
            echo ""
            echo -e "  ${RED}${BOLD}+==================================================+${NC}"
            echo -e "  ${RED}${BOLD}|  !!  未检测到任何可挂载的存储设备！              |${NC}"
            echo -e "  ${RED}${BOLD}+==================================================+${NC}"
            echo -e "  ${RED}${BOLD}|                                                |${NC}"
            echo -e "  ${RED}${BOLD}|  请检查:                                       |${NC}"
            echo -e "  ${RED}${BOLD}|  1. SD 卡是否已插入卡槽？                      |${NC}"
            echo -e "  ${RED}${BOLD}|  2. USB 移动硬盘是否已连接到 USB 接口？        |${NC}"
            echo -e "  ${RED}${BOLD}|  3. 连接后请稍等几秒让系统识别设备             |${NC}"
            echo -e "  ${RED}${BOLD}|                                                |${NC}"
            echo -e "  ${RED}${BOLD}+==================================================+${NC}"
            echo ""

            echo -e "  ${BOLD}6)${NC} 查看当前挂载状态"
            echo -e "  ${BOLD}7)${NC} 设置默认挂载目录  (当前: ${CYAN}$DEFAULT_MOUNT_PATH${NC})"
            echo -e "  ${BOLD}0)${NC} 退出"
            echo ""

            echo -ne "  ${YELLOW}请输入选项 [0/6/7]: ${NC}"
            read -r choice

            case $choice in
                6) show_mount_status ;;
                7) set_default_mount_path ;;
                0)
                    echo ""
                    echo -e "${GREEN}感谢使用！再见！${NC}"
                    exit 0
                    ;;
                *)
                    print_error "无效选项，请输入 0/6/7。"
                    ;;
            esac
        else
            # 有设备时，标记不可用的选项
            local sd_label="挂载 SD 卡"
            local usb1_label="挂载 USB 磁盘 1"
            local usb2_label="挂载 USB 磁盘 2"
            local lvm_label="LVM 双盘合并挂载"

            if [ $sd_ok -eq 1 ]; then
                echo -e "  ${BOLD}1)${NC} ${sd_label}          (${GREEN}$SD_CARD${NC})"
            else
                echo -e "  ${YELLOW}1)${NC} ${sd_label}          ${YELLOW}(SD 卡未插入)${NC}"
            fi

            if [ $usb1_ok -eq 1 ]; then
                echo -e "  ${BOLD}2)${NC} ${usb1_label}     (${GREEN}$USB_DISK1${NC})"
            else
                echo -e "  ${YELLOW}2)${NC} ${usb1_label}     ${YELLOW}(USB 磁盘 1 未连接)${NC}"
            fi

            if [ $usb2_ok -eq 1 ]; then
                echo -e "  ${BOLD}3)${NC} ${usb2_label}     (${GREEN}$USB_DISK2${NC})"
            else
                echo -e "  ${YELLOW}3)${NC} ${usb2_label}     ${YELLOW}(USB 磁盘 2 未连接)${NC}"
            fi

            if [ $usb1_ok -eq 1 ] && [ $usb2_ok -eq 1 ]; then
                echo -e "  ${BOLD}4)${NC} ${lvm_label}    (${CYAN}$USB_DISK1 + $USB_DISK2${NC})"
            else
                echo -e "  ${YELLOW}4)${NC} ${lvm_label}    ${YELLOW}(需要两个 USB 磁盘都已连接)${NC}"
            fi

            echo -e "  ${BOLD}5)${NC} 卸载磁盘"
            echo -e "  ${BOLD}6)${NC} 查看当前挂载状态"
            echo -e "  ${BOLD}7)${NC} 设置默认挂载目录  (当前: ${CYAN}$DEFAULT_MOUNT_PATH${NC})"
            echo -e "  ${BOLD}0)${NC} 退出"
            echo ""

            echo -ne "  ${YELLOW}请输入选项 [0-7]: ${NC}"
            read -r choice

            case $choice in
                1)
                    if [ $sd_ok -eq 1 ]; then
                        select_and_mount_device "SD 卡" "$SD_CARD"
                    else
                        print_error "SD 卡未插入，请先插入 SD 卡。"
                    fi
                    ;;
                2)
                    if [ $usb1_ok -eq 1 ]; then
                        select_and_mount_device "USB 磁盘 1" "$USB_DISK1"
                    else
                        print_error "USB 磁盘 1 未连接，请先接入 USB 设备。"
                    fi
                    ;;
                3)
                    if [ $usb2_ok -eq 1 ]; then
                        select_and_mount_device "USB 磁盘 2" "$USB_DISK2"
                    else
                        print_error "USB 磁盘 2 未连接，请先接入 USB 设备。"
                    fi
                    ;;
                4)
                    if [ $usb1_ok -eq 1 ] && [ $usb2_ok -eq 1 ]; then
                        lvm_merge_usb_disks
                    else
                        print_error "LVM 合并需要两个 USB 磁盘都已连接！"
                    fi
                    ;;
                5) unmount_disk ;;
                6) show_mount_status ;;
                7) set_default_mount_path ;;
                0)
                    echo ""
                    echo -e "${GREEN}感谢使用！再见！${NC}"
                    exit 0
                    ;;
                *)
                    print_error "无效选项，请输入 0-7。"
                    ;;
            esac
        fi

        echo ""
        echo -ne "${YELLOW}按 Enter 键返回主菜单...${NC}"
        read -r
    done
}

#========================= 脚本入口 =========================

echo "" > "$MOUNT_LOG"
check_root
main_menu
