#!/bin/bash
#
# Bitcoin Core + Ord Bootstrap Script
# This script automates the complete setup of a Bitcoin node with Ordinals (ord) support
# It includes runes, transaction, and address indexing functionality.
#
# Usage: sudo bash bootstrap.sh
#

# Exit on error, unset variable, or pipe failure
set -euo pipefail

# Create a state file directory to track progress
STATE_DIR="/var/lib/bitstrap"
STATE_FILE="${STATE_DIR}/state"
CONFIG_FILE="${STATE_DIR}/config"

# Create a trap for cleanup and error handling
cleanup() {
    local exit_code=$?
    if [ $exit_code -ne 0 ]; then
        echo "Script interrupted or error occurred with exit code: $exit_code"
        echo "You can resume the script by running it again."
    fi
    exit $exit_code
}

# Trap to catch errors and interrupts
trap cleanup ERR INT TERM

# Display welcome message
echo "
╔═══════════════════════════════════════════════════════════════════╗
║                                                                   ║
║   Bitcoin Core + Ord Automatic Setup Script                       ║
║                                                                   ║
║   This script will:                                               ║
║   - Update your system                                            ║
║   - Install Bitcoin Core                                          ║
║   - Configure a full Bitcoin node                                 ║
║   - Install and configure ord with advanced indexing              ║
║   - Set up systemd services with auto-restart                     ║
║                                                                   ║
║   Recommended Hardware:                                           ║
║   - Ubuntu 22.04 or 24.04                                         ║
║   - At least 800GB disk space                                     ║
║   - 8GB+ RAM (16GB recommended)                                   ║
║   - 2+ CPU cores (4+ recommended)                                 ║
║                                                                   ║
╚═══════════════════════════════════════════════════════════════════╝
"

# Check if running as root
if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root."
   echo "Please run: sudo bash bootstrap.sh"
   exit 1
fi

# Configuration variables
BITCOIN_VERSION="26.0"
ORD_HTTP_PORT="8080"
INDEX_CACHE_SIZE="8000000000"  # 8GB cache by default
BITCOIN_DATA_DIR=""
ORD_DATA_DIR=""

# Initialize state tracking
initialize_state() {
    mkdir -p "${STATE_DIR}"
    
    if [[ ! -f "${STATE_FILE}" ]]; then
        echo "dependencies=0" > "${STATE_FILE}"
        echo "storage=0" >> "${STATE_FILE}"
        echo "bitcoin=0" >> "${STATE_FILE}"
        echo "ord=0" >> "${STATE_FILE}"
        echo "monitoring=0" >> "${STATE_FILE}"
        echo "status_page=0" >> "${STATE_FILE}"
        echo "sync_monitor=0" >> "${STATE_FILE}"  # Added for sync monitor
        echo "user_guide=0" >> "${STATE_FILE}"
        echo "finish=0" >> "${STATE_FILE}"
    fi
    
    # Load config if it exists
    if [[ -f "${CONFIG_FILE}" ]]; then
        source "${CONFIG_FILE}"
        echo "Loaded configuration from previous run."
        echo "Bitcoin data directory: ${BITCOIN_DATA_DIR}"
        echo "Ord data directory: ${ORD_DATA_DIR}"
    fi
}

# Function to update state
update_state() {
    sed -i "s/${1}=0/${1}=1/" "${STATE_FILE}"
    echo "Completed step: $1"
}

# Function to check state
check_state() {
    grep -q "${1}=1" "${STATE_FILE}"
    return $?
}

# Save configuration
save_config() {
    echo "BITCOIN_DATA_DIR=\"${BITCOIN_DATA_DIR}\"" > "${CONFIG_FILE}"
    echo "ORD_DATA_DIR=\"${ORD_DATA_DIR}\"" >> "${CONFIG_FILE}"
    echo "ORD_HTTP_PORT=\"${ORD_HTTP_PORT}\"" >> "${CONFIG_FILE}"
    echo "INDEX_CACHE_SIZE=\"${INDEX_CACHE_SIZE}\"" >> "${CONFIG_FILE}"
}

# Install dependencies first
install_dependencies() {
    echo "Updating system and installing dependencies..."
    apt update && apt upgrade -y
    apt install -y build-essential git curl wget gnupg unzip jq pkg-config \
        libssl-dev libclang-dev clang cmake libleveldb-dev libsqlite3-dev \
        python3-pip python3-venv libgmp-dev htop tmux bc
    
    echo "Dependencies installed successfully."
}

# Display storage options before asking for input
choose_storage() {
    echo "===== Storage Setup ====="
    echo "We need to choose where to store Bitcoin and ord data (~ 800GB+ recommended)"
    echo ""
    
    # Show device list
    echo "Available storage devices:"
    lsblk -o NAME,SIZE,MOUNTPOINT
    echo ""
    
    # Show filesystems with space
    echo "Mounted filesystems with available space:"
    df -h | grep -v tmpfs | grep -v udev | grep -v loop
    echo ""
    
    # Print table header
    echo "Storage options table:"
    echo "-------------------------------------------------------------------------"
    echo "OPTION | PATH | AVAILABLE SPACE | RECOMMENDATION"
    echo "-------------------------------------------------------------------------"
    
    # Create arrays to store options
    declare -a paths
    declare -a sizes
    declare -a recommendations
    
    # Start with root filesystem
    paths[1]="/"
    root_size=$(df -h / | tail -n 1 | awk '{print $4}')
    sizes[1]=$root_size
    recommendations[1]="Default system location"
    echo "1 | / (root) | $root_size | Default system location"
    
    # Get size in GB for comparison
    if [[ $root_size == *T* ]]; then
        root_gb=$(echo "$root_size" | sed 's/T//' | bc -l)
        root_gb=$(echo "$root_gb * 1024" | bc -l)
    elif [[ $root_size == *G* ]]; then
        root_gb=$(echo "$root_size" | sed 's/G//' | bc -l)
    else
        root_gb=0
    fi
    
    # Initialize variables for best option
    best_option=1
    best_size=$root_gb
    
    # Get list of non-root mounted volumes
    count=2
    
    # Process each filesystem directly from df output
    while read -r line; do
        # Skip header and root
        if [[ $line == Filesystem* ]] || [[ $line == *" / "* ]]; then
            continue
        fi
        
        # Parse the line
        mount=$(echo "$line" | awk '{print $6}')
        size=$(echo "$line" | awk '{print $4}')
        
        # Skip small or boot filesystems
        if [[ $mount == "/boot"* ]] || [[ $size == *K* ]] || [[ $size == *M* ]]; then
            continue
        fi
        
        # Convert size to GB for comparison
        if [[ $size == *T* ]]; then
            size_gb=$(echo "$size" | sed 's/T//' | bc -l)
            size_gb=$(echo "$size_gb * 1024" | bc -l)
        elif [[ $size == *G* ]]; then
            size_gb=$(echo "$size" | sed 's/G//' | bc -l)
        else
            continue
        fi
        
        # Determine recommendation
        recommendation=""
        if (( $(echo "$size_gb > 800" | bc -l) )); then
            recommendation="RECOMMENDED (over 800GB)"
            
            # Update best option if this is larger
            if (( $(echo "$size_gb > $best_size" | bc -l) )); then
                best_size=$size_gb
                best_option=$count
            fi
        elif (( $(echo "$size_gb > 500" | bc -l) )); then
            recommendation="GOOD OPTION (sufficient space)"
        else
            recommendation="Limited space (not recommended)"
        fi
        
        # Store and display this option
        paths[$count]=$mount
        sizes[$count]=$size
        recommendations[$count]=$recommendation
        
        echo "$count | $mount | $size | $recommendation"
        count=$((count + 1))
    done < <(df -h | grep -v tmpfs | grep -v udev | grep -v loop)
    
    # Complete the table
    echo "-------------------------------------------------------------------------"
    
    # Show recommendation
    echo ""
    echo "RECOMMENDATION: Option $best_option offers the most available space."
    echo ""
    
    # Force output to display
    sleep 1
    
    # Now ask for input
    read -p "Select storage option (1-$((count-1))) [recommended: $best_option]: " choice
    
    # Default to best option if empty
    if [ -z "$choice" ]; then
        choice=$best_option
    fi
    
    # Validate choice
    if ! [[ "$choice" =~ ^[0-9]+$ ]] || [ "$choice" -lt 1 ] || [ "$choice" -ge "$count" ]; then
        echo "Invalid choice. Using option 1 (root filesystem)."
        choice=1
    fi
    
    # Set directories
    selected_path=${paths[$choice]}
    
    # Create data directories
    BITCOIN_DATA_DIR="${selected_path}/bitcoin"
    ORD_DATA_DIR="${selected_path}/ord"
    
    mkdir -p "${BITCOIN_DATA_DIR}"
    mkdir -p "${ORD_DATA_DIR}"
    
    echo "Using $selected_path for Bitcoin and ord data storage."
    echo "Data directories created at:"
    echo "- Bitcoin: ${BITCOIN_DATA_DIR}"
    echo "- Ord: ${ORD_DATA_DIR}"
    
    # Save configuration
    save_config
}

# Set up Bitcoin Core
setup_bitcoin() {
    echo "Setting up Bitcoin Core..."
    
    # Create bitcoin.conf with lower initial cache settings
    cat > "${BITCOIN_DATA_DIR}/bitcoin.conf" << EOF
# Network
server=1
listen=1
rpcbind=127.0.0.1
rpcallowip=127.0.0.1

# Performance - Start with lower cache for initial startup
dbcache=512
maxmempool=300
maxconnections=40

# Storage
txindex=1
prune=0
datadir=${BITCOIN_DATA_DIR}

# Security
disablewallet=0

# RPC settings - explicitly set these to ensure the RPC server works
rpcuser=bitcoin
rpcpassword=$(head -c 32 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 32)
EOF
    
    # Save the RPC credentials for later use
    echo "rpcuser=bitcoin" > "${STATE_DIR}/bitcoin_rpc"
    grep "rpcpassword=" "${BITCOIN_DATA_DIR}/bitcoin.conf" >> "${STATE_DIR}/bitcoin_rpc"
    
    # Download and install Bitcoin Core
    echo "Downloading Bitcoin Core ${BITCOIN_VERSION}..."
    cd /tmp
    
    # Check if file exists already to avoid re-downloading
    if [[ ! -f "bitcoin-${BITCOIN_VERSION}-x86_64-linux-gnu.tar.gz" ]]; then
        wget "https://bitcoincore.org/bin/bitcoin-core-${BITCOIN_VERSION}/bitcoin-${BITCOIN_VERSION}-x86_64-linux-gnu.tar.gz"
    else
        echo "Bitcoin archive already downloaded. Skipping download."
    fi
    
    echo "Extracting and installing Bitcoin Core..."
    tar -xvf "bitcoin-${BITCOIN_VERSION}-x86_64-linux-gnu.tar.gz"
    install -m 0755 -o root -g root -t /usr/local/bin "bitcoin-${BITCOIN_VERSION}/bin"/*
    
    # Create bash script to run bitcoind with correct parameters and create pid file
    cat > /usr/local/bin/start-bitcoin.sh << EOF
#!/bin/bash
# Start Bitcoin Core with correct parameters
PIDFILE="${BITCOIN_DATA_DIR}/bitcoind.pid"

# Kill any existing Bitcoin process
if [ -f "\$PIDFILE" ]; then
    OLD_PID=\$(cat "\$PIDFILE")
    if ps -p \$OLD_PID > /dev/null; then
        echo "Killing existing Bitcoin process \$OLD_PID"
        kill -15 \$OLD_PID
        sleep 5
    fi
    rm -f "\$PIDFILE"
fi

# Start bitcoind
/usr/local/bin/bitcoind -conf=${BITCOIN_DATA_DIR}/bitcoin.conf -datadir=${BITCOIN_DATA_DIR} -daemon

# Get PID and save it
sleep 3
PID=\$(pgrep -f "bitcoind.*${BITCOIN_DATA_DIR}")
if [ -n "\$PID" ]; then
    echo "\$PID" > "\$PIDFILE"
    echo "Bitcoin Core started with PID \$PID"
    exit 0
else
    echo "Failed to start Bitcoin Core"
    exit 1
fi
EOF
    
    chmod +x /usr/local/bin/start-bitcoin.sh
    
    # Create systemd service for Bitcoin Core with extended timeout
    cat > /etc/systemd/system/bitcoin.service << EOF
[Unit]
Description=Bitcoin daemon
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/bin/start-bitcoin.sh
ExecStop=/usr/local/bin/bitcoin-cli -conf=${BITCOIN_DATA_DIR}/bitcoin.conf -datadir=${BITCOIN_DATA_DIR} stop
PIDFile=${BITCOIN_DATA_DIR}/bitcoind.pid
Restart=on-failure
RestartSec=20
TimeoutStartSec=300
TimeoutStopSec=300
StartLimitInterval=500
StartLimitBurst=5

[Install]
WantedBy=multi-user.target
EOF
    
    # Enable the service but don't try to start it yet
    systemctl daemon-reload
    systemctl enable bitcoin.service
    
    # Add bitcoin-cli alias
    echo "alias bitcoin-cli='bitcoin-cli -conf=${BITCOIN_DATA_DIR}/bitcoin.conf -datadir=${BITCOIN_DATA_DIR}'" >> /root/.bashrc
    
    echo "Bitcoin Core setup complete."
}

# Set up ord
setup_ord() {
    echo "Setting up ord..."
    
    # Install Rust
    echo "Installing Rust..."
    if ! command -v rustc &> /dev/null; then
        curl https://sh.rustup.rs -sSf | sh -s -- -y
        source $HOME/.cargo/env
    else
        echo "Rust is already installed. Skipping."
    fi
    
    # Create ord directories
    mkdir -p /root/.local/share/ord
    
    # Clone and build ord
    echo "Cloning and building ord..."
    if [[ ! -d "/opt/ord" ]]; then
        git clone https://github.com/ordinals/ord.git /opt/ord
    else
        echo "Ord repository already exists. Updating..."
        cd /opt/ord
        git pull
    fi
    
    # Build ord if not already built
    if [[ ! -f "/opt/ord/target/release/ord" ]]; then
        cd /opt/ord
        RUSTFLAGS="-C target-cpu=native" cargo build --release
    else
        echo "Ord binary already exists. Skipping build."
    fi
    
    # Adjust cache size based on available memory
    total_mem_kb=$(grep MemTotal /proc/meminfo | awk '{print $2}')
    total_mem_gb=$((total_mem_kb / 1024 / 1024))
    
    if [ "$total_mem_gb" -ge 32 ]; then
        INDEX_CACHE_SIZE="16000000000"  # 16GB for systems with 32GB+ RAM
    elif [ "$total_mem_gb" -ge 16 ]; then
        INDEX_CACHE_SIZE="8000000000"   # 8GB for systems with 16GB RAM
    else
        INDEX_CACHE_SIZE="4000000000"   # 4GB for systems with less RAM
    fi
    
    echo "Detected ${total_mem_gb}GB of RAM, setting index cache to ${INDEX_CACHE_SIZE} bytes"
    
    # Load RPC credentials
    if [[ -f "${STATE_DIR}/bitcoin_rpc" ]]; then
        source "${STATE_DIR}/bitcoin_rpc"
    fi
    
    # Create ord.yaml configuration
    cat > /root/.local/share/ord/ord.yaml << EOF
bitcoin_data_dir: ${BITCOIN_DATA_DIR}
bitcoin_rpc_url: 127.0.0.1:8332
chain: mainnet
index_runes: true
index_sats: false
index_transactions: true
index_addresses: true
index_cache_size: ${INDEX_CACHE_SIZE}
data_dir: ${ORD_DATA_DIR}
EOF
    
    # Add RPC credentials if they exist
    if [ -n "${rpcuser:-}" ] && [ -n "${rpcpassword:-}" ]; then
        echo "bitcoin_rpc_user: ${rpcuser}" >> /root/.local/share/ord/ord.yaml
        echo "bitcoin_rpc_pass: ${rpcpassword}" >> /root/.local/share/ord/ord.yaml
    fi
    
    # Create bash script to wait for Bitcoin RPC before starting ord
    cat > /usr/local/bin/start-ord.sh << EOF
#!/bin/bash
# Script to wait for Bitcoin RPC before starting ord

# Maximum wait time in seconds
MAX_WAIT=300
WAITED=0

# Check for Bitcoin RPC availability
while [ \$WAITED -lt \$MAX_WAIT ]; do
    if /usr/local/bin/bitcoin-cli -conf=${BITCOIN_DATA_DIR}/bitcoin.conf -datadir=${BITCOIN_DATA_DIR} getblockchaininfo &>/dev/null; then
        echo "Bitcoin RPC is available. Starting ord..."
        break
    fi
    
    echo "Waiting for Bitcoin RPC to become available... (\$WAITED seconds)"
    sleep 10
    WAITED=\$((WAITED + 10))
done

if [ \$WAITED -ge \$MAX_WAIT ]; then
    echo "Bitcoin RPC did not become available within \$MAX_WAIT seconds."
    echo "ord requires Bitcoin RPC to be responsive."
    echo "Will start ord anyway and let it handle reconnection..."
fi

# Start ord
exec /opt/ord/target/release/ord server --http-port ${ORD_HTTP_PORT}
EOF
    
    chmod +x /usr/local/bin/start-ord.sh
    
    # Create systemd service for ord with extended timeout
    cat > /etc/systemd/system/ord.service << EOF
[Unit]
Description=Ord server
After=network.target bitcoin.service
# Use "Wants" instead of "Requires" for a softer dependency
Wants=bitcoin.service

[Service]
ExecStart=/usr/local/bin/start-ord.sh
Restart=always
RestartSec=30
TimeoutStartSec=300
TimeoutStopSec=300
StartLimitInterval=500
StartLimitBurst=5

[Install]
WantedBy=multi-user.target
EOF
    
    # Enable the service (but don't start it yet)
    systemctl daemon-reload
    systemctl enable ord.service
    
    echo "Ord setup complete."
}

# Create monitoring script
create_monitoring_script() {
    echo "Creating monitoring script..."
    
    cat > /usr/local/bin/check-services.sh << 'EOF'
#!/bin/bash

# Load configuration to get proper Bitcoin paths
if [[ -f "/var/lib/bitstrap/config" ]]; then
    source "/var/lib/bitstrap/config"
    BITCOIN_CLI="bitcoin-cli -conf=${BITCOIN_DATA_DIR}/bitcoin.conf -datadir=${BITCOIN_DATA_DIR}"
else
    # Fallback to default command
    BITCOIN_CLI="bitcoin-cli"
    echo "Warning: Could not find configuration file. Using default bitcoin-cli command."
fi

# Set default ORD_HTTP_PORT if not found in config
if [[ -z "${ORD_HTTP_PORT}" ]]; then
    ORD_HTTP_PORT="8080"
fi

# Check Bitcoin Core process
BITCOIN_RUNNING=false
BITCOIN_PID=$(pgrep -f "bitcoind")
if [ -n "$BITCOIN_PID" ]; then
    echo "Bitcoin Core is running with PID $BITCOIN_PID"
    BITCOIN_RUNNING=true
else
    echo "Bitcoin Core is not running. Attempting to restart..."
    systemctl restart bitcoin.service
    sleep 10
    
    # Check if it started
    if pgrep -f "bitcoind" > /dev/null; then
        echo "Bitcoin Core restarted successfully."
        BITCOIN_RUNNING=true
    else
        echo "Failed to restart Bitcoin Core. Please check logs with: journalctl -u bitcoin.service"
    fi
fi

# Check Bitcoin RPC access
if $BITCOIN_RUNNING; then
    if ! $BITCOIN_CLI getblockchaininfo &>/dev/null; then
        echo "WARNING: Bitcoin Core is running but RPC is not accessible."
        echo "This will prevent ord from connecting properly."
    fi
fi

# Check ord
if ! systemctl is-active --quiet ord.service; then
    echo "Ord is not running. Attempting to restart..."
    systemctl restart ord.service
    sleep 10
    
    if ! systemctl is-active --quiet ord.service; then
        echo "Failed to restart Ord. Please check logs with: journalctl -u ord.service"
    else
        echo "Ord restarted successfully."
    fi
fi

# Check Bitcoin sync status
bitcoin_status=$($BITCOIN_CLI getblockchaininfo 2>/dev/null)
if [ $? -eq 0 ]; then
    current_height=$(echo $bitcoin_status | jq -r '.blocks')
    target_height=$(echo $bitcoin_status | jq -r '.headers')
    progress=$(echo $bitcoin_status | jq -r '.verificationprogress')
    progress_percent=$(echo "$progress * 100" | bc -l | awk '{printf "%.2f", $0}')
    
    echo "Bitcoin Core: Block $current_height of $target_height ($progress_percent%)"
else
    echo "Could not get Bitcoin sync status. Command used: $BITCOIN_CLI"
fi

# Check ord status
ord_status=$(curl -s http://localhost:${ORD_HTTP_PORT}/status 2>/dev/null)
if [ $? -eq 0 ]; then
    ord_height=$(curl -s http://localhost:${ORD_HTTP_PORT}/blockheight 2>/dev/null)
    if [ ! -z "$ord_height" ]; then
        echo "Ord: Indexed up to block $ord_height"
    else
        echo "Ord is running but could not get block height."
    fi
else
    echo "Could not get Ord status."
fi
EOF
    
    chmod +x /usr/local/bin/check-services.sh
    
    # Create a cron job to run the monitoring script
    echo "*/10 * * * * /usr/local/bin/check-services.sh >> /var/log/service-monitor.log 2>&1" > /tmp/cronjob
    crontab /tmp/cronjob
    
    echo "Monitoring script created and scheduled."
}

# Create sync monitor for automatic Ord start
create_sync_monitor() {
    echo "Creating Bitcoin sync monitor..."
    
    # Create a script to monitor sync and start ord when complete
    cat > /usr/local/bin/sync-monitor.sh << 'EOF'
#!/bin/bash

# Log file for sync monitoring
LOG_FILE="/var/log/bitcoin-sync-monitor.log"

# Log function
log() {
    echo "[$(date)] $1" >> "$LOG_FILE"
    echo "$1"
}

# Load config
if [[ -f "/var/lib/bitstrap/config" ]]; then
    source "/var/lib/bitstrap/config"
    BITCOIN_CLI="bitcoin-cli -conf=${BITCOIN_DATA_DIR}/bitcoin.conf -datadir=${BITCOIN_DATA_DIR}"
else
    # Fallback to default command
    BITCOIN_CLI="bitcoin-cli"
    log "Warning: Could not find configuration file. Using default bitcoin-cli command."
fi

log "Starting Bitcoin sync monitor..."
log "Using Bitcoin CLI command: ${BITCOIN_CLI}"

# Main monitoring loop
while true; do
    # Check if Bitcoin is running
    if ! pgrep -f "bitcoind" > /dev/null; then
        log "Bitcoin Core is not running. Waiting..."
        sleep 60
        continue
    fi
    
    # Get sync info
    sync_info=$($BITCOIN_CLI getblockchaininfo 2>/dev/null)
    if [ $? -ne 0 ]; then
        log "Failed to get blockchain info. Waiting..."
        sleep 60
        continue
    fi
    
    blocks=$(echo "$sync_info" | jq -r '.blocks')
    headers=$(echo "$sync_info" | jq -r '.headers')
    progress=$(echo "$sync_info" | jq -r '.verificationprogress')
    progress_pct=$(echo "$progress * 100" | bc -l | awk '{printf "%.2f", $0}')
    
    log "Sync progress: Block $blocks of $headers ($progress_pct%)"
    
    # Check if sync is complete (progress > 0.9999)
    if (( $(echo "$progress > 0.9999" | bc -l) )); then
        log "Bitcoin Core sync appears to be complete!"
        
        # Check if ord is already running
        if systemctl is-active --quiet ord.service; then
            log "Ord service is already running."
        else
            log "Starting ord service..."
            systemctl start ord.service
            
            if systemctl is-active --quiet ord.service; then
                log "Ord service started successfully!"
            else
                log "Failed to start ord service. Please check logs."
            fi
        fi
        
        log "Monitoring complete. Exiting."
        exit 0
    fi
    
    # Sleep for 5 minutes before checking again
    sleep 300
done
EOF

    chmod +x /usr/local/bin/sync-monitor.sh

    # Create a systemd service for the sync monitor
    cat > /etc/systemd/system/sync-monitor.service << EOF
[Unit]
Description=Bitcoin Sync Monitor
After=bitcoin.service
Wants=bitcoin.service

[Service]
ExecStart=/usr/local/bin/sync-monitor.sh
Restart=on-failure
RestartSec=30

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload
    systemctl enable sync-monitor.service
    systemctl start sync-monitor.service
    
    echo "Sync monitor created and started."
}

# Set up status page
setup_status_page() {
    echo "Setting up status page..."
    
    # Install Node.js for the status page
    if ! command -v node &> /dev/null; then
        curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
        apt-get install -y nodejs
    else
        echo "Node.js is already installed. Skipping."
    fi
    
    # Create status page directory
    mkdir -p /var/www/status
    
    # Create a simple status page
    cat > /var/www/status/index.js << EOF
const http = require('http');
const { exec } = require('child_process');
const fs = require('fs');

const PORT = 3000;
let ORD_HTTP_PORT = 8080; // Default value

// Get Bitcoin configuration from bitstrap config file
let BITCOIN_DATA_DIR = '';
let bitcoinConfPath = '';
let bitcoinCliCommand = '';

try {
    const configContent = fs.readFileSync('/var/lib/bitstrap/config', 'utf8');
    
    // Get Bitcoin data directory
    const dataMatch = configContent.match(/BITCOIN_DATA_DIR="([^"]+)"/);
    if (dataMatch && dataMatch[1]) {
        BITCOIN_DATA_DIR = dataMatch[1];
        bitcoinConfPath = BITCOIN_DATA_DIR + '/bitcoin.conf';
        bitcoinCliCommand = 'bitcoin-cli -conf=' + bitcoinConfPath + ' -datadir=' + BITCOIN_DATA_DIR;
    } else {
        // Fallback to default command
        bitcoinCliCommand = 'bitcoin-cli';
    }
    
    // Get Ord HTTP port
    const portMatch = configContent.match(/ORD_HTTP_PORT="([^"]+)"/);
    if (portMatch && portMatch[1]) {
        ORD_HTTP_PORT = portMatch[1];
    }
    
} catch (e) {
    console.error('Error loading configuration:', e);
    // Fallback to default command
    bitcoinCliCommand = 'bitcoin-cli';
}

console.log('Using Bitcoin CLI command:', bitcoinCliCommand);
console.log('Using Ord HTTP port:', ORD_HTTP_PORT);

const runCommand = (cmd) => {
    return new Promise((resolve, reject) => {
        exec(cmd, (error, stdout, stderr) => {
            if (error) {
                return reject(error);
            }
            resolve(stdout.trim());
        });
    });
};

// Calculate estimated time remaining based on sync progress
const calculateEstimatedTimeRemaining = (blocks, headers, currentRate) => {
    const blocksRemaining = headers - blocks;
    const hoursRemaining = blocksRemaining / (currentRate * 6); // Assuming 6 blocks per hour average
    
    if (hoursRemaining < 1) {
        return 'less than 1 hour';
    } else if (hoursRemaining < 24) {
        return \`~\${Math.ceil(hoursRemaining)} hours\`;
    } else {
        const days = hoursRemaining / 24;
        return \`~\${days.toFixed(1)} days\`;
    }
};

const server = http.createServer(async (req, res) => {
    try {
        // Get Bitcoin Core status
        let bitcoinStatus;
        let syncRate = 6; // Default assumption of 6 blocks per hour
        let estimatedTimeRemaining = 'calculating...';
        
        try {
            const bitcoinJson = await runCommand(bitcoinCliCommand + ' getblockchaininfo');
            bitcoinStatus = JSON.parse(bitcoinJson);
            
            // Get sync rate from previous measurements
            try {
                const rateDataFile = '/var/www/status/sync_rate.json';
                let rateData = { timestamp: Date.now(), blocks: 0 };
                
                if (fs.existsSync(rateDataFile)) {
                    rateData = JSON.parse(fs.readFileSync(rateDataFile, 'utf8'));
                    
                    const hoursPassed = (Date.now() - rateData.timestamp) / (1000 * 60 * 60);
                    if (hoursPassed > 0.25) { // Only update if at least 15 minutes passed
                        syncRate = (bitcoinStatus.blocks - rateData.blocks) / hoursPassed;
                        // Avoid negative or zero rates due to potential reorg
                        if (syncRate <= 0) syncRate = 6;
                        
                        // Save new measurement
                        fs.writeFileSync(rateDataFile, JSON.stringify({
                            timestamp: Date.now(),
                            blocks: bitcoinStatus.blocks
                        }));
                    }
                } else {
                    // First run, save initial data
                    fs.writeFileSync(rateDataFile, JSON.stringify({
                        timestamp: Date.now(),
                        blocks: bitcoinStatus.blocks
                    }));
                }
                
                // Calculate estimated time
                estimatedTimeRemaining = calculateEstimatedTimeRemaining(
                    bitcoinStatus.blocks, 
                    bitcoinStatus.headers,
                    syncRate
                );
                
            } catch (e) {
                console.error("Error calculating sync rate:", e);
            }
            
        } catch (e) {
            console.error("Bitcoin CLI error:", e);
            bitcoinStatus = { error: "Unable to connect to Bitcoin Core: " + e.message };
        }
        
        // Get ord status
        let ordStatus;
        try {
            const ordUrl = \`http://localhost:\${ORD_HTTP_PORT}/status\`;
            console.log('Trying to fetch ord status from:', ordUrl);
            
            const response = await fetch(ordUrl);
            if (response.ok) {
                ordStatus = await response.text();
            } else {
                ordStatus = "Error fetching ord status";
            }
        } catch (e) {
            console.error('Error connecting to ord:', e);
            ordStatus = "Unable to connect to ord server";
        }
        
        // Get system info
        const diskSpace = await runCommand('df -h /');
        const memory = await runCommand('free -h');
        const uptime = await runCommand('uptime');
        
        const html = \`
<!DOCTYPE html>
<html>
<head>
    <title>Bitcoin + Ord Status</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            line-height: 1.6;
        }
        .card {
            background: #f9f9f9;
            border-radius: 8px;
            padding: 20px;
            margin-bottom: 20px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
        }
        h1, h2 {
            color: #333;
        }
        .metrics {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
        }
        .metric {
            background: #fff;
            padding: 15px;
            border-radius: 8px;
            flex: 1;
            min-width: 200px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.05);
        }
        pre {
            background: #f1f1f1;
            padding: 15px;
            border-radius: 4px;
            overflow-x: auto;
        }
        .progress-bar {
            height: 20px;
            background: #e0e0e0;
            border-radius: 10px;
            overflow: hidden;
            margin: 10px 0;
        }
        .progress {
            height: 100%;
            background: #4caf50;
            transition: width 0.3s ease;
        }
        .phase-indicator {
            display: flex;
            margin: 20px 0;
            position: relative;
        }
        .phase {
            flex: 1;
            text-align: center;
            padding: 10px;
            position: relative;
        }
        .phase::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 5px;
            background: #e0e0e0;
        }
        .phase.active::before {
            background: #4caf50;
        }
        .phase.active {
            font-weight: bold;
        }
        .alert {
            background-color: #fff3cd;
            color: #856404;
            padding: 15px;
            border-radius: 8px;
            margin-bottom: 20px;
        }
        .alert.success {
            background-color: #d4edda;
            color: #155724;
        }
    </style>
</head>
<body>
    <h1>Bitcoin + Ord Status</h1>
    
    \${!bitcoinStatus.error && bitcoinStatus.verificationprogress < 0.9999 ? \`
    <div class="alert">
        <strong>Synchronization in Progress:</strong> Bitcoin needs to sync the entire blockchain before Ord can function properly. 
        This process can take 1-3 days depending on your hardware. Ord will automatically start once sync is complete.
    </div>
    \` : ''}
    
    \${!bitcoinStatus.error && bitcoinStatus.verificationprogress > 0.9999 ? \`
    <div class="alert success">
        <strong>Synchronization Complete:</strong> Bitcoin Core is fully synchronized! Ord should now be operational.
    </div>
    \` : ''}
    
    <div class="card">
        <h2>System Information</h2>
        <div class="metrics">
            <div class="metric">
                <h3>Disk Space</h3>
                <pre>\${diskSpace}</pre>
            </div>
            <div class="metric">
                <h3>Memory</h3>
                <pre>\${memory}</pre>
            </div>
            <div class="metric">
                <h3>Uptime</h3>
                <pre>\${uptime}</pre>
            </div>
        </div>
    </div>
    
    <div class="card">
        <h2>Bitcoin Core Status</h2>
        \${bitcoinStatus.error ? 
            \`<p>Error: \${bitcoinStatus.error}</p>\` : 
            \`<div class="phase-indicator">
                <div class="phase \${bitcoinStatus.blocks > 0 ? 'active' : ''}">
                    <p>Initial Setup</p>
                </div>
                <div class="phase \${bitcoinStatus.blocks > 0 && bitcoinStatus.verificationprogress < 0.9999 ? 'active' : ''}">
                    <p>Blockchain Sync</p>
                </div>
                <div class="phase \${bitcoinStatus.verificationprogress > 0.9999 ? 'active' : ''}">
                    <p>Ready</p>
                </div>
            </div>
            
            <div class="metrics">
                <div class="metric">
                    <h3>Blockchain</h3>
                    <p>Current Block: \${bitcoinStatus.blocks}</p>
                    <p>Headers: \${bitcoinStatus.headers}</p>
                    <p>Blocks Remaining: \${bitcoinStatus.headers - bitcoinStatus.blocks}</p>
                    <p>Sync Rate: ~\${syncRate.toFixed(1)} blocks/hour</p>
                    <p>Estimated Time Remaining: \${estimatedTimeRemaining}</p>
                    <p>Verification Progress:</p>
                    <div class="progress-bar">
                        <div class="progress" style="width: \${bitcoinStatus.verificationprogress * 100}%"></div>
                    </div>
                    <p>\${(bitcoinStatus.verificationprogress * 100).toFixed(2)}%</p>
                </div>
                <div class="metric">
                    <h3>Network</h3>
                    <p>Chain: \${bitcoinStatus.chain}</p>
                    <p>Difficulty: \${bitcoinStatus.difficulty}</p>
                </div>
            </div>
            <h3>Full Details:</h3>
            <pre>\${JSON.stringify(bitcoinStatus, null, 2)}</pre>\`
        }
    </div>
    
    <div class="card">
        <h2>Ord Status</h2>
        \${!bitcoinStatus.error && bitcoinStatus.verificationprogress < 0.9999 ? \`
        <p>Ord is waiting for Bitcoin Core to finish synchronizing before it can start indexing.</p>
        <p>Estimated start time: \${estimatedTimeRemaining}</p>
        \` : \`<pre>\${ordStatus}</pre>
        <p><a href="http://localhost:\${ORD_HTTP_PORT}" target="_blank">Open Ord Explorer</a></p>\`}
    </div>
    
    <div class="card">
        <h2>Useful Commands</h2>
        <pre>
# Check Bitcoin sync status:
\${bitcoinCliCommand} getblockchaininfo

# View Bitcoin Core logs:
journalctl -u bitcoin.service -f

# View Ord logs:
journalctl -u ord.service -f

# Check sync monitor logs:
cat /var/log/bitcoin-sync-monitor.log

# Manually start ord after sync completes:
systemctl start ord.service
        </pre>
    </div>
    
    <footer>
        <p>Last updated: \${new Date().toLocaleString()}</p>
        <p><button onclick="location.reload()">Refresh</button></p>
    </footer>
    
    <script>
        // Auto refresh every 60 seconds
        setTimeout(() => location.reload(), 60000);
    </script>
</body>
</html>
        \`;
        
        res.setHeader('Content-Type', 'text/html');
        res.end(html);
    } catch (error) {
        res.statusCode = 500;
        res.end(\`Error: \${error.message}\`);
    }
});

server.listen(PORT, () => {
    console.log(\`Status page running at http://localhost:\${PORT}\`);
});
EOF
    
    # Create systemd service for the status page
    cat > /etc/systemd/system/node-status.service << EOF
[Unit]
Description=Bitcoin and Ord Status Page
After=network.target

[Service]
ExecStart=/usr/bin/node /var/www/status/index.js
Restart=always
User=root
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target
EOF
    
    # Enable the service
    systemctl enable node-status.service
    
    echo "Status page setup complete. Will be available at http://your-server-ip:3000"
}

# Create user guide
create_user_guide() {
    echo "Creating user guide..."
    
    cat > /root/BITCOIN_ORD_GUIDE.md << 'EOF'
# Bitcoin Core + Ord User Guide

## Overview

Your Bitcoin Core + Ord node has been set up with the following features:

- Full Bitcoin blockchain validation
- Transaction indexing
- Ordinals inscription support
- Rune support
- Address indexing

## Bitcoin Sync Process

The Bitcoin blockchain is a large database (over 500GB) that needs to be downloaded and verified. This process can take several days depending on your hardware and internet connection.

### Monitoring Sync Progress

You can monitor the sync progress using several methods:

1. **Status Page**: Visit http://your-server-ip:3000 to see a visual representation of the sync progress.

2. **Command Line**: Check the current status with:
   ```
   bitcoin-cli getblockchaininfo
   ```
   Look for the "blocks", "headers", and "verificationprogress" fields.

3. **Log Files**: View real-time sync logs with:
   ```
   journalctl -u bitcoin.service -f
   ```

### Sync Phases

1. **Header Download**: The node first downloads all block headers. This is relatively quick.
2. **Block Download and Verification**: This is the longest phase where full blocks are downloaded and verified.
3. **Indexing**: After sync completes, Bitcoin Core builds transaction indexes. This can take 1-2 additional hours.

### When Will Ord Start Working?

The Ord server requires a fully synced Bitcoin Core node to function properly. The script is configured to automatically start Ord once Bitcoin Core is synced.

If you want to manually start Ord after sync completion:
```
systemctl start ord.service
```

### Speeding Up Sync

To speed up the sync process, you can:

1. **Increase dbcache**: Edit [BITCOIN_DATA_DIR]/bitcoin.conf and increase the dbcache value (if you have sufficient RAM).
2. **Improve Network Connection**: Ensure you have good bandwidth.
3. **Use SSD Storage**: SSD significantly speeds up sync compared to HDD.

## Checking Status

### Bitcoin Core

Check Bitcoin sync status:
```
bitcoin-cli getblockchaininfo
```

Check network status:
```
bitcoin-cli getnetworkinfo
```

### Ord

Check ord status by visiting:
```
http://your-server-ip:8080/status
```

Or via the command line:
```
curl http://localhost:8080/status
```

## Available Web Interfaces

- **Ord Explorer**: http://your-server-ip:8080
- **Node Status Page**: http://your-server-ip:3000

## Useful Commands

### Bitcoin Core

Create a new wallet:
```
bitcoin-cli createwallet "ordinals"
```

Generate a new address:
```
bitcoin-cli -rpcwallet=ordinals getnewaddress
```

Check wallet balance:
```
bitcoin-cli -rpcwallet=ordinals getbalance
```

### Ord

Check wallet balance:
```
/opt/ord/target/release/ord wallet balance
```

Create a new wallet:
```
/opt/ord/target/release/ord wallet create
```

Get a new receive address:
```
/opt/ord/target/release/ord wallet receive
```

## Service Management

Restart Bitcoin Core:
```
sudo systemctl restart bitcoin.service
```

Restart Ord:
```
sudo systemctl restart ord.service
```

Check service logs:
```
sudo journalctl -u bitcoin.service -f
sudo journalctl -u ord.service -f
```

## Monitoring

A monitoring script runs every 10 minutes to check service status.
Check the logs:
```
tail -f /var/log/service-monitor.log
```

The sync monitor will automatically start ord once Bitcoin Core is fully synced:
```
tail -f /var/log/bitcoin-sync-monitor.log
```

## Troubleshooting

### If Bitcoin fails to start
```
# Check detailed logs
sudo journalctl -u bitcoin.service -f

# If you see timeout errors, try manual startup:
sudo systemctl stop bitcoin.service
sudo /usr/local/bin/start-bitcoin.sh
```

### If ord cannot connect to Bitcoin Core
```
# Verify Bitcoin RPC is accessible
bitcoin-cli getblockchaininfo

# Check ord logs
journalctl -u ord.service -f

# Restart ord after confirming Bitcoin is running
systemctl restart ord.service
```

### Initial sync may be slow
The first-time Bitcoin Core initialization can take several minutes to create databases.
Initial blockchain sync can take 1-3 days depending on your hardware and internet connection.

## Backup Information

- Bitcoin data directory: [BITCOIN_DATA_DIR]
- Ord data directory: [ORD_DATA_DIR]
- Bitcoin configuration: [BITCOIN_DATA_DIR]/bitcoin.conf
- Ord configuration: /root/.local/share/ord/ord.yaml

Remember to back up your Bitcoin wallet if you create one:
```
bitcoin-cli backupwallet /path/to/backup/wallet.dat
```

## Additional Resources

- [Bitcoin Core Documentation](https://bitcoin.org/en/bitcoin-core/)
- [Ord Documentation](https://docs.ordinals.com/)
- [Ordinals Discord](https://discord.com/invite/ordinals)
EOF

    # Replace placeholders with actual directories
    sed -i "s|\[BITCOIN_DATA_DIR\]|${BITCOIN_DATA_DIR}|g" /root/BITCOIN_ORD_GUIDE.md
    sed -i "s|\[ORD_DATA_DIR\]|${ORD_DATA_DIR}|g" /root/BITCOIN_ORD_GUIDE.md
    
    echo "User guide created at /root/BITCOIN_ORD_GUIDE.md"
}

# Final setup with staged service start
finish_setup() {
    echo "Final setup steps..."
    
    # Check for and kill any existing Bitcoin processes
    if pgrep -f "bitcoind" > /dev/null; then
        echo "Existing Bitcoin Core process found. Stopping it..."
        killall bitcoind
        sleep 5
    fi
    
    # Start Bitcoin using the script we created
    echo "Starting Bitcoin Core..."
    /usr/local/bin/start-bitcoin.sh
    
    # Wait for Bitcoin to initialize
    echo "Waiting for Bitcoin Core to initialize (creating databases)..."
    echo "This may take 3-5 minutes on slower disks. Please be patient."
    
    # Wait loop with progress indicator
    bitcoin_ready=false
    for i in {1..120}; do # Increase timeout to 10 minutes (120 * 5s)
        echo -n "."
        sleep 5
        
        # Try to get info from Bitcoin - if successful, we can proceed
        if bitcoin-cli -conf=${BITCOIN_DATA_DIR}/bitcoin.conf -datadir=${BITCOIN_DATA_DIR} getblockchaininfo &>/dev/null; then
            echo ""
            echo "Bitcoin Core is responding to RPC requests!"
            bitcoin_ready=true
            break
        fi
        
        # If we've waited the full time and still no response
        if [ $i -eq 120 ]; then
            echo ""
            echo "Bitcoin Core is still initializing. This is normal for the first startup."
            echo "Will continue with setup, but you may need to wait longer before the node is fully operational."
        fi
    done
    
    # Start services
    echo "Starting status page service..."
    systemctl start node-status.service
    
    # Start sync monitor (will start ord once sync is complete)
    echo "Starting sync monitor service..."
    systemctl start sync-monitor.service
    
    # Update bitcoin.conf with better performance settings after initialization
    echo "Creating optimized Bitcoin configuration for future use..."
    
    # Get system memory and calculate appropriate cache size
    total_mem_kb=$(grep MemTotal /proc/meminfo | awk '{print $2}')
    total_mem_gb=$((total_mem_kb / 1024 / 1024))
    
    # Determine appropriate dbcache based on available memory
    if [ "$total_mem_gb" -ge 32 ]; then
        db_cache=4096  # 4GB for systems with 32GB+ RAM
        max_mempool=2000
    elif [ "$total_mem_gb" -ge 16 ]; then
        db_cache=2048  # 2GB for systems with 16GB RAM
        max_mempool=1000
    else
        db_cache=1024  # 1GB for systems with less RAM
        max_mempool=500
    fi
    
    # Load RPC credentials
    if [[ -f "${STATE_DIR}/bitcoin_rpc" ]]; then
        source "${STATE_DIR}/bitcoin_rpc"
    fi
    
    # Create updated bitcoin.conf with better performance settings
    cat > "${BITCOIN_DATA_DIR}/bitcoin.conf.new" << EOF
# Network
server=1
listen=1
rpcbind=127.0.0.1
rpcallowip=127.0.0.1

# Performance - Optimized settings
dbcache=${db_cache}
maxmempool=${max_mempool}
maxconnections=40

# Storage
txindex=1
prune=0
datadir=${BITCOIN_DATA_DIR}

# Security
disablewallet=0

# RPC settings
rpcuser=${rpcuser:-bitcoin}
rpcpassword=${rpcpassword:-$(head -c 32 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 32)}
EOF
    
    echo "Created ${BITCOIN_DATA_DIR}/bitcoin.conf.new with optimized settings."
    echo "You can apply these settings on the next restart with:"
    echo "  cp ${BITCOIN_DATA_DIR}/bitcoin.conf.new ${BITCOIN_DATA_DIR}/bitcoin.conf"
    echo "  systemctl restart bitcoin.service"
    
    # Run one check of the monitoring script to get current status
    echo "Running status check..."
    /usr/local/bin/check-services.sh
    
    # If Bitcoin is still not responding, wait longer in a loop and show progress
    if ! $bitcoin_ready; then
        echo "Waiting for Bitcoin Core to become responsive..."
        for i in {1..60}; do # Wait up to 5 more minutes
            echo -n "."
            sleep 5
            
            if bitcoin-cli -conf=${BITCOIN_DATA_DIR}/bitcoin.conf -datadir=${BITCOIN_DATA_DIR} getblockchaininfo &>/dev/null; then
                echo ""
                echo "Bitcoin Core is now responsive!"
                bitcoin_ready=true
                break
            fi
        done
    fi
    
    # Initialize variables for sync status
    current_block=0
    total_headers=0
    sync_percent="0.00"
    estimated_days="calculating"
    initial_blocks=0
    blocks_synced=0
    
    # Function to get current sync status
    get_sync_status() {
        chain_info=$(bitcoin-cli -conf=${BITCOIN_DATA_DIR}/bitcoin.conf -datadir=${BITCOIN_DATA_DIR} getblockchaininfo 2>/dev/null)
        if [ $? -eq 0 ]; then
            current_block=$(echo $chain_info | jq -r '.blocks')
            total_headers=$(echo $chain_info | jq -r '.headers')
            sync_progress=$(echo $chain_info | jq -r '.verificationprogress')
            sync_percent=$(echo "$sync_progress * 100" | bc -l | awk '{printf "%.2f", $0}')
            
            # Estimate remaining time based on sync data
            blocks_remaining=$((total_headers - current_block))
            estimated_days=$(echo "scale=1; $blocks_remaining / 144" | bc -l)  # ~144 blocks per day
            
            # Calculate blocks synced since start
            if [ $initial_blocks -eq 0 ]; then
                initial_blocks=$current_block
            else
                blocks_synced=$((current_block - initial_blocks))
            fi
            
            return 0
        else
            return 1
        fi
    }
    
    # Get initial status
    if get_sync_status; then
        echo "Bitcoin Core is starting to sync the blockchain."
        echo "Initial block height: $current_block"
        
        # If the initial block count is very low, wait to see some sync progress
        if [ $current_block -lt 10 ]; then
            echo "Waiting to see sync progress..."
            
            # Wait for at least 5 minutes or until we see progress
            for i in {1..30}; do
                echo -n "."
                sleep 10
                
                if get_sync_status; then
                    blocks_synced=$((current_block - initial_blocks))
                    if [ $blocks_synced -gt 0 ]; then
                        echo ""
                        echo "Blockchain sync has started! $blocks_synced blocks processed so far."
                        break
                    fi
                fi
                
                # If we've waited the full time and still no progress
                if [ $i -eq 30 ]; then
                    echo ""
                    echo "Bitcoin Core is still at block $current_block."
                    echo "This is normal during initial setup - syncing will continue in the background."
                fi
            done
        fi
    else
        echo "Unable to get blockchain information. Bitcoin Core sync status is unknown."
        echo "The node will continue syncing in the background."
    fi
    
    # Display summary with more sync details
    cat << EOF

╔═══════════════════════════════════════════════════════════════════╗
║                                                                   ║
║   Setup Complete!                                                 ║
║                                                                   ║
║   Bitcoin Core is syncing the blockchain:                         ║
║   Current Block: ${current_block} of ${total_headers}             ║
║   Sync Progress: ${sync_percent}%                                 ║
║   Estimated completion time: ~${estimated_days} days              ║
EOF

    # Add blocks synced info if we've seen progress
    if [ $blocks_synced -gt 0 ]; then
        cat << EOF
║   Blocks synced during setup: ${blocks_synced}                    ║
EOF
    fi

    cat << EOF
║                                                                   ║
║   IMPORTANT: Ord server will start automatically once Bitcoin     ║
║   Core is fully synced. You can monitor progress through the      ║
║   status page.                                                    ║
║                                                                   ║
║   Access Ord Explorer: http://your-server-ip:${ORD_HTTP_PORT}    ║
║   Access Status Page: http://your-server-ip:3000                  ║
║                                                                   ║
║   Check sync progress with:                                       ║
║     - bitcoin-cli getblockchaininfo                               ║
║     - http://your-server-ip:3000 (Status Page)                    ║
║                                                                   ║
║   Sync monitor will automatically start ord after sync completion ║
║   You can check sync monitor logs with:                           ║
║     - cat /var/log/bitcoin-sync-monitor.log                       ║
║                                                                   ║
║   A user guide has been created at /root/BITCOIN_ORD_GUIDE.md     ║
║                                                                   ║
╚═══════════════════════════════════════════════════════════════════╝

EOF
}

# Create uninstall script
create_uninstall_script() {
    cat > /usr/local/bin/uninstall-bitcoin-ord.sh << 'EOF'
#!/bin/bash
# Uninstall script for Bitcoin Core + Ord setup

echo "WARNING: This will remove all Bitcoin Core and Ord data and configurations."
echo "This action is IRREVERSIBLE and will DELETE all blockchain data."
read -p "Are you sure you want to continue? (yes/no): " confirm

if [[ "$confirm" != "yes" ]]; then
    echo "Uninstallation cancelled."
    exit 1
fi

# Load configuration
CONFIG_FILE="/var/lib/bitstrap/config"
if [[ -f "$CONFIG_FILE" ]]; then
    source "$CONFIG_FILE"
    echo "Found configuration file."
    echo "Bitcoin data directory: $BITCOIN_DATA_DIR"
    echo "Ord data directory: $ORD_DATA_DIR"
else
    echo "Configuration file not found. Using default paths."
    BITCOIN_DATA_DIR="/mnt/bitcoin"
    ORD_DATA_DIR="/mnt/ord"
fi

# Kill any running processes first
echo "Killing any running processes..."
killall bitcoind 2>/dev/null || true
killall ord 2>/dev/null || true

# Stop services
echo "Stopping services..."
systemctl stop sync-monitor.service
systemctl stop ord.service
systemctl stop bitcoin.service
systemctl stop node-status.service

# Disable services
echo "Disabling services..."
systemctl disable sync-monitor.service
systemctl disable ord.service
systemctl disable bitcoin.service
systemctl disable node-status.service

# Remove service files
echo "Removing service files..."
rm -f /etc/systemd/system/sync-monitor.service
rm -f /etc/systemd/system/bitcoin.service
rm -f /etc/systemd/system/ord.service
rm -f /etc/systemd/system/node-status.service
systemctl daemon-reload

# Remove data directories
echo "Removing data directories..."
read -p "Delete Bitcoin data (${BITCOIN_DATA_DIR})? (yes/no): " delete_bitcoin
if [[ "$delete_bitcoin" == "yes" ]]; then
    rm -rf "${BITCOIN_DATA_DIR}"
    echo "Bitcoin data deleted."
else
    echo "Bitcoin data preserved."
fi

read -p "Delete Ord data (${ORD_DATA_DIR})? (yes/no): " delete_ord
if [[ "$delete_ord" == "yes" ]]; then
    rm -rf "${ORD_DATA_DIR}"
    echo "Ord data deleted."
else
    echo "Ord data preserved."
fi

# Remove startup scripts
echo "Removing startup scripts..."
rm -f /usr/local/bin/start-bitcoin.sh
rm -f /usr/local/bin/start-ord.sh
rm -f /usr/local/bin/sync-monitor.sh

# Remove configuration files
echo "Removing configuration files..."
rm -rf /root/.local/share/ord
rm -f /root/BITCOIN_ORD_GUIDE.md
rm -f /usr/local/bin/check-services.sh
rm -rf /var/www/status
rm -rf /var/lib/bitstrap
rm -f /var/log/bitcoin-sync-monitor.log

# Remove cron job
echo "Removing cron job..."
crontab -l | grep -v "check-services.sh" | crontab -

echo "Uninstallation complete! To remove Bitcoin Core and Ord binaries, run:"
echo "rm -f /usr/local/bin/bitcoin*"
echo "rm -rf /opt/ord"

echo "To remove dependencies (Node.js, Rust, etc.), you may need to manually remove them."
EOF

    chmod +x /usr/local/bin/uninstall-bitcoin-ord.sh
    echo "Uninstall script created at /usr/local/bin/uninstall-bitcoin-ord.sh"
}

# Function to print status of setup
print_status() {
    echo "===== Current Setup Status ====="
    
    # Check dependencies
    if check_state "dependencies"; then
        echo "✅ Dependencies: Installed"
    else
        echo "❌ Dependencies: Not installed"
    fi
    
    # Check storage
    if check_state "storage"; then
        echo "✅ Storage: Configured (${BITCOIN_DATA_DIR})"
    else
        echo "❌ Storage: Not configured"
    fi
    
    # Check Bitcoin
    if check_state "bitcoin"; then
        echo "✅ Bitcoin Core: Installed"
        if pgrep -f "bitcoind" > /dev/null; then
            echo "   - Status: Running"
            bitcoin_info=$(bitcoin-cli -conf=${BITCOIN_DATA_DIR}/bitcoin.conf -datadir=${BITCOIN_DATA_DIR} getblockchaininfo 2>/dev/null)
            if [ $? -eq 0 ]; then
                blocks=$(echo $bitcoin_info | jq -r '.blocks')
                progress=$(echo $bitcoin_info | jq -r '.verificationprogress')
                progress_pct=$(echo "$progress * 100" | bc -l | awk '{printf "%.2f", $0}')
                echo "   - Sync: Block $blocks (${progress_pct}%)"
            else
                echo "   - Sync: Unknown (unable to query RPC)"
            fi
        else
            echo "   - Status: Not running"
        fi
    else
        echo "❌ Bitcoin Core: Not installed"
    fi
    
    # Check ord
    if check_state "ord"; then
        echo "✅ Ord: Installed"
        if pgrep -f "ord server" > /dev/null; then
            echo "   - Status: Running"
        else
            echo "   - Status: Not running"
        fi
    else
        echo "❌ Ord: Not installed"
    fi
    
    # Check monitoring
    if check_state "monitoring"; then
        echo "✅ Monitoring: Configured"
    else
        echo "❌ Monitoring: Not configured"
    fi
    
    # Check sync monitor
    if check_state "sync_monitor"; then
        echo "✅ Sync Monitor: Configured"
        if systemctl is-active --quiet sync-monitor.service; then
            echo "   - Status: Running"
        else
            echo "   - Status: Not running"
        fi
    else
        echo "❌ Sync Monitor: Not configured"
    fi
    
    # Check status page
    if check_state "status_page"; then
        echo "✅ Status Page: Installed"
        if pgrep -f "node /var/www/status/index.js" > /dev/null; then
            echo "   - Status: Running (http://your-server-ip:3000)"
        else
            echo "   - Status: Not running"
        fi
    else
        echo "❌ Status Page: Not installed"
    fi
    
    # Check user guide
    if check_state "user_guide"; then
        echo "✅ User Guide: Created"
    else
        echo "❌ User Guide: Not created"
    fi
    
    # Check setup completion
    if check_state "finish"; then
        echo "✅ Setup: Complete"
    else
        echo "❌ Setup: Not complete"
    fi
    
    echo "============================="
}

# Main execution
main() {
    # Create uninstall script first in case we need it
    create_uninstall_script
    
    # Initialize state
    initialize_state
    
    # Print current status
    print_status
    
    # Step 1: Install dependencies
    if ! check_state "dependencies"; then
        install_dependencies
        update_state "dependencies"
    else
        echo "Dependencies already installed. Skipping."
    fi
    
    # Step 2: Choose storage
    if ! check_state "storage"; then
        choose_storage
        update_state "storage"
    else
        echo "Storage already configured. Skipping."
    fi
    
    # Step 3: Set up Bitcoin Core
    if ! check_state "bitcoin"; then
        setup_bitcoin
        update_state "bitcoin"
    else
        echo "Bitcoin Core already set up. Skipping."
    fi
    
    # Step 4: Set up ord
    if ! check_state "ord"; then
        setup_ord
        update_state "ord"
    else
        echo "Ord already set up. Skipping."
    fi
    
    # Step 5: Create monitoring script
    if ! check_state "monitoring"; then
        create_monitoring_script
        update_state "monitoring"
    else
        echo "Monitoring already configured. Skipping."
    fi
    
    # Step 6: Set up status page
    if ! check_state "status_page"; then
        setup_status_page
        update_state "status_page"
    else
        echo "Status page already set up. Skipping."
    fi
    
    # Step 7: Set up sync monitor
    if ! check_state "sync_monitor"; then
        create_sync_monitor
        update_state "sync_monitor"
    else
        echo "Sync monitor already set up. Skipping."
    fi
    
    # Step 8: Create user guide
    if ! check_state "user_guide"; then
        create_user_guide
        update_state "user_guide"
    else
        echo "User guide already created. Skipping."
    fi
    
    # Step 9: Finish setup
    if ! check_state "finish"; then
        finish_setup
        update_state "finish"
    else
        echo "Setup already completed. Skipping."
    fi
    
    # Print final status
    print_status
}

# Run the main function
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main
fi