#!/bin/bash

# Companion Dashboard Raspberry Pi Zero/armv6l Kiosk Install Script
# Optimized for older Raspberry Pi models with armv6l architecture

set -e  # Exit on any error

# Global variables
REBOOT_REQUIRED=false
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Configuration
REPO_URL="https://github.com/tomhillmeyer/companion-dashboard"
CONTAINER_NAME="companion-dashboard"
IMAGE_NAME="companion-dashboard:latest"
APP_PORT=${APP_PORT:-3000}

# Function to print colored output
print_status() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

print_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# Function to check if running as root
check_root() {
    if [[ $EUID -eq 0 ]]; then
        print_error "This script should not be run as root. Please run as a regular user with sudo privileges."
        exit 1
    fi
}

# Function to detect if this is an update vs fresh install
detect_installation_type() {
    if [ -d ~/companion-dashboard-kiosk ] && [ -f ~/companion-dashboard-kiosk/app.js ]; then
        print_status "Existing installation detected - running update"
        return 0  # Update mode
    else
        print_status "No existing installation found - running fresh install"
        return 1  # Fresh install mode
    fi
}

# Function to check system compatibility
check_system() {
    print_status "Checking system compatibility..."
    
    # Check architecture
    ARCH=$(uname -m)
    print_status "Detected architecture: $ARCH"
    
    if [[ "$ARCH" == "armv6l" ]]; then
        print_warning "Detected Raspberry Pi Zero/Original Pi (armv6l)"
        print_warning "Using optimized installation for slower hardware"
    fi
    
    # Check if we have apt
    if ! command -v apt >/dev/null 2>&1; then
        print_error "This script requires apt package manager"
        exit 1
    fi
    
    # Test basic network connectivity with shorter timeout
    print_status "Testing network connectivity..."
    if ! timeout 10 ping -c 1 -W 3 8.8.8.8 >/dev/null 2>&1; then
        print_error "No internet connectivity detected. Please check your network connection."
        exit 1
    fi
    
    print_success "System check passed"
}

# Function to fix apt sources if needed
fix_apt_sources() {
    print_status "Checking and fixing apt sources..."
    
    # For older Raspberry Pi OS, sometimes the sources need updating
    if grep -q "stretch" /etc/os-release 2>/dev/null; then
        print_warning "Detected older Raspberry Pi OS, updating sources"
        sudo sed -i 's/stretch/buster/g' /etc/apt/sources.list
    fi
    
    # Clean apt cache and fix any issues
    sudo apt clean
    sudo rm -rf /var/lib/apt/lists/*
    
    print_success "APT sources checked"
}

# Function to update system packages with better error handling
update_system() {
    print_status "Updating system packages (this may take a while on Pi Zero)..."
    
    fix_apt_sources
    
    # Try apt update with multiple attempts and longer timeout
    local attempts=0
    local max_attempts=3
    
    while [ $attempts -lt $max_attempts ]; do
        print_status "Attempting apt update (attempt $((attempts + 1))/$max_attempts)..."
        
        if timeout 600 sudo apt update; then
            print_success "Package list updated successfully"
            break
        else
            attempts=$((attempts + 1))
            if [ $attempts -lt $max_attempts ]; then
                print_warning "apt update failed, waiting 30 seconds before retry..."
                sleep 30
            else
                print_error "apt update failed after $max_attempts attempts"
                print_error "Please check your internet connection and run: sudo apt update"
                exit 1
            fi
        fi
    done
    
    # Try to upgrade essential packages only
    print_status "Upgrading essential packages..."
    if ! timeout 900 sudo apt upgrade -y curl wget ca-certificates; then
        print_warning "Package upgrade failed or timed out, continuing anyway..."
    else
        print_success "Essential packages upgraded"
    fi
}

# Function to install required packages (minimal set for armv6l)
install_system_packages() {
    print_status "Installing required system packages..."
    
    # Minimal packages for GUI and Node.js
    PACKAGES=(
        "curl"
        "wget"
        "git"
        "ca-certificates"
        "gnupg"
        "xorg"
        "openbox"
        "chromium-browser"
        "x11-xserver-utils"
        "unclutter"
        "nodejs"
        "npm"
    )
    
    # Install packages one by one for better error handling
    for package in "${PACKAGES[@]}"; do
        print_status "Installing $package..."
        if ! timeout 300 sudo apt install -y "$package"; then
            print_warning "Failed to install $package, continuing..."
        fi
    done
    
    print_success "System packages installation completed"
}

# Function to install Node.js directly (skip Docker for armv6l)
install_nodejs() {
    print_status "Setting up Node.js environment..."
    
    # Check if Node.js and npm are both installed with correct versions
    if command -v node >/dev/null 2>&1 && command -v npm >/dev/null 2>&1; then
        NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1)
        if [ "$NODE_VERSION" -ge 16 ]; then
            print_success "Node.js $(node --version) and npm $(npm --version) are already installed"
            return
        fi
    fi
    
    # For armv6l, we need to install Node.js manually as Docker support is limited
    print_status "Installing Node.js with npm for armv6l architecture..."
    
    # Remove any existing incomplete installations
    sudo rm -rf /opt/nodejs 2>/dev/null || true
    sudo rm -f /usr/local/bin/node /usr/local/bin/npm /usr/local/bin/npx 2>/dev/null || true
    
    # Create nodejs directory
    sudo mkdir -p /opt/nodejs
    
    cd /tmp
    NODE_VERSION="18.19.0"  # Use a known working version
    NODEJS_URL="https://unofficial-builds.nodejs.org/download/release/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-armv6l.tar.xz"
    
    print_status "Downloading Node.js ${NODE_VERSION} with npm..."
    if wget --timeout=30 --tries=3 "$NODEJS_URL"; then
        print_status "Extracting Node.js and npm..."
        sudo tar -xf "node-v${NODE_VERSION}-linux-armv6l.tar.xz" -C /opt/nodejs --strip-components=1
        
        # Create symlinks for node, npm, and npx
        sudo ln -sf /opt/nodejs/bin/node /usr/local/bin/node
        sudo ln -sf /opt/nodejs/bin/npm /usr/local/bin/npm
        sudo ln -sf /opt/nodejs/bin/npx /usr/local/bin/npx
        
        # Also add to PATH in case symlinks don't work
        if ! grep -q "/opt/nodejs/bin" ~/.bashrc; then
            echo 'export PATH=$PATH:/opt/nodejs/bin' >> ~/.bashrc
        fi
        export PATH=$PATH:/opt/nodejs/bin
        
        # Clean up
        rm "node-v${NODE_VERSION}-linux-armv6l.tar.xz"
        
        # Verify installation
        if command -v node >/dev/null 2>&1 && command -v npm >/dev/null 2>&1; then
            print_success "Node.js $(node --version) and npm $(npm --version) installed successfully"
        else
            print_error "Node.js installation completed but commands not accessible"
            print_status "Trying to fix PATH issues..."
            
            # Force PATH update for current session
            export PATH=/opt/nodejs/bin:$PATH
            
            if command -v node >/dev/null 2>&1 && command -v npm >/dev/null 2>&1; then
                print_success "PATH fixed - Node.js $(node --version) and npm $(npm --version) now accessible"
            else
                print_error "Unable to make Node.js and npm accessible"
                exit 1
            fi
        fi
    else
        print_error "Failed to download Node.js from unofficial builds"
        print_status "Trying alternative installation methods..."
        
        # Fallback method 1: Use sdesalas script
        print_status "Trying sdesalas Node.js installation script..."
        if curl -o- https://raw.githubusercontent.com/sdesalas/node-pi-zero/master/install-node-v18.sh | bash; then
            # Add to PATH
            if ! grep -q "/opt/nodejs/bin" ~/.bashrc; then
                echo 'export PATH=$PATH:/opt/nodejs/bin' >> ~/.bashrc
            fi
            export PATH=$PATH:/opt/nodejs/bin
            
            if command -v node >/dev/null 2>&1 && command -v npm >/dev/null 2>&1; then
                print_success "Node.js installed via sdesalas script: $(node --version), npm: $(npm --version)"
                return
            fi
        fi
        
        # Fallback method 2: System packages (usually old but works)
        print_warning "All manual methods failed, trying system packages..."
        sudo apt install -y nodejs npm
        
        if command -v node >/dev/null 2>&1 && command -v npm >/dev/null 2>&1; then
            print_warning "Installed system Node.js: $(node --version), npm: $(npm --version)"
            print_warning "Note: System packages may be outdated but should work"
        else
            print_error "All Node.js installation methods failed"
            exit 1
        fi
    fi
}

# Function to setup the application without Docker
setup_application() {
    print_status "Setting up Companion Dashboard application..."
    
    # Ensure Node.js and npm are accessible
    export PATH=$PATH:/opt/nodejs/bin
    
    # Double-check npm is accessible before proceeding
    if ! command -v npm >/dev/null 2>&1; then
        print_error "npm command not found. Attempting to fix..."
        
        # Try to find npm
        NPM_PATH=$(find /opt /usr/local /usr -name "npm" 2>/dev/null | head -1)
        if [ -n "$NPM_PATH" ]; then
            NPM_DIR=$(dirname "$NPM_PATH")
            export PATH="$NPM_DIR:$PATH"
            print_status "Found npm at $NPM_PATH, added to PATH"
        else
            print_error "Cannot find npm anywhere on the system"
            exit 1
        fi
    fi
    
    # Verify npm is working
    print_status "Verifying npm: $(npm --version)"
    
    # Create application directory
    mkdir -p ~/companion-dashboard-kiosk
    cd ~/companion-dashboard-kiosk
    
    # Clone or update repository
    if [ -d ".git" ]; then
        print_status "Updating existing repository..."
        git pull origin main || git pull origin master
    else
        print_status "Cloning repository..."
        git clone $REPO_URL .
    fi
    
    # Install dependencies with better error handling
    print_status "Installing npm dependencies (this may take a while on Pi Zero)..."
    print_warning "This step can take 15-30 minutes on Raspberry Pi Zero - please be patient"
    
    # Set npm configuration for better Pi Zero compatibility
    npm config set fund false
    npm config set audit false
    
    if timeout 2400 npm install --no-optional --prefer-offline; then
        print_success "npm dependencies installed successfully"
    elif timeout 2400 npm install --no-optional; then
        print_success "npm dependencies installed successfully (second attempt)"
    else
        print_error "npm install failed after multiple attempts"
        print_status "Trying with reduced dependencies..."
        if timeout 1800 npm install --production --no-optional; then
            print_warning "Installed production dependencies only"
        else
            print_error "All npm install attempts failed"
            exit 1
        fi
    fi
    
    # Try to build the application
    print_status "Building application..."
    if npm run build; then
        print_success "Application built successfully"
    elif npm run electron:build; then
        print_success "Application built with electron:build"
    else
        print_warning "Build failed, but continuing (app may still work)"
    fi
    
    # Create a simple startup script
    cat > ~/companion-dashboard-kiosk/start-app.sh << 'EOF'
#!/bin/bash

# Ensure Node.js and npm are in PATH
export PATH=$PATH:/opt/nodejs/bin

cd ~/companion-dashboard-kiosk

# Try different ways to start the app
if [ -f "dist/main.js" ]; then
    echo "Starting from dist/main.js..."
    node dist/main.js
elif [ -f "build/main.js" ]; then
    echo "Starting from build/main.js..."
    node build/main.js
elif [ -f "main.js" ]; then
    echo "Starting from main.js..."
    node main.js
else
    echo "Starting with npm start..."
    npm start
fi
EOF
    
    chmod +x ~/companion-dashboard-kiosk/start-app.sh
    
    print_success "Application setup completed"
}

# Function to create systemd service (without Docker)
create_systemd_service() {
    print_status "Creating systemd service for auto-start..."
    
    # Create the service file
    sudo tee /etc/systemd/system/companion-dashboard-kiosk.service > /dev/null << EOF
[Unit]
Description=Companion Dashboard Kiosk
After=network.target

[Service]
Type=simple
User=$USER
WorkingDirectory=/home/$USER/companion-dashboard-kiosk
Environment=NODE_ENV=production
Environment=PORT=$APP_PORT
ExecStart=/home/$USER/companion-dashboard-kiosk/start-app.sh
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF
    
    sudo systemctl daemon-reload
    sudo systemctl enable companion-dashboard-kiosk.service
    
    print_success "Systemd service created and enabled"
}

# Function to configure X11 and kiosk mode
setup_kiosk_mode() {
    print_status "Setting up kiosk mode..."
    
    # Create .xinitrc for kiosk mode
    cat > ~/.xinitrc << EOF
#!/bin/bash

# Disable screen saver and power management
xset s off
xset -dpms
xset s noblank

# Hide cursor after inactivity
unclutter -idle 0.5 -root &

# Start window manager
openbox-session &

# Wait for the application to start
sleep 15

# Start Chromium in kiosk mode pointing to the app
chromium-browser --noerrdialogs --disable-infobars --kiosk --app=http://localhost:$APP_PORT &

# Keep X session alive
while true; do
    sleep 60
done
EOF
    
    chmod +x ~/.xinitrc
    
    # Configure auto-login
    if [ ! -f /etc/systemd/system/getty@tty1.service.d/override.conf ]; then
        sudo mkdir -p /etc/systemd/system/getty@tty1.service.d/
        sudo tee /etc/systemd/system/getty@tty1.service.d/override.conf > /dev/null << EOF
[Service]
ExecStart=
ExecStart=-/sbin/agetty --noissue --autologin $USER %I \$TERM
Type=idle
EOF
    fi
    
    # Add startx to .bash_profile for auto-start X
    if ! grep -q "startx" ~/.bash_profile 2>/dev/null; then
        echo "
# Auto-start X session on login
if [ -z \"\$DISPLAY\" ] && [ \"\$XDG_VTNR\" = 1 ]; then
    exec startx
fi" >> ~/.bash_profile
    fi
    
    print_success "Kiosk mode configured"
}

# Function to create management scripts
create_management_scripts() {
    print_status "Creating management scripts..."
    
    mkdir -p ~/companion-dashboard-kiosk/scripts
    
    # Start script
    cat > ~/companion-dashboard-kiosk/scripts/start.sh << 'EOF'
#!/bin/bash
echo "Starting Companion Dashboard..."
sudo systemctl start companion-dashboard-kiosk.service
sudo systemctl status companion-dashboard-kiosk.service
EOF
    
    # Stop script
    cat > ~/companion-dashboard-kiosk/scripts/stop.sh << 'EOF'
#!/bin/bash
echo "Stopping Companion Dashboard..."
sudo systemctl stop companion-dashboard-kiosk.service
EOF
    
    # Restart script
    cat > ~/companion-dashboard-kiosk/scripts/restart.sh << 'EOF'
#!/bin/bash
echo "Restarting Companion Dashboard..."
sudo systemctl restart companion-dashboard-kiosk.service
sudo systemctl status companion-dashboard-kiosk.service
EOF
    
    # Update script
    cat > ~/companion-dashboard-kiosk/scripts/update.sh << 'EOF'
#!/bin/bash
echo "Updating Companion Dashboard..."
cd ~/companion-dashboard-kiosk
sudo systemctl stop companion-dashboard-kiosk.service
git pull origin main || git pull origin master
npm install
npm run build || npm run electron:build || echo "Build may have failed"
sudo systemctl start companion-dashboard-kiosk.service
echo "Update complete!"
EOF
    
    # Logs script
    cat > ~/companion-dashboard-kiosk/scripts/logs.sh << 'EOF'
#!/bin/bash
echo "Showing Companion Dashboard logs (Ctrl+C to exit)..."
sudo journalctl -u companion-dashboard-kiosk.service -f
EOF
    
    # Test script
    cat > ~/companion-dashboard-kiosk/scripts/test.sh << 'EOF'
#!/bin/bash
echo "Testing Companion Dashboard..."
cd ~/companion-dashboard-kiosk
./start-app.sh
EOF
    
    chmod +x ~/companion-dashboard-kiosk/scripts/*.sh
    
    print_success "Management scripts created in ~/companion-dashboard-kiosk/scripts/"
}

# Main installation function
main() {
    print_status "Starting Companion Dashboard Raspberry Pi Zero/armv6l installation..."
    print_warning "This installation is optimized for slower hardware - it may take longer than usual"
    
    check_root
    
    # Handle the return value properly with set -e
    if detect_installation_type; then
        IS_UPDATE=0  # Update mode
        print_status "Existing installation detected - running update"
    else
        IS_UPDATE=1  # Fresh install mode
        print_status "No existing installation found - running fresh install"
    fi
    
    check_system
    
    if [ $IS_UPDATE -eq 1 ]; then
        # Fresh install - do everything
        update_system
        install_system_packages
        install_nodejs
        setup_application
        create_systemd_service
        setup_kiosk_mode
        create_management_scripts
        
        print_success "Fresh installation completed successfully!"
        echo
        print_status "Next steps:"
        echo -e "  1. Test the application: ${YELLOW}cd ~/companion-dashboard-kiosk/scripts && ./test.sh${NC}"
        echo -e "  2. If the test works, reboot your Raspberry Pi: ${YELLOW}sudo reboot${NC}"
        echo -e "  3. After reboot, the dashboard should start automatically in kiosk mode"
    else
        # Update existing install
        print_status "Updating existing installation..."
        sudo systemctl stop companion-dashboard-kiosk.service 2>/dev/null || true
        
        setup_application
        create_management_scripts  # Refresh management scripts
        
        sudo systemctl start companion-dashboard-kiosk.service
        
        print_success "Update completed successfully!"
        echo
        print_status "The service has been restarted with the latest version"
    fi
    
    echo
    echo -e "  Management scripts in ~/companion-dashboard-kiosk/scripts/:"
    echo -e "     - ${YELLOW}./start.sh${NC}   - Start the service"
    echo -e "     - ${YELLOW}./stop.sh${NC}    - Stop the service"
    echo -e "     - ${YELLOW}./restart.sh${NC} - Restart the service"
    echo -e "     - ${YELLOW}./update.sh${NC}  - Update the app"
    echo -e "     - ${YELLOW}./logs.sh${NC}    - View logs"
    echo -e "     - ${YELLOW}./test.sh${NC}    - Test the app manually"
    echo
    print_status "The dashboard will be available at: http://localhost:$APP_PORT"
    echo -e "  Configure your Companion connection in the dashboard settings"
    echo
    print_warning "Note: This installation skips Docker due to armv6l limitations"
    print_warning "The app runs directly with Node.js for better compatibility"
}

# Run main function
main "$@"