#!/bin/bash
# Tool_OCR WSL Ubuntu 開發環境設置腳本
#
# Usage:
#   ./setup_dev_env.sh              完整安裝 (自動偵測 GPU)
#   ./setup_dev_env.sh --cpu-only   強制使用 CPU 版本
#   ./setup_dev_env.sh --skip-db    跳過數據庫初始化
#   ./setup_dev_env.sh --help       顯示幫助

set -e  # 遇到錯誤時停止

# 顏色定義
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 配置變數
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MIN_DISK_GB=10
MIN_MEMORY_GB=4
MIN_PYTHON_VERSION="3.10"
FORCE_CPU=false
SKIP_DB=false

# ===== 幫助信息 =====
show_help() {
    echo "Tool_OCR 開發環境設置腳本"
    echo ""
    echo "Usage: ./setup_dev_env.sh [options]"
    echo ""
    echo "Options:"
    echo "  --cpu-only    強制使用 CPU 版本的 PaddlePaddle (跳過 GPU 偵測)"
    echo "  --skip-db     跳過數據庫初始化步驟"
    echo "  --help        顯示此幫助信息"
    echo ""
    echo "Examples:"
    echo "  ./setup_dev_env.sh              # 完整安裝"
    echo "  ./setup_dev_env.sh --cpu-only   # 不使用 GPU"
    echo ""
}

# 解析參數
while [[ $# -gt 0 ]]; do
    case $1 in
        --cpu-only)
            FORCE_CPU=true
            shift
            ;;
        --skip-db)
            SKIP_DB=true
            shift
            ;;
        --help|-h)
            show_help
            exit 0
            ;;
        *)
            echo -e "${RED}Unknown option: $1${NC}"
            show_help
            exit 1
            ;;
    esac
done

# ===== 工具函數 =====
print_header() {
    echo ""
    echo -e "${BLUE}================================${NC}"
    echo -e "${BLUE}    Tool_OCR 開發環境設置${NC}"
    echo -e "${BLUE}================================${NC}"
    echo ""
}

print_step() {
    local step=$1
    local total=$2
    local msg=$3
    echo ""
    echo -e "${YELLOW}[$step/$total] $msg${NC}"
}

print_success() {
    echo -e "${GREEN}✓ $1${NC}"
}

print_warning() {
    echo -e "${YELLOW}⚠ $1${NC}"
}

print_error() {
    echo -e "${RED}✗ $1${NC}"
}

# ===== 預檢函數 =====
check_not_root() {
    if [ "$EUID" -eq 0 ]; then
        print_error "請不要使用 sudo 運行此腳本"
        echo "腳本會在需要時提示輸入 sudo 密碼"
        exit 1
    fi
}

check_disk_space() {
    local available_gb=$(df -BG "$SCRIPT_DIR" | awk 'NR==2 {print $4}' | sed 's/G//')
    if [ "$available_gb" -lt "$MIN_DISK_GB" ]; then
        print_error "磁碟空間不足: ${available_gb}GB 可用, 需要至少 ${MIN_DISK_GB}GB"
        echo ""
        echo "解決方案:"
        echo "  1. 清理不需要的文件: sudo apt autoremove && sudo apt clean"
        echo "  2. 刪除舊的 Docker 映像: docker system prune -a"
        echo "  3. 清理 pip 緩存: pip cache purge"
        exit 1
    fi
    print_success "磁碟空間: ${available_gb}GB 可用"
}

check_memory() {
    local total_gb=$(free -g | awk '/^Mem:/{print $2}')
    if [ "$total_gb" -lt "$MIN_MEMORY_GB" ]; then
        print_warning "記憶體較低: ${total_gb}GB (建議 ${MIN_MEMORY_GB}GB+)"
        echo "  OCR 處理可能會較慢，建議增加記憶體或使用 swap"
    else
        print_success "系統記憶體: ${total_gb}GB"
    fi
}

check_python_version() {
    if ! command -v python3 &> /dev/null; then
        print_error "未找到 Python3"
        echo ""
        echo "解決方案:"
        echo "  sudo apt update && sudo apt install python3 python3-pip python3-venv"
        exit 1
    fi

    local py_version=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
    local py_major=$(echo $py_version | cut -d. -f1)
    local py_minor=$(echo $py_version | cut -d. -f2)
    local min_major=$(echo $MIN_PYTHON_VERSION | cut -d. -f1)
    local min_minor=$(echo $MIN_PYTHON_VERSION | cut -d. -f2)

    if [ "$py_major" -lt "$min_major" ] || ([ "$py_major" -eq "$min_major" ] && [ "$py_minor" -lt "$min_minor" ]); then
        print_error "Python 版本過低: $py_version (需要 $MIN_PYTHON_VERSION+)"
        echo ""
        echo "解決方案:"
        echo "  sudo apt update && sudo apt install python3.10 python3.10-venv"
        exit 1
    fi
    print_success "Python 版本: $py_version"
}

run_preflight_checks() {
    echo -e "${BLUE}執行預檢...${NC}"
    check_not_root
    check_disk_space
    check_memory
    check_python_version
    echo ""
    print_success "預檢完成"
}

# ===== GPU 偵測函數 =====
detect_gpu() {
    if [ "$FORCE_CPU" = true ]; then
        echo -e "${YELLOW}ℹ 已指定 --cpu-only，跳過 GPU 偵測${NC}"
        USE_GPU=false
        PADDLE_PACKAGE="paddlepaddle==3.2.0"
        PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cpu/"
        return
    fi

    if command -v nvidia-smi &> /dev/null; then
        print_success "偵測到 NVIDIA GPU"
        nvidia-smi --query-gpu=name,memory.total --format=csv,noheader 2>/dev/null || true

        CUDA_VERSION=$(nvidia-smi 2>/dev/null | grep "CUDA Version" | awk '{print $9}')
        if [ -n "$CUDA_VERSION" ]; then
            print_success "CUDA 版本: $CUDA_VERSION"

            CUDA_MAJOR=$(echo $CUDA_VERSION | cut -d. -f1)
            CUDA_MINOR=$(echo $CUDA_VERSION | cut -d. -f2)

            if [ "$CUDA_MAJOR" -ge 13 ] || ([ "$CUDA_MAJOR" -eq 12 ] && [ "$CUDA_MINOR" -ge 6 ]); then
                echo "將安裝 PaddlePaddle GPU 版本 (CUDA 12.6+)"
                USE_GPU=true
                PADDLE_PACKAGE="paddlepaddle-gpu==3.2.0"
                PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cu126/"
            elif [ "$CUDA_MAJOR" -eq 12 ]; then
                echo "將安裝 PaddlePaddle GPU 版本 (CUDA 12.x)"
                USE_GPU=true
                PADDLE_PACKAGE="paddlepaddle-gpu==3.2.0"
                PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cu126/"
            elif [ "$CUDA_MAJOR" -eq 11 ]; then
                echo "將安裝 PaddlePaddle GPU 版本 (CUDA 11.8)"
                USE_GPU=true
                PADDLE_PACKAGE="paddlepaddle-gpu==3.2.0"
                PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cu118/"
            else
                print_warning "CUDA 版本不支援 ($CUDA_VERSION)，將使用 CPU 版本"
                USE_GPU=false
                PADDLE_PACKAGE="paddlepaddle==3.2.0"
                PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cpu/"
            fi
        else
            print_warning "無法獲取 CUDA 版本，將使用 CPU 版本"
            USE_GPU=false
            PADDLE_PACKAGE="paddlepaddle==3.2.0"
            PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cpu/"
        fi
    else
        echo -e "${YELLOW}ℹ 未偵測到 NVIDIA GPU，將使用 CPU 版本${NC}"
        USE_GPU=false
        PADDLE_PACKAGE="paddlepaddle==3.2.0"
        PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cpu/"
    fi
}

# ===== 數據庫初始化 =====
init_database() {
    if [ "$SKIP_DB" = true ]; then
        print_warning "已指定 --skip-db，跳過數據庫初始化"
        return
    fi

    echo "初始化數據庫..."
    cd "$SCRIPT_DIR/backend"

    # 檢查 .env.local 是否存在
    if [ ! -f "$SCRIPT_DIR/.env.local" ]; then
        print_warning "未找到 .env.local，跳過數據庫初始化"
        echo "  請複製 .env.example 到 .env.local 並配置後，手動執行:"
        echo "  cd backend && alembic upgrade head"
        cd "$SCRIPT_DIR"
        return
    fi

    # 載入環境變量
    export $(grep -v '^#' "$SCRIPT_DIR/.env.local" | xargs)

    # 執行遷移
    if alembic upgrade head 2>/dev/null; then
        print_success "數據庫遷移完成"
    else
        print_warning "數據庫遷移失敗 (可能數據庫未連接)"
        echo "  請確認 .env.local 中的數據庫配置正確後，手動執行:"
        echo "  cd backend && alembic upgrade head"
    fi

    cd "$SCRIPT_DIR"
}

# ===== 主流程 =====
print_header

# 預檢
run_preflight_checks

# Step 1: 更新系統
print_step 1 10 "更新系統套件列表..."
sudo apt update

# Step 2: Python 開發工具
print_step 2 10 "安裝 Python 開發工具..."
sudo apt install -y \
    python3-pip \
    python3-venv \
    python3-dev \
    build-essential \
    pkg-config

# Step 3: 系統依賴
print_step 3 10 "安裝系統層級依賴..."
sudo apt install -y \
    pandoc \
    libmagic1 \
    libmagic-dev \
    fonts-noto-cjk \
    fonts-noto-cjk-extra \
    fonts-liberation \
    libpango-1.0-0 \
    libpangocairo-1.0-0 \
    libcairo2 \
    libcairo2-dev \
    libgdk-pixbuf2.0-0 \
    libgdk-pixbuf-2.0-dev \
    libffi-dev \
    libffi8 \
    shared-mime-info \
    poppler-utils \
    libgl1 \
    libglib2.0-0 \
    libglib2.0-dev \
    libgomp1 \
    libjpeg-dev \
    libpng-dev \
    libtiff-dev \
    libopencv-dev \
    libsqlite3-dev \
    libreoffice-core-nogui \
    libreoffice-writer-nogui \
    libreoffice-impress-nogui \
    ca-certificates \
    curl \
    wget \
    libxml2 \
    libxslt1-dev \
    python3-cffi

# Step 4: Node.js
print_step 4 10 "安裝 Node.js..."
if [ ! -d "$HOME/.nvm" ]; then
    echo "安裝 nvm..."
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
fi

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

nvm install --lts
nvm use --lts
print_success "Node.js $(node -v) 已安裝"

# Step 5: Python 虛擬環境
print_step 5 10 "創建 Python 虛擬環境..."
if [ ! -d "$SCRIPT_DIR/venv" ]; then
    python3 -m venv "$SCRIPT_DIR/venv"
    print_success "虛擬環境已創建"
else
    print_success "虛擬環境已存在"
fi

# Step 6: GPU 偵測
print_step 6 10 "偵測 GPU 支援..."
detect_gpu

# Step 7: Python 依賴
print_step 7 10 "安裝 Python 依賴..."
source "$SCRIPT_DIR/venv/bin/activate"
pip install --upgrade pip setuptools wheel

echo ""
echo "安裝 PaddlePaddle..."
if [ "$USE_GPU" = true ]; then
    echo "安裝 GPU 版本: $PADDLE_PACKAGE"
    pip install "$PADDLE_PACKAGE" -i "$PADDLE_INDEX"

    # WSL CUDA 路徑配置
    if grep -qi microsoft /proc/version && [ -d "/usr/lib/wsl/lib" ]; then
        if ! grep -q "export LD_LIBRARY_PATH=/usr/lib/wsl/lib" ~/.bashrc; then
            echo "" >> ~/.bashrc
            echo "# WSL CUDA Libraries Path (Added by Tool_OCR setup)" >> ~/.bashrc
            echo "export LD_LIBRARY_PATH=/usr/lib/wsl/lib:\$LD_LIBRARY_PATH" >> ~/.bashrc
        fi
        export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH
        print_success "WSL CUDA 路徑已配置"
    fi
else
    echo "安裝 CPU 版本..."
    pip install "$PADDLE_PACKAGE" -i "$PADDLE_INDEX"
fi

echo ""
echo "安裝其他 Python 依賴..."
pip install -r "$SCRIPT_DIR/requirements.txt"

# Step 8: 驗證安裝
print_step 8 10 "驗證安裝..."
python -c "import magic; print('✓ python-magic')" || print_warning "python-magic 未正確安裝"
python -c "from weasyprint import HTML; print('✓ WeasyPrint')" || print_warning "WeasyPrint 未正確安裝"
python -c "import cv2; print('✓ OpenCV')" || print_warning "OpenCV 未正確安裝"
python -c "import paddle; print('✓ PaddlePaddle', paddle.__version__)" || print_warning "PaddlePaddle 未正確安裝"

# Step 9: 前端依賴
print_step 9 10 "安裝前端依賴..."
cd "$SCRIPT_DIR/frontend"

if [ -d "node_modules" ]; then
    echo "清理現有 node_modules..."
    rm -rf node_modules package-lock.json
fi

npm cache clean --force
npm install --force

cd "$SCRIPT_DIR"
print_success "前端依賴已安裝"

# Step 10: 創建目錄和初始化數據庫
print_step 10 10 "創建目錄和初始化數據庫..."
mkdir -p backend/uploads/{temp,processed,images}
mkdir -p backend/storage/{markdown,json,exports,results}
mkdir -p backend/models/paddleocr
mkdir -p backend/logs

init_database

# ===== 完成 =====
echo ""
echo -e "${GREEN}================================${NC}"
echo -e "${GREEN}    環境設置完成！${NC}"
echo -e "${GREEN}================================${NC}"
echo ""
echo "系統配置:"
if [ "$USE_GPU" = true ]; then
    echo -e "  GPU 加速: ${GREEN}已啟用${NC}"
    echo "  PaddlePaddle: GPU 版本"
else
    echo -e "  GPU 加速: ${YELLOW}未啟用 (CPU 模式)${NC}"
    echo "  PaddlePaddle: CPU 版本"
fi
echo ""
echo "下一步操作："
echo ""
echo "1. 配置環境變量 (如尚未配置):"
echo "   cp .env.example .env.local"
echo "   # 編輯 .env.local 填入實際配置"
echo ""
echo "2. 啟動應用:"
echo "   ./start.sh              # 同時啟動前後端"
echo "   ./start.sh backend      # 僅啟動後端"
echo "   ./start.sh frontend     # 僅啟動前端"
echo ""
echo "3. 訪問應用:"
echo "   前端: http://localhost:5173"
echo "   API文檔: http://localhost:8000/docs"
echo ""
if [ "$USE_GPU" = true ] && grep -qi microsoft /proc/version; then
    echo -e "${YELLOW}注意: WSL GPU 用戶需要重新啟動終端以應用 CUDA 路徑配置${NC}"
    echo ""
fi
