#!/usr/bin/env bash
# ---
# name: pdf-env-setup (macOS / Linux)
# description: Environment detection, dependency check & install for PDF skill on macOS and Linux.
# ---
set -euo pipefail

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
ok()   { echo -e "  ${GREEN}✓${NC} $1"; }
fail() { echo -e "  ${RED}✗${NC} $1"; }
warn() { echo -e "  ${YELLOW}○${NC} $1"; }
info() { echo -e "  ${BLUE}→${NC} $1"; }

# ── Resolve PDF_SKILL_DIR ──
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PDF_SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
export PDF_SKILL_DIR

echo "============================================"
echo "  PDF Skill — Environment Setup"
echo "  (macOS / Linux)"
echo "============================================"
echo ""

# ── Step 1: Platform Detection ──
OS="$(uname -s)"
ARCH="$(uname -m)"
echo "Platform: $OS $ARCH"

if [ "$OS" = "Darwin" ]; then
    PLATFORM="mac"
elif [ "$OS" = "Linux" ]; then
    PLATFORM="linux"
else
    echo "Unsupported platform: $OS. For Windows use env_setup/setup_windows.ps1"
    exit 1
fi

echo "Detected: $PLATFORM"
echo "PDF_SKILL_DIR=$PDF_SKILL_DIR"
echo ""

# ── China mirror detection & config ──
USE_CN_MIRROR=false
PIP_MIRROR_ARGS=""
NPM_MIRROR_ARGS=""
PLAYWRIGHT_HOST=""

if [ "${USE_CN_MIRROR_FORCE:-}" = "true" ]; then
    USE_CN_MIRROR=true
elif curl -s --connect-timeout 3 https://pypi.org > /dev/null 2>&1; then
    USE_CN_MIRROR=false
else
    warn "pypi.org unreachable — enabling China mirrors"
    USE_CN_MIRROR=true
fi

if [ "$USE_CN_MIRROR" = true ]; then
    PIP_MIRROR_ARGS="-i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn"
    NPM_MIRROR_ARGS="--registry https://registry.npmmirror.com"
    PLAYWRIGHT_HOST="https://npmmirror.com/mirrors/playwright/"
    info "China mirrors enabled (pip: tuna, npm: npmmirror, playwright: npmmirror)"
    echo ""
fi

ERRORS=0

# ── Step 2a: Homebrew (macOS only) ──
if [ "$PLATFORM" = "mac" ]; then
    echo "--- [1/10] Homebrew (macOS package manager) ---"
    if command -v brew &>/dev/null; then
        ok "brew installed"
    else
        fail "brew not found"
        info "Install: /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
        ERRORS=$((ERRORS + 1))
    fi
    echo ""
fi

# ── Step 2b: Python 3 ──
echo "--- [2/10] Python 3 ---"
if command -v python3 &>/dev/null; then
    PY_VER=$(python3 --version 2>&1)
    ok "python3 ($PY_VER)"
    if [ "$PLATFORM" = "mac" ]; then
        PY_PATH=$(which python3 2>/dev/null)
        if [[ "$PY_PATH" == "/usr/bin/python3" ]]; then
            warn "Using macOS system Python (limited). Recommend: brew install python3"
        fi
    fi
else
    fail "python3 not found"
    case "$PLATFORM" in
        mac)   info "Install: brew install python3" ;;
        linux) info "Install: sudo apt install python3 python3-pip   (Debian/Ubuntu)"
               info "         sudo dnf install python3 python3-pip   (Fedora/RHEL)" ;;
    esac
    ERRORS=$((ERRORS + 1))
fi
echo ""

# ── Step 2c: pip ──
echo "--- [3/10] pip ---"
if python3 -m pip --version &>/dev/null 2>&1; then
    ok "pip installed"
else
    fail "pip not found"
    case "$PLATFORM" in
        mac)   info "Install: python3 -m ensurepip --upgrade" ;;
        linux) info "Install: sudo apt install python3-pip" ;;
    esac
    ERRORS=$((ERRORS + 1))
fi
echo ""

# ── Step 2d: Python packages ──
echo "--- [4/10] Python Packages (pikepdf, pdfplumber, pypdf, reportlab, PyMuPDF) ---"
PY_PKGS=(
    "pikepdf:pikepdf"
    "pdfplumber:pdfplumber"
    "pypdf:pypdf"
    "reportlab:reportlab"
    "pymupdf:PyMuPDF"
)

MISSING_PY=()
for entry in "${PY_PKGS[@]}"; do
    mod="${entry%%:*}"
    pkg="${entry##*:}"
    # PyMuPDF imports as 'fitz'
    if [ "$mod" = "pymupdf" ]; then mod="fitz"; fi
    if python3 -c "import $mod" 2>/dev/null; then
        ver=$(python3 -c "import $mod; print(getattr($mod, '__version__', getattr($mod, 'version', 'ok')))" 2>/dev/null)
        ok "$pkg ($ver)"
    else
        fail "$pkg not installed"
        MISSING_PY+=("$pkg")
    fi
done

if [ ${#MISSING_PY[@]} -gt 0 ]; then
    info "Installing missing Python packages: ${MISSING_PY[*]}"
    # shellcheck disable=SC2086
    python3 -m pip install -q $PIP_MIRROR_ARGS "${MISSING_PY[@]}" 2>/dev/null \
        || python3 -m pip install -q --user $PIP_MIRROR_ARGS "${MISSING_PY[@]}" 2>/dev/null \
        || python3 -m pip install -q --break-system-packages $PIP_MIRROR_ARGS "${MISSING_PY[@]}" 2>/dev/null \
        || { fail "pip install failed. Try: pip install $PIP_MIRROR_ARGS ${MISSING_PY[*]}"; ERRORS=$((ERRORS + 1)); }
    ok "Installed: ${MISSING_PY[*]}"
fi
echo ""

# ── Step 2e: Node.js + npm ──
echo "--- [5/10] Node.js + npm ---"
if command -v node &>/dev/null; then
    ok "node ($(node --version))"
else
    fail "node not found"
    case "$PLATFORM" in
        mac)   info "Install: brew install node" ;;
        linux) info "Install: curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -"
               info "         sudo apt install -y nodejs"
               if [ "$USE_CN_MIRROR" = true ]; then
                   info "China alt: https://npmmirror.com/mirrors/node/"
               fi ;;
    esac
    ERRORS=$((ERRORS + 1))
fi

if command -v npm &>/dev/null; then
    ok "npm ($(npm --version))"
else
    fail "npm not found"
    ERRORS=$((ERRORS + 1))
fi
echo ""

# ── Step 2f: Playwright + Chromium ──
echo "--- [6/10] Playwright + Chromium ---"
if node -e "require('playwright')" 2>/dev/null; then
    PW_VER=$(node -e "console.log(require('playwright/package.json').version)" 2>/dev/null)
    ok "playwright ($PW_VER)"
else
    fail "playwright not installed"
    if [ "$USE_CN_MIRROR" = true ]; then
        info "Install: npm install -g playwright@1.50.0 $NPM_MIRROR_ARGS"
    else
        info "Install: npm install -g playwright@1.50.0"
    fi
    ERRORS=$((ERRORS + 1))
fi

if [ "$PLATFORM" = "mac" ]; then
    PW_CACHE="$HOME/Library/Caches/ms-playwright"
else
    PW_CACHE="$HOME/.cache/ms-playwright"
fi

if ls "$PW_CACHE"/chromium-* &>/dev/null 2>&1; then
    ok "chromium installed"
else
    fail "chromium not installed"
    if [ "$USE_CN_MIRROR" = true ]; then
        info "Install: PLAYWRIGHT_DOWNLOAD_HOST=$PLAYWRIGHT_HOST npx playwright install chromium"
    else
        info "Install: npx playwright install chromium"
    fi
    if [ "$PLATFORM" = "linux" ]; then
        info "         npx playwright install-deps   (system libs, needs sudo)"
    fi
    ERRORS=$((ERRORS + 1))
fi
echo ""

# ── Step 2g: Tectonic (optional, LaTeX engine) ──
echo "--- [7/10] Tectonic (optional, LaTeX/Academic PDFs) ---"
BUNDLED="$PDF_SKILL_DIR/scripts/tectonic"
if [ -x "$BUNDLED" ] && [ "$OS" = "Darwin" ] && [ "$ARCH" = "arm64" ]; then
    ok "tectonic (bundled, macOS arm64)"
elif command -v tectonic &>/dev/null; then
    TEC_VER=$(tectonic --version 2>&1 | head -1)
    ok "tectonic ($TEC_VER)"
elif [ -x "$HOME/tectonic" ]; then
    ok "tectonic (~/tectonic)"
else
    warn "tectonic not installed (needed only for LaTeX/academic PDFs)"
    case "$PLATFORM" in
        mac)   info "Install: brew install tectonic" ;;
        linux) info "Install: conda install -c conda-forge tectonic"
               info "     or: conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/ && conda install tectonic" ;;
    esac
fi
echo ""

# ── Step 2h: LibreOffice (optional) ──
echo "--- [8/10] LibreOffice (optional, Office→PDF) ---"
if command -v soffice &>/dev/null; then
    LO_VER=$(soffice --version 2>/dev/null | head -1)
    ok "libreoffice ($LO_VER)"
else
    warn "libreoffice not installed (needed only for .docx/.xlsx→PDF conversion)"
    case "$PLATFORM" in
        mac)   info "Install: brew install --cask libreoffice" ;;
        linux) info "Install: sudo apt install libreoffice-core" ;;
    esac
fi
echo ""

# ── Step 2i: Font Installation (from CDN) ──
echo "--- [9/10] Font Installation ---"
FONT_CDN_BASE="https://z-cdn.chatglm.cn/office-skill/fonts"
FONT_LIST="$SCRIPT_DIR/font_list.txt"

if [ "$PLATFORM" = "mac" ]; then
    USER_FONT_DIR="$HOME/Library/Fonts"
else
    USER_FONT_DIR="$HOME/.local/share/fonts"
fi
mkdir -p "$USER_FONT_DIR"

MARKER="$USER_FONT_DIR/.office-skill-fonts-installed"
if [ -f "$MARKER" ]; then
    ok "Fonts already installed (marker found). To re-install, delete $MARKER"
else
    if [ ! -f "$FONT_LIST" ]; then
        fail "Font list not found: $FONT_LIST"
        ERRORS=$((ERRORS + 1))
    else
        TOTAL=$(wc -l < "$FONT_LIST" | tr -d ' ')
        INSTALLED=0
        SKIPPED=0
        FAILED=0
        info "Downloading $TOTAL fonts from CDN..."
        
        while IFS= read -r rel_path || [ -n "$rel_path" ]; do
            [ -z "$rel_path" ] && continue
            fname="$(basename "$rel_path")"
            
            if [ -f "$USER_FONT_DIR/$fname" ]; then
                SKIPPED=$((SKIPPED + 1))
                continue
            fi
            
            # URL-encode special chars (brackets)
            encoded=$(echo "$rel_path" | sed 's/\[/%5B/g; s/\]/%5D/g; s/ /%20/g')
            url="$FONT_CDN_BASE/$encoded"
            
            if curl -fSL --connect-timeout 15 --retry 2 -o "$USER_FONT_DIR/$fname" "$url" 2>/dev/null; then
                INSTALLED=$((INSTALLED + 1))
            else
                warn "Failed to download: $rel_path"
                FAILED=$((FAILED + 1))
                rm -f "$USER_FONT_DIR/$fname" 2>/dev/null
            fi
        done < "$FONT_LIST"
        
        if [ "$PLATFORM" = "linux" ] && [ $INSTALLED -gt 0 ]; then
            fc-cache -f "$USER_FONT_DIR" 2>/dev/null
        fi
        
        if [ $FAILED -eq 0 ]; then
            touch "$MARKER"
            ok "Fonts: $INSTALLED newly installed, $SKIPPED already present (target: $USER_FONT_DIR)"
        else
            warn "Fonts: $INSTALLED installed, $SKIPPED skipped, $FAILED failed (marker not written, will retry next run)"
            ERRORS=$((ERRORS + 1))
        fi
    fi
fi

# Set FONT_DIR to user font directory (fonts are now installed there)
FONT_DIR="$USER_FONT_DIR"
export FONT_DIR
echo ""

# ── Step 2j: CJK Font Verification ──
echo "--- [10/10] CJK Font Verification ---"
CJK_FOUND=false

if [ "$PLATFORM" = "mac" ]; then
    if [ -f "$HOME/Library/Fonts/NotoSansSC[wght].ttf" ] || fc-list :lang=zh 2>/dev/null | head -1 | grep -q .; then
        ok "CJK fonts available (Noto Sans SC or system)"
        CJK_FOUND=true
    fi
    if [ -f "$HOME/Library/Fonts/NotoSansSC[wght].ttf" ]; then
        ok "Noto Sans SC (user fonts)"
        CJK_FOUND=true
    fi
elif [ "$PLATFORM" = "linux" ]; then
    if fc-list :lang=zh 2>/dev/null | head -1 | grep -q .; then
        ok "CJK fonts available (fc-list)"
        CJK_FOUND=true
    fi
fi

if [ "$CJK_FOUND" = false ]; then
    warn "No CJK font detected — fonts were downloaded and copied; rebuild font cache if needed"
fi
echo ""

# ── Summary ──
echo "============================================"
if [ $ERRORS -eq 0 ]; then
    echo "  All dependencies OK."
else
    echo "  $ERRORS issue(s) found. Fix them above."
fi
echo "  PDF_SKILL_DIR=$PDF_SKILL_DIR"
echo "  FONT_DIR=$FONT_DIR (user font directory)"
echo "============================================"
