#!/usr/bin/env bash

# MeTube installation script with offline Deno installation
# Place this script and deno-x86_64-unknown-linux-gnu.zip in the same directory

set -e

APP="MeTube"
APP_DIR="/opt/metube"
DENO_INSTALL_DIR="/usr/local"
DENO_ZIP="deno-x86_64-unknown-linux-gnu.zip"
GITHUB_REPO="alexta69/metube"
SERVICE_USER="root"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

info() { echo -e "${GREEN}[INFO]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
step() { echo -e "${BLUE}[STEP]${NC} $1"; }

# Check if running as root
if [[ $EUID -ne 0 ]]; then
   error "This script must be run as root"
fi

# Check for local Deno archive
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DENO_ARCHIVE_PATH="${SCRIPT_DIR}/${DENO_ZIP}"

if [[ ! -f "$DENO_ARCHIVE_PATH" ]]; then
    error "Deno archive not found at $DENO_ARCHIVE_PATH"
fi

info "Found Deno archive: $DENO_ARCHIVE_PATH"

# Install dependencies
step "Installing system dependencies"
apt-get update
apt-get install -y curl wget unzip git build-essential python3 python3-pip python3-venv

# Install FFmpeg
step "Installing FFmpeg"
apt-get install -y ffmpeg
if command -v ffmpeg >/dev/null 2>&1; then
    info "FFmpeg installed successfully: $(ffmpeg -version | head -n1)"
else
    error "FFmpeg installation failed"
fi

step "Installing NODEJS"
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
apt install -y nodejs
npm install -g pm2

# Install Deno from local archive
step "Installing Deno from local archive"
if [[ -d "${DENO_INSTALL_DIR}/deno" ]]; then
    rm -rf "${DENO_INSTALL_DIR}/deno"
fi

unzip -o "$DENO_ARCHIVE_PATH" -d /tmp/deno_extract
chmod +x /tmp/deno_extract/deno
mv /tmp/deno_extract/deno "${DENO_INSTALL_DIR}/bin/deno"
rm -rf /tmp/deno_extract

if command -v deno >/dev/null 2>&1; then
    info "Deno installed successfully: $(deno --version)"
else
    error "Deno installation failed"
fi

# Install pnpm
step "Installing pnpm"
curl -fsSL https://get.pnpm.io/install.sh | sh -

# Download and setup MeTube
step "Downloading MeTube from GitHub"
LATEST_URL=$(curl -s "https://api.github.com/repos/${GITHUB_REPO}/releases/latest" | grep "tarball_url" | cut -d '"' -f 4)

if [[ -z "$LATEST_URL" ]]; then
    error "Failed to get latest release URL"
fi

if [[ -d "$APP_DIR" ]]; then
    warn "Existing installation found, backing up..."
    mv "$APP_DIR" "${APP_DIR}_bak_$(date +%Y%m%d_%H%M%S)"
fi

mkdir -p "$APP_DIR"
cd "$APP_DIR"

curl -L "$LATEST_URL" -o metube.tar.gz
tar -xzf metube.tar.gz --strip-components=1
rm metube.tar.gz

# Build frontend
step "Building frontend"
if [[ -d "$APP_DIR/ui" ]]; then
    cd "$APP_DIR/ui"
    /root/.local/share/pnpm/pnpm install --frozen-lockfile
    /root/.local/share/pnpm/pnpm run build
else
    error "UI directory not found"
fi

# Setup Python backend
step "Setting up Python backend"
cd "$APP_DIR"
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip

# Install required Python packages
step "Installing Python packages"
pip install yt-dlp aiohttp python-dotenv python-socketio watchfiles

# Check for requirements.txt and install if exists
if [[ -f "$APP_DIR/requirements.txt" ]]; then
    pip install -r requirements.txt
fi

# Configure yt-dlp to use Deno for JS challenges
step "Configuring yt-dlp for JavaScript challenges"
mkdir -p /root/.config/yt-dlp

# Create yt-dlp config to enable remote components
cat > /root/.config/yt-dlp/config <<EOF
# Enable Deno for JS challenge solving
--remote-components ejs:github
EOF

info "yt-dlp configured to use Deno for JavaScript challenges"

# Create .env file with yt-dlp options in JSON format
step "Creating configuration"
if [[ ! -f "$APP_DIR/.env" ]]; then
    cat > "$APP_DIR/.env" <<'EOF'
# MeTube Configuration
DOWNLOAD_DIR=/downloads
STATE_DIR=/opt/metube/state
URL_PREFIX=
HTTP_USERNAME=
HTTP_PASSWORD=
YTDL_OPTIONS={"extractor_args":{"youtube":{"skip":[["hls","dash","live"]],"player_client":["android","web"]}},"remote_components":"ejs:github"}
EOF
else
    # Check if YTDL_OPTIONS already exists in .env
    if ! grep -q "YTDL_OPTIONS" "$APP_DIR/.env"; then
        echo "" >> "$APP_DIR/.env"
        echo "# yt-dlp options for JS challenge solving" >> "$APP_DIR/.env"
        echo 'YTDL_OPTIONS={"extractor_args":{"youtube":{"skip":[["hls","dash","live"]],"player_client":["android","web"]}},"remote_components":"ejs:github"}' >> "$APP_DIR/.env"
    fi
fi

# Create download and state directories
mkdir -p /downloads
mkdir -p "$APP_DIR/state"
chown -R root:root /downloads
chown -R root:root "$APP_DIR"

# Fix potential missing app/main.py structure
step "Checking MeTube application structure"
if [[ ! -f "$APP_DIR/app/main.py" ]]; then
    warn "app/main.py not found, checking alternative locations..."
    if [[ -f "$APP_DIR/main.py" ]]; then
        warn "Found main.py in root, creating app directory structure"
        mkdir -p "$APP_DIR/app"
        mv "$APP_DIR/main.py" "$APP_DIR/app/"
    else
        error "Cannot find main.py. MeTube structure may be different than expected"
    fi
fi

# Create systemd service
step "Creating systemd service"
cat > /etc/systemd/system/metube.service <<EOF
[Unit]
Description=MeTube - YouTube Downloader
After=network.target

[Service]
Type=simple
WorkingDirectory=${APP_DIR}
EnvironmentFile=${APP_DIR}/.env
Environment="PATH=/usr/local/bin:/usr/bin:/bin:${APP_DIR}/.venv/bin"
ExecStartPre=/bin/bash -c 'echo "Starting MeTube with YTDL_OPTIONS=\${YTDL_OPTIONS}"'
ExecStart=${APP_DIR}/.venv/bin/python3 ${APP_DIR}/app/main.py
Restart=always
User=root
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

# Test the Python application manually before starting service
step "Testing Python application manually"
cd "$APP_DIR"
source .venv/bin/activate
timeout 5 python3 -c "
import os
import json
os.environ['DOWNLOAD_DIR'] = '/downloads'
os.environ['STATE_DIR'] = '/opt/metube/state'
ytdl_options_str = '{\"extractor_args\":{\"youtube\":{\"skip\":[[\"hls\",\"dash\",\"live\"]],\"player_client\":[\"android\",\"web\"]}},\"remote_components\":\"ejs:github\"}'
try:
    ytdl_options = json.loads(ytdl_options_str)
    print(f'YTDL_OPTIONS parsed successfully: {ytdl_options}')
except Exception as e:
    print(f'Error parsing YTDL_OPTIONS: {e}')
    exit(1)
" || warn "Manual test failed, but continuing..."

# Reload systemd and start service
step "Starting MeTube service"
systemctl daemon-reload
systemctl enable metube
systemctl start metube

# Check if service is running
sleep 5
if systemctl is-active --quiet metube; then
    info "MeTube service started successfully"
else
    warn "MeTube service failed to start. Checking logs..."
    journalctl -u metube --no-pager -n 30
    echo ""
    echo "Trying to run MeTube directly to see error:"
    cd "$APP_DIR"
    source .venv/bin/activate
    timeout 10 python3 app/main.py || true
    error "MeTube service failed to start. Check logs with: journalctl -u metube"
fi

# Get IP address
IP_ADDRESS=$(hostname -I | awk '{print $1}')

echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}MeTube installation completed!${NC}"
echo -e "${GREEN}========================================${NC}"
echo -e "Access MeTube at: ${YELLOW}http://${IP_ADDRESS}:8081${NC}"
echo ""
echo -e "Commands:"
echo -e "  Start:   ${BLUE}systemctl start metube${NC}"
echo -e "  Stop:    ${BLUE}systemctl stop metube${NC}"
echo -e "  Status:  ${BLUE}systemctl status metube${NC}"
echo -e "  Logs:    ${BLUE}journalctl -u metube -f${NC}"
echo ""
echo -e "Download directory: ${YELLOW}/downloads${NC}"
echo -e "Config file: ${YELLOW}${APP_DIR}/.env${NC}"
echo -e "yt-dlp config: ${YELLOW}/root/.config/yt-dlp/config${NC}"
echo ""
echo -e "${GREEN}Note:${NC} yt-dlp has been configured to use Deno for JavaScript challenge solving"
echo -e "This helps bypass YouTube's anti-bot protection for downloading videos"