#!/bin/bash

# Production Deployment Script for WhatsApp Concierge Taxi Booking System
# Version: 2.0.0

set -e  # Exit on any error

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

# Configuration
APP_NAME="whatsapp-concierge-taxi-booking"
NODE_VERSION="18.0.0"
PM2_APP_NAME="concierge-taxi-booking"

# Logging function
log() {
    echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}"
}

warn() {
    echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}"
}

error() {
    echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}"
}

# Check if running as root
check_root() {
    if [[ $EUID -eq 0 ]]; then
        error "This script should not be run as root"
        exit 1
    fi
}

# Check system requirements
check_requirements() {
    log "Checking system requirements..."
    
    # Check Node.js version
    if ! command -v node &> /dev/null; then
        error "Node.js is not installed"
        exit 1
    fi
    
    NODE_CURRENT=$(node -v | cut -d'v' -f2)
    if [[ "$(printf '%s\n' "$NODE_VERSION" "$NODE_CURRENT" | sort -V | head -n1)" != "$NODE_VERSION" ]]; then
        warn "Node.js version $NODE_CURRENT is older than recommended $NODE_VERSION"
    fi
    
    # Check npm
    if ! command -v npm &> /dev/null; then
        error "npm is not installed"
        exit 1
    fi
    
    # Check MongoDB
    if ! command -v mongod &> /dev/null; then
        warn "MongoDB is not installed locally. Make sure you have access to a MongoDB instance."
    fi
    
    # Check PM2
    if ! command -v pm2 &> /dev/null; then
        log "Installing PM2..."
        npm install -g pm2
    fi
    
    log "System requirements check completed"
}

# Create production environment file
setup_environment() {
    log "Setting up production environment..."
    
    if [[ ! -f .env ]]; then
        log "Creating .env file from template..."
        cp env.example .env
        warn "Please update .env file with your production values"
    else
        log ".env file already exists"
    fi
    
    # Create logs directory
    mkdir -p logs
    mkdir -p data/backups
    
    log "Environment setup completed"
}

# Install dependencies
install_dependencies() {
    log "Installing dependencies..."
    
    # Clean install
    rm -rf node_modules package-lock.json
    npm ci --production
    
    log "Dependencies installed successfully"
}

# Build application
build_application() {
    log "Building application..."
    
    # Run any build scripts if they exist
    if [[ -f "scripts/build.js" ]]; then
        node scripts/build.js
    fi
    
    log "Application build completed"
}

# Setup PM2 ecosystem
setup_pm2() {
    log "Setting up PM2 ecosystem..."
    
    cat > ecosystem.config.js << EOF
module.exports = {
  apps: [
    {
      name: '${PM2_APP_NAME}-web',
      script: 'src/web-server.js',
      instances: 1,
      autorestart: true,
      watch: false,
      max_memory_restart: '1G',
      env: {
        NODE_ENV: 'production',
        PORT: 3001
      },
      error_file: './logs/web-error.log',
      out_file: './logs/web-out.log',
      log_file: './logs/web-combined.log',
      time: true
    },
    {
      name: '${PM2_APP_NAME}-bot',
      script: 'src/index.js',
      instances: 1,
      autorestart: true,
      watch: false,
      max_memory_restart: '1G',
      env: {
        NODE_ENV: 'production',
        PORT: 3000
      },
      error_file: './logs/bot-error.log',
      out_file: './logs/bot-out.log',
      log_file: './logs/bot-combined.log',
      time: true
    }
  ]
};
EOF
    
    log "PM2 ecosystem configured"
}

# Run database migrations
run_migrations() {
    log "Running database migrations..."
    
    # Initialize database
    node scripts/initDatabase.js
    
    # Run any additional migrations
    if [[ -f "scripts/migrateAllConfigsToDatabase.js" ]]; then
        node scripts/migrateAllConfigsToDatabase.js
    fi
    
    log "Database migrations completed"
}

# Setup monitoring
setup_monitoring() {
    log "Setting up monitoring..."
    
    # Create log rotation configuration
    cat > /etc/logrotate.d/${APP_NAME} << EOF
${PWD}/logs/*.log {
    daily
    missingok
    rotate 7
    compress
    delaycompress
    notifempty
    create 644 $(whoami) $(whoami)
    postrotate
        pm2 reloadLogs
    endscript
}
EOF
    
    log "Monitoring setup completed"
}

# Setup firewall rules
setup_firewall() {
    log "Setting up firewall rules..."
    
    # Allow HTTP and HTTPS
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    
    # Allow application ports
    sudo ufw allow 3000/tcp
    sudo ufw allow 3001/tcp
    
    # Allow MongoDB port if running locally
    sudo ufw allow 27017/tcp
    
    log "Firewall rules configured"
}

# Create systemd service (optional)
setup_systemd() {
    log "Setting up systemd service..."
    
    sudo tee /etc/systemd/system/${APP_NAME}.service > /dev/null << EOF
[Unit]
Description=WhatsApp Concierge Taxi Booking System
After=network.target

[Service]
Type=forking
User=$(whoami)
WorkingDirectory=${PWD}
ExecStart=/usr/bin/pm2 start ecosystem.config.js
ExecReload=/usr/bin/pm2 reload ecosystem.config.js
ExecStop=/usr/bin/pm2 stop ecosystem.config.js
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF
    
    sudo systemctl daemon-reload
    sudo systemctl enable ${APP_NAME}
    
    log "Systemd service configured"
}

# Health check
health_check() {
    log "Performing health check..."
    
    # Wait for services to start
    sleep 10
    
    # Check web server
    if node -e "const httpClient = require('./src/utils/httpClient'); httpClient.healthCheck('http://localhost:3001/health/live').then(result => { process.exit(result.healthy ? 0 : 1); }).catch(() => process.exit(1));" 2>/dev/null; then
        log "Web server is healthy"
    else
        error "Web server health check failed"
        return 1
    fi
    
    # Check bot server
    if node -e "const httpClient = require('./src/utils/httpClient'); httpClient.healthCheck('http://localhost:3000/health/live').then(result => { process.exit(result.healthy ? 0 : 1); }).catch(() => process.exit(1));" 2>/dev/null; then
        log "Bot server is healthy"
    else
        error "Bot server health check failed"
        return 1
    fi
    
    log "Health check completed successfully"
}

# Main deployment function
deploy() {
    log "Starting production deployment..."
    
    check_root
    check_requirements
    setup_environment
    install_dependencies
    build_application
    setup_pm2
    run_migrations
    setup_monitoring
    setup_firewall
    setup_systemd
    
    log "Starting services with PM2..."
    pm2 start ecosystem.config.js
    
    health_check
    
    log "Deployment completed successfully!"
    log "Application URLs:"
    log "  - Web Dashboard: http://localhost:3001"
    log "  - Health Check: http://localhost:3001/health"
    log "  - Metrics: http://localhost:3001/metrics"
    
    log "PM2 Commands:"
    log "  - View logs: pm2 logs"
    log "  - Monitor: pm2 monit"
    log "  - Restart: pm2 restart all"
    log "  - Stop: pm2 stop all"
}

# Rollback function
rollback() {
    log "Rolling back deployment..."
    
    pm2 stop all
    pm2 delete all
    
    # Restore from backup if exists
    if [[ -d "backups/latest" ]]; then
        log "Restoring from backup..."
        cp -r backups/latest/* .
    fi
    
    log "Rollback completed"
}

# Usage
usage() {
    echo "Usage: $0 [deploy|rollback|health]"
    echo "  deploy   - Deploy the application to production"
    echo "  rollback - Rollback to previous version"
    echo "  health   - Check application health"
    exit 1
}

# Main script
case "${1:-deploy}" in
    deploy)
        deploy
        ;;
    rollback)
        rollback
        ;;
    health)
        health_check
        ;;
    *)
        usage
        ;;
esac 