#!/bin/bash
set -euo pipefail

# ═══════════════════════════════════════════════════════════════════════════════
# Ultima v5.5.4 — ONE-CLICK INSTALLER (macOS & Linux)
# ═══════════════════════════════════════════════════════════════════════════════
#   bash <(curl -s https://ivanchepurnov.ru/ultima-win/install.sh)
#
# Does EVERYTHING automatically:
#   1. Installs/upgrades opencode-ai
#   2. Downloads Ultima 5.5.4 (автономно, без GitHub)
#   3. Migrates database (workspace IDs, types)
#   4. Installs Python deps (chromadb, pyyaml, httpx)
#   5. Creates .env + start script
#   6. Runs WAL checkpoint + auto-sets hourly protection (launchd / cron / systemd)
#   7. Verifies everything
# ═══════════════════════════════════════════════════════════════════════════════

SERVER="https://ivanchepurnov.ru/ultima-win"
ARCHIVE="ultima-5.5.4.tar.gz"

GREEN='\033[0;32m'; CYAN='\033[0;36m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'; BOLD='\033[1m'
log()  { echo -e "${GREEN}[✓]${NC} $1"; }
warn() { echo -e "${YELLOW}[!]${NC} $1"; }
error(){ echo -e "${RED}[✗]${NC} $1"; }

echo ""
echo -e "${CYAN}${BOLD}"
echo "╔══════════════════════════════════════════════════╗"
echo "║        ULTIMA v5.5 — ONE-CLICK INSTALL           ║"
echo "╚══════════════════════════════════════════════════╝"
echo -e "${NC}"

# ── OS Detection ──────────────────────────────────────────────────────────────

OS="unknown"
case "$(uname -s)" in Darwin*) OS="macos" ;; Linux*) OS="linux" ;; *)
    error "Unsupported OS: $(uname -s)"; exit 1 ;; esac
log "OS: $OS"

# ── Step 1: Dependencies ──────────────────────────────────────────────────────

echo ""
echo -e "${YELLOW}--- [1/6] Проверка зависимостей ---${NC}"

MISSING=0
for cmd in curl git node npm python3; do
    if ! command -v "$cmd" &>/dev/null; then
        warn "Установка $cmd..."
        case "$OS" in
            macos)
                if ! command -v brew &>/dev/null; then
                    error "brew не найден. Установи вручную: $cmd"
                    MISSING=$((MISSING+1))
                else
                    brew install "$cmd" 2>/dev/null || true
                fi
                ;;
            linux)
                if command -v apt-get &>/dev/null; then
                    sudo apt-get install -y -qq "$cmd" 2>/dev/null || true
                elif command -v yum &>/dev/null; then
                    sudo yum install -y -qq "$cmd" 2>/dev/null || true
                else
                    error "apt/yum не найден. Установи вручную: $cmd"
                    MISSING=$((MISSING+1))
                fi
                ;;
        esac
    fi
done
[ $MISSING -gt 0 ] && { error "Установи недостающие программы и запусти снова."; exit 1; }
log "Все зависимости установлены"

# ── Step 2: Install / upgrade opencode-ai ─────────────────────────────────────

echo ""
echo -e "${YELLOW}--- [2/6] Установка/обновление opencode-ai ---${NC}"

CURRENT_VER=$(opencode --version 2>/dev/null || echo "none")
log "Текущая версия: $CURRENT_VER"

# Always install latest — the pinned version is in the repo config
npm install -g opencode-ai@latest 2>/dev/null || npm install -g opencode-ai@latest
NEW_VER=$(opencode --version 2>/dev/null || echo "unknown")
log "OpenCode $NEW_VER установлен"

# ── Step 3: Clone / update Ultima ─────────────────────────────────────────────

echo ""
echo -e "${YELLOW}--- [3/6] Загрузка Ultima 5.5.4 ---${NC}"

ULTIMA_DIR="$HOME/Projects/Ultima"

# Если уже установлено — просто проверяем целостность
if [ -f "$ULTIMA_DIR/VERSION" ]; then
    warn "Ultima уже установлена. Пропускаем загрузку."
    log "Ultima 5.5.4 в $ULTIMA_DIR"
else
    mkdir -p "$HOME/Projects"
    log "Скачиваю Ultima 5.5.4 с сервера..."
    if curl -sL "$SERVER/$ARCHIVE" -o /tmp/ultima.tar.gz; then
        mkdir -p /tmp/ultima-extract
        tar xzf /tmp/ultima.tar.gz -C /tmp/ultima-extract
        rm -rf "$ULTIMA_DIR" 2>/dev/null || true
        mv /tmp/ultima-extract "$ULTIMA_DIR"
        rm -f /tmp/ultima.tar.gz
        log "Ultima 5.5.4 скачана и распакована"
    else
        error "Не удалось скачать Ultima с $SERVER/$ARCHIVE"
        error "Проверь интернет или попробуй позже"
        exit 1
    fi
fi

cd "$ULTIMA_DIR"
log "Ultima 5.5 в $ULTIMA_DIR"

# ── Step 4: Database migration ────────────────────────────────────────────────

echo ""
echo -e "${YELLOW}--- [4/7] Миграция базы данных OpenCode ---${NC}"

if python3 scripts/migrate_opencode.py; then
    log "База данных OpenCode: проверена"
else
    warn "Миграция БД не удалась (будет создана при первом запуске)"
fi

# ── Step 5: Python deps + config ──────────────────────────────────────────────

echo ""
echo -e "${YELLOW}--- [5/7] Установка зависимостей ---${NC}"

# Python packages
pip3 install chromadb pyyaml httpx 2>/dev/null || pip3 install --user chromadb pyyaml httpx 2>/dev/null || true
log "Python-пакеты: chromadb, pyyaml, httpx"

# .env
if [ ! -f "$ULTIMA_DIR/.env" ]; then
    cat > "$ULTIMA_DIR/.env" << ENVEOF
# Ultima v5.5 — Environment
# Укажи свой API-ключ OpenRouter: https://openrouter.ai/keys
OPENROUTER_API_KEY=""
ZEN_API_KEY=""
ENVEOF
    log ".env создан"
fi

# Ensure start script is executable
chmod +x "$ULTIMA_DIR/start-ultima.sh" 2>/dev/null || true

# Link config to global ~/.config/opencode/ (if not already linked)
OPENCODE_CFG_DIR="$HOME/.config/opencode"
mkdir -p "$OPENCODE_CFG_DIR"
if [ ! -f "$OPENCODE_CFG_DIR/opencode.json" ]; then
    ln -sf "$ULTIMA_DIR/.opencode/opencode.json" "$OPENCODE_CFG_DIR/opencode.json"
    log "Конфиг OpenCode: подключен глобально"
else
    # Check if existing link points elsewhere
    if [ "$(readlink "$OPENCODE_CFG_DIR/opencode.json" 2>/dev/null)" != "$ULTIMA_DIR/.opencode/opencode.json" ]; then
        warn "Существующий конфиг $OPENCODE_CFG_DIR/opencode.json сохранён, Ultima не подключена глобально."
        warn "  Вручную: ln -sf $ULTIMA_DIR/.opencode/opencode.json $OPENCODE_CFG_DIR/opencode.json"
    else
        log "Конфиг OpenCode: уже подключен"
    fi
fi

# ── Session protection (WAL checkpoint) ───────────────────────────────────────

echo ""
echo -e "${YELLOW}--- [6/7] Защита сессий (WAL checkpoint) ---${NC}"

if [ -f "$ULTIMA_DIR/scripts/opencode-wal-checkpoint.sh" ]; then
    bash "$ULTIMA_DIR/scripts/opencode-wal-checkpoint.sh" 2>/dev/null || true
    log "WAL checkpoint: выполнен"

    # Автоматическая настройка: WAL checkpoint каждый час
    case "$OS" in
        macos)
            PLIST_DIR="$HOME/Library/LaunchAgents"
            mkdir -p "$PLIST_DIR"
            CHECK_SCRIPT="$ULTIMA_DIR/scripts/opencode-wal-checkpoint.sh"
            cat > "$PLIST_DIR/com.opencode.wal-checkpoint.plist" << PLISTEOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.opencode.wal-checkpoint</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>$CHECK_SCRIPT</string>
    </array>
    <key>StartInterval</key>
    <integer>3600</integer>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardOutPath</key>
    <string>/tmp/opencode-wal-checkpoint.log</string>
    <key>StandardErrorPath</key>
    <string>/tmp/opencode-wal-checkpoint.log</string>
</dict>
</plist>
PLISTEOF
            launchctl load "$PLIST_DIR/com.opencode.wal-checkpoint.plist" 2>/dev/null || true
            log "Защита сессий: launchd (каждый час)"
            ;;
        linux)
            if [ -d /etc/cron.hourly ] && [ "$(id -u)" -eq 0 ]; then
                cat > /etc/cron.hourly/opencode-wal-checkpoint << CRONEOF
#!/bin/bash
exec $ULTIMA_DIR/scripts/opencode-wal-checkpoint.sh
CRONEOF
                chmod +x /etc/cron.hourly/opencode-wal-checkpoint
                log "Защита сессий: cron.hourly (каждый час)"
            else
                # systemd --user timer (без sudo)
                mkdir -p "$HOME/.config/systemd/user"
                UNIT_DIR="$HOME/.config/systemd/user"
                cat > "$UNIT_DIR/opencode-wal-checkpoint.service" << UNITEOF
[Unit]
Description=OpenCode WAL checkpoint
[Service]
Type=oneshot
ExecStart=$ULTIMA_DIR/scripts/opencode-wal-checkpoint.sh
UNITEOF
                cat > "$UNIT_DIR/opencode-wal-checkpoint.timer" << TIMEREOF
[Unit]
Description=OpenCode WAL checkpoint (hourly)
[Timer]
OnCalendar=hourly
Persistent=true
[Install]
WantedBy=timers.target
TIMEREOF
                systemctl --user daemon-reload 2>/dev/null || true
                systemctl --user enable opencode-wal-checkpoint.timer 2>/dev/null || true
                systemctl --user start opencode-wal-checkpoint.timer 2>/dev/null || true
                log "Защита сессий: systemd --user timer (каждый час)"
            fi
            ;;
    esac
else
    warn "opencode-wal-checkpoint.sh не найден"
fi

# ── Step 7: Verify ────────────────────────────────────────────────────────────

echo ""
echo -e "${YELLOW}--- [6/6] Проверка ---${NC}"

ERRORS=0

# Check opencode binary
opencode --version 2>/dev/null && log "opencode: OK" || { error "opencode: НЕ НАЙДЕН"; ERRORS=$((ERRORS+1)); }

# Check Ultima files
for f in ".opencode/opencode.json" "scripts/migrate_opencode.py" "scripts/load_context.py" "scripts/web_search.py" "VERSION" "start-ultima.sh"; do
    [ -f "$ULTIMA_DIR/$f" ] && log "Файл $f: OK" || { error "Файл $f: ОТСУТСТВУЕТ"; ERRORS=$((ERRORS+1)); }
done

# Check Python syntax of critical scripts
for s in "migrate_opencode.py" "load_context.py" "compile_session.py" "web_search.py"; do
    python3 -m py_compile "$ULTIMA_DIR/scripts/$s" 2>/dev/null && log "Скрипт $s: OK" || { warn "Скрипт $s: ОШИБКА СИНТАКСИСА"; ERRORS=$((ERRORS+1)); }
done

echo ""
if [ $ERRORS -eq 0 ]; then
    echo -e "${GREEN}${BOLD}╔══════════════════════════════════════════════╗${NC}"
    echo -e "${GREEN}${BOLD}║     ULTIMA 5.5 ГОТОВА К ЗАПУСКУ!          ║${NC}"
    echo -e "${GREEN}${BOLD}╚══════════════════════════════════════════════╝${NC}"
    echo ""
    echo -e "  ${CYAN}Запуск:${NC}"
    echo -e "    cd $ULTIMA_DIR && opencode"
    echo -e "    # или: $ULTIMA_DIR/start-ultima.sh"
    echo ""
    echo -e "  ${CYAN}Первый запуск:${NC}"
    echo -e "    1. Открой $ULTIMA_DIR/.env"
    echo -e "    2. Вставь API-ключ: ${BOLD}OPENROUTER_API_KEY=sk-or-v1-...${NC}"
    echo -e "    3. Запусти opencode"
    echo ""
    exit 0
else
    echo -e "${RED}${BOLD}$ERRORS ошибок.${NC}"
    echo -e "Исправь их вручную или перезапусти установщик."
    exit 1
fi
