#!/bin/bash

# Vision Videoke Customer Installer
# One-click installer for customers to deploy Vision Videoke on their EC2 instance

set -e

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

# ASCII Art Banner
show_banner() {
    echo -e "${PURPLE}"
    cat << "EOF"
╦  ╦┬┌─┐┬┌─┐┌┐┌  ╦  ╦┬┌┬┐┌─┐┌─┐┬┌─┌─┐
╚╗╔╝│└─┐││ ││││  ╚╗╔╝│ ││ ├┤ │ │├┴┐├┤ 
 ╚╝ ┴└─┘┴└─┘┘└┘   ╚╝ ┴─┴┘ └─┘└─┘┴ ┴└─┘
                                        
    Professional Music Video Creator
         One-Click EC2 Installer
EOF
    echo -e "${NC}"
}

log() {
    echo -e "${GREEN}[$(date +'%H:%M:%S')] ✓ $1${NC}"
}

error() {
    echo -e "${RED}[ERROR] ✗ $1${NC}"
    exit 1
}

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

info() {
    echo -e "${BLUE}[INFO] ℹ $1${NC}"
}

step() {
    echo -e "${CYAN}[STEP] ➤ $1${NC}"
}

# Check if running on Amazon Linux
check_system() {
    if [ ! -f /etc/os-release ]; then
        error "Cannot determine operating system"
    fi
    
    if ! grep -q "Amazon Linux" /etc/os-release; then
        error "This installer is designed for Amazon Linux. Please use an Amazon Linux EC2 instance."
    fi
    
    if [[ $EUID -eq 0 ]]; then
        error "Please run this installer as ec2-user, not as root"
    fi
    
    log "System check passed - Amazon Linux detected"
}

# Welcome message and confirmation
welcome_message() {
    clear
    show_banner
    
    echo -e "${CYAN}Welcome to the Vision Videoke Installer!${NC}"
    echo ""
    echo "This installer will set up a complete Vision Videoke platform on your EC2 instance."
    echo ""
    echo -e "${YELLOW}What will be installed:${NC}"
    echo "• Node.js 18 (LTS) and npm"
    echo "• PM2 process manager"
    echo "• Nginx web server with SSL support"
    echo "• Vision Videoke application"
    echo "• Security configurations and monitoring"
    echo "• Automated backup system"
    echo ""
    echo -e "${YELLOW}Prerequisites:${NC}"
    echo "• Amazon Linux EC2 instance (t3.medium or larger recommended)"
    echo "• At least 2GB RAM and 20GB storage"
    echo "• Domain name pointed to this server (for SSL)"
    echo "• API keys for OpenAI, Udio, and ElevenLabs"
    echo ""
    
    read -p "Do you want to continue with the installation? (y/N): " -n 1 -r
    echo ""
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        echo "Installation cancelled."
        exit 0
    fi
}

# Collect customer information
collect_info() {
    step "Collecting configuration information"
    echo ""
    
    # Domain name
    while true; do
        read -p "Enter your domain name (e.g., mysite.com): " DOMAIN_NAME
        if [[ $DOMAIN_NAME =~ ^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}$ ]]; then
            break
        else
            warn "Please enter a valid domain name"
        fi
    done
    
    # Email for SSL
    while true; do
        read -p "Enter your email for SSL certificate: " SSL_EMAIL
        if [[ $SSL_EMAIL =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$ ]]; then
            break
        else
            warn "Please enter a valid email address"
        fi
    done
    
    # API Keys
    echo ""
    info "API Keys (required for full functionality):"
    echo "You can update these later in the configuration file."
    echo ""
    
    read -p "OpenAI API Key: " -s OPENAI_KEY
    echo ""
    read -p "Udio API Key: " -s UDIO_KEY
    echo ""
    read -p "ElevenLabs API Key: " -s ELEVENLABS_KEY
    echo ""
    
    # Optional: Stripe keys
    echo ""
    read -p "Stripe Publishable Key (optional): " STRIPE_PUB_KEY
    read -p "Stripe Secret Key (optional): " -s STRIPE_SECRET_KEY
    echo ""
    
    log "Configuration information collected"
}

# Download and extract installation files
download_installer() {
    step "Downloading installation files"
    
    INSTALL_DIR="/tmp/visionvideoke-install"
    rm -rf $INSTALL_DIR
    mkdir -p $INSTALL_DIR
    cd $INSTALL_DIR
    
    # In a real deployment, this would download from your distribution server
    # For now, we'll create the necessary files
    info "Preparing installation files..."
    
    # Create a temporary structure (in production, this would be downloaded)
    mkdir -p {scripts,config,app}
    
    log "Installation files prepared"
}

# Run system setup
run_system_setup() {
    step "Setting up system environment"
    
    # Update system
    info "Updating system packages..."
    sudo yum update -y > /dev/null 2>&1
    
    # Install essential packages
    info "Installing essential packages..."
    sudo yum groupinstall -y "Development Tools" > /dev/null 2>&1
    sudo yum install -y git curl wget unzip htop nginx certbot python3-certbot-nginx fail2ban firewalld > /dev/null 2>&1
    
    # Install Node.js
    info "Installing Node.js 18..."
    curl -fsSL https://rpm.nodesource.com/setup_18.x | sudo bash - > /dev/null 2>&1
    sudo yum install -y nodejs > /dev/null 2>&1
    
    # Install PM2
    info "Installing PM2..."
    sudo npm install -g pm2 > /dev/null 2>&1
    
    # Install Yarn
    sudo npm install -g yarn > /dev/null 2>&1
    
    log "System setup completed"
}

# Configure security
setup_security() {
    step "Configuring security"
    
    # Setup firewall
    info "Configuring firewall..."
    sudo systemctl start firewalld > /dev/null 2>&1
    sudo systemctl enable firewalld > /dev/null 2>&1
    sudo firewall-cmd --permanent --add-service=http > /dev/null 2>&1
    sudo firewall-cmd --permanent --add-service=https > /dev/null 2>&1
    sudo firewall-cmd --permanent --add-service=ssh > /dev/null 2>&1
    sudo firewall-cmd --permanent --add-port=3000/tcp > /dev/null 2>&1
    sudo firewall-cmd --reload > /dev/null 2>&1
    
    # Setup fail2ban
    info "Configuring fail2ban..."
    sudo systemctl start fail2ban > /dev/null 2>&1
    sudo systemctl enable fail2ban > /dev/null 2>&1
    
    log "Security configuration completed"
}

# Setup application directories
setup_directories() {
    step "Creating application directories"
    
    sudo mkdir -p /var/www/visionvideoke
    sudo mkdir -p /var/log/visionvideoke
    sudo mkdir -p /var/backups/visionvideoke
    
    sudo chown ec2-user:ec2-user /var/www/visionvideoke
    sudo chown ec2-user:ec2-user /var/log/visionvideoke
    sudo chown ec2-user:ec2-user /var/backups/visionvideoke
    
    log "Application directories created"
}

# Configure nginx
setup_nginx() {
    step "Configuring Nginx"
    
    # Create nginx configuration
    sudo tee /etc/nginx/sites-available/visionvideoke > /dev/null <<EOF
# Vision Videoke Nginx Configuration
upstream visionvideoke_app {
    server 127.0.0.1:3000;
    keepalive 32;
}

server {
    listen 80;
    server_name $DOMAIN_NAME www.$DOMAIN_NAME;
    
    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }
    
    location / {
        proxy_pass http://visionvideoke_app;
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_cache_bypass \$http_upgrade;
    }
    
    location /health {
        access_log off;
        return 200 "healthy\\n";
        add_header Content-Type text/plain;
    }
}
EOF
    
    # Create sites-enabled directory if it doesn't exist
    sudo mkdir -p /etc/nginx/sites-enabled
    
    # Enable the site
    sudo ln -sf /etc/nginx/sites-available/visionvideoke /etc/nginx/sites-enabled/
    
    # Remove default site
    sudo rm -f /etc/nginx/sites-enabled/default
    
    # Test and start nginx
    sudo nginx -t
    sudo systemctl start nginx
    sudo systemctl enable nginx
    
    log "Nginx configuration completed"
}

# Create environment configuration
create_environment() {
    step "Creating environment configuration"
    
    # Generate secrets
    JWT_SECRET=$(openssl rand -hex 32)
    ENCRYPTION_KEY=$(openssl rand -hex 32)
    
    # Create environment file
    cat > /var/www/visionvideoke/.env <<EOF
# Vision Videoke Production Environment
NODE_ENV=production
PORT=3000

# Domain Configuration
DOMAIN_NAME=$DOMAIN_NAME
SSL_EMAIL=$SSL_EMAIL

# API Keys
REACT_APP_OPENAI_API_KEY=$OPENAI_KEY
REACT_APP_UDIO_API_KEY=$UDIO_KEY
REACT_APP_ELEVENLABS_API_KEY=$ELEVENLABS_KEY

# Payment Processing
REACT_APP_STRIPE_PUBLISHABLE_KEY=$STRIPE_PUB_KEY
STRIPE_SECRET_KEY=$STRIPE_SECRET_KEY

# Security
JWT_SECRET=$JWT_SECRET
ENCRYPTION_KEY=$ENCRYPTION_KEY

# Application URLs
REACT_APP_API_URL=https://$DOMAIN_NAME/api
REACT_APP_APP_URL=https://$DOMAIN_NAME

# Feature Flags
REACT_APP_ENABLE_VOICE_CLONING=true
REACT_APP_ENABLE_VIDEO_GENERATION=true
REACT_APP_ENABLE_PAYMENTS=true
EOF
    
    chmod 600 /var/www/visionvideoke/.env
    
    log "Environment configuration created"
}

# Install application
install_application() {
    step "Installing Vision Videoke application"
    
    cd /var/www/visionvideoke
    
    # In production, this would download the actual application package
    # For now, we'll create a placeholder structure
    info "Downloading application package..."
    
    # Create package.json
    cat > package.json <<EOF
{
  "name": "visionvideoke",
  "version": "1.0.0",
  "description": "Vision Videoke - Transform vision boards into music videos",
  "main": "server.js",
  "scripts": {
    "start": "serve -s dist -l 3000",
    "build": "echo 'Build completed'",
    "dev": "echo 'Development mode'"
  },
  "dependencies": {
    "serve": "^14.0.0"
  }
}
EOF
    
    # Create basic dist directory with index.html
    mkdir -p dist
    cat > dist/index.html <<EOF
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vision Videoke - Coming Soon</title>
    <style>
        body { 
            font-family: Arial, sans-serif; 
            text-align: center; 
            padding: 50px; 
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            margin: 0;
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-direction: column;
        }
        .container {
            max-width: 600px;
            padding: 40px;
            background: rgba(255,255,255,0.1);
            border-radius: 20px;
            backdrop-filter: blur(10px);
        }
        h1 { font-size: 3em; margin-bottom: 20px; }
        p { font-size: 1.2em; line-height: 1.6; }
        .status { 
            background: rgba(0,255,0,0.2); 
            padding: 10px 20px; 
            border-radius: 10px; 
            margin: 20px 0;
            border: 1px solid rgba(0,255,0,0.3);
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>🎬 Vision Videoke</h1>
        <div class="status">✅ Installation Successful!</div>
        <p>Your Vision Videoke platform has been successfully installed and is running.</p>
        <p>Transform your vision boards into personalized music videos with karaoke lyrics!</p>
        <p><strong>Next Steps:</strong></p>
        <ul style="text-align: left; display: inline-block;">
            <li>Upload your application files</li>
            <li>Configure SSL certificate</li>
            <li>Update API keys in configuration</li>
            <li>Start creating amazing music videos!</li>
        </ul>
        <p style="margin-top: 30px; font-size: 0.9em; opacity: 0.8;">
            Server: $DOMAIN_NAME | Status: Online | Version: 1.0.0
        </p>
    </div>
</body>
</html>
EOF
    
    # Install dependencies
    info "Installing dependencies..."
    npm install > /dev/null 2>&1
    
    # Create PM2 ecosystem
    cat > ecosystem.config.js <<EOF
module.exports = {
  apps: [{
    name: 'visionvideoke',
    script: 'npm',
    args: 'start',
    cwd: '/var/www/visionvideoke',
    instances: 'max',
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    },
    error_file: '/var/log/visionvideoke/error.log',
    out_file: '/var/log/visionvideoke/out.log',
    log_file: '/var/log/visionvideoke/combined.log',
    time: true,
    max_memory_restart: '1G'
  }]
};
EOF
    
    # Start application
    pm2 start ecosystem.config.js
    pm2 save
    
    log "Application installation completed"
}

# Setup SSL certificate
setup_ssl() {
    step "Setting up SSL certificate"
    
    info "Obtaining SSL certificate for $DOMAIN_NAME..."
    
    # Stop nginx temporarily
    sudo systemctl stop nginx
    
    # Get certificate
    if sudo certbot certonly --standalone -d $DOMAIN_NAME --email $SSL_EMAIL --agree-tos --non-interactive; then
        log "SSL certificate obtained successfully"
        
        # Update nginx configuration for SSL
        sudo tee /etc/nginx/sites-available/visionvideoke > /dev/null <<EOF
upstream visionvideoke_app {
    server 127.0.0.1:3000;
    keepalive 32;
}

server {
    listen 80;
    server_name $DOMAIN_NAME www.$DOMAIN_NAME;
    return 301 https://\$server_name\$request_uri;
}

server {
    listen 443 ssl http2;
    server_name $DOMAIN_NAME www.$DOMAIN_NAME;
    
    ssl_certificate /etc/letsencrypt/live/$DOMAIN_NAME/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$DOMAIN_NAME/privkey.pem;
    
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    
    location / {
        proxy_pass http://visionvideoke_app;
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_cache_bypass \$http_upgrade;
    }
    
    location /health {
        access_log off;
        return 200 "healthy\\n";
        add_header Content-Type text/plain;
    }
}
EOF
        
        # Setup auto-renewal
        echo "0 12 * * * /usr/bin/certbot renew --quiet" | sudo crontab -
        
    else
        warn "SSL certificate setup failed. You can set it up later manually."
    fi
    
    # Start nginx
    sudo systemctl start nginx
}

# Setup monitoring and maintenance
setup_monitoring() {
    step "Setting up monitoring and maintenance"
    
    # Create health check script
    cat > /home/ec2-user/health-check.sh <<'EOF'
#!/bin/bash
if ! curl -f -s http://localhost:3000/health > /dev/null; then
    echo "Application is down, restarting..."
    pm2 restart all
fi
EOF
    chmod +x /home/ec2-user/health-check.sh
    
    # Create backup script
    cat > /home/ec2-user/backup.sh <<'EOF'
#!/bin/bash
BACKUP_DIR="/var/backups/visionvideoke"
APP_DIR="/var/www/visionvideoke"
BACKUP_NAME="backup-$(date +%Y%m%d-%H%M%S).tar.gz"

mkdir -p $BACKUP_DIR
tar -czf "$BACKUP_DIR/$BACKUP_NAME" -C "$APP_DIR" . --exclude=node_modules --exclude=.git

# Keep only last 10 backups
cd $BACKUP_DIR
ls -t backup-*.tar.gz | tail -n +11 | xargs rm -f 2>/dev/null || true
EOF
    chmod +x /home/ec2-user/backup.sh
    
    # Setup cron jobs
    (crontab -l 2>/dev/null; echo "*/5 * * * * /home/ec2-user/health-check.sh") | crontab -
    (crontab -l 2>/dev/null; echo "0 2 * * * /home/ec2-user/backup.sh") | crontab -
    
    log "Monitoring and maintenance setup completed"
}

# Create management scripts
create_management_scripts() {
    step "Creating management scripts"
    
    # Create update script
    cat > /home/ec2-user/update-app.sh <<'EOF'
#!/bin/bash
echo "Updating Vision Videoke application..."
cd /var/www/visionvideoke
pm2 stop all
# Add your update logic here
pm2 start all
echo "Update completed!"
EOF
    chmod +x /home/ec2-user/update-app.sh
    
    # Create status script
    cat > /home/ec2-user/status.sh <<'EOF'
#!/bin/bash
echo "=== Vision Videoke Status ==="
echo ""
echo "Application Status:"
pm2 list
echo ""
echo "Nginx Status:"
sudo systemctl status nginx --no-pager -l
echo ""
echo "SSL Certificate Status:"
sudo certbot certificates 2>/dev/null || echo "No SSL certificates found"
echo ""
echo "Disk Usage:"
df -h /var/www/visionvideoke
echo ""
echo "Memory Usage:"
free -h
EOF
    chmod +x /home/ec2-user/status.sh
    
    log "Management scripts created"
}

# Final setup and testing
final_setup() {
    step "Performing final setup and testing"
    
    # Test application
    info "Testing application..."
    sleep 5
    
    if curl -f -s http://localhost:3000/health > /dev/null; then
        log "Application is running successfully"
    else
        warn "Application health check failed, but installation completed"
    fi
    
    # Test nginx
    if sudo nginx -t > /dev/null 2>&1; then
        log "Nginx configuration is valid"
    else
        warn "Nginx configuration has issues"
    fi
    
    # Create installation summary
    cat > /home/ec2-user/installation-summary.txt <<EOF
Vision Videoke Installation Summary
==================================
Installation Date: $(date)
Domain: $DOMAIN_NAME
SSL Email: $SSL_EMAIL

Installation Status: COMPLETED

Services Status:
- Application: Running on port 3000
- Nginx: Running on ports 80/443
- PM2: Managing application processes
- SSL: $([ -f "/etc/letsencrypt/live/$DOMAIN_NAME/fullchain.pem" ] && echo "Configured" || echo "Not configured")

Important Files:
- Application: /var/www/visionvideoke/
- Environment: /var/www/visionvideoke/.env
- Logs: /var/log/visionvideoke/
- Backups: /var/backups/visionvideoke/

Management Commands:
- ./status.sh          - Check system status
- ./update-app.sh      - Update application
- ./backup.sh          - Create backup
- pm2 restart all      - Restart application
- sudo systemctl reload nginx - Reload web server

Next Steps:
1. Upload your Vision Videoke application files to /var/www/visionvideoke/
2. Update API keys in /var/www/visionvideoke/.env
3. Test your domain: https://$DOMAIN_NAME
4. Configure payment processing if needed

Support:
- Check logs: tail -f /var/log/visionvideoke/combined.log
- Monitor status: ./status.sh
- Create backups: ./backup.sh
EOF
    
    log "Final setup completed"
}

# Success message
show_success() {
    clear
    show_banner
    
    echo -e "${GREEN}🎉 Installation Completed Successfully! 🎉${NC}"
    echo ""
    echo -e "${CYAN}Your Vision Videoke platform is now running!${NC}"
    echo ""
    echo -e "${YELLOW}Access your platform:${NC}"
    echo "• HTTP:  http://$DOMAIN_NAME"
    echo "• HTTPS: https://$DOMAIN_NAME (if SSL was configured)"
    echo "• Local: http://$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4 2>/dev/null || echo 'YOUR-SERVER-IP')"
    echo ""
    echo -e "${YELLOW}Important Next Steps:${NC}"
    echo "1. 📁 Upload your application files to /var/www/visionvideoke/"
    echo "2. 🔑 Update API keys in /var/www/visionvideoke/.env"
    echo "3. 🧪 Test your platform functionality"
    echo "4. 💳 Configure payment processing (Stripe)"
    echo ""
    echo -e "${YELLOW}Management Commands:${NC}"
    echo "• ./status.sh          - Check system status"
    echo "• ./update-app.sh      - Update application"
    echo "• ./backup.sh          - Create backup"
    echo "• pm2 logs             - View application logs"
    echo ""
    echo -e "${CYAN}Installation summary saved to: /home/ec2-user/installation-summary.txt${NC}"
    echo ""
    echo -e "${GREEN}Thank you for choosing Vision Videoke! 🎵🎬${NC}"
}

# Main installation flow
main() {
    welcome_message
    check_system
    collect_info
    download_installer
    run_system_setup
    setup_security
    setup_directories
    setup_nginx
    create_environment
    install_application
    setup_ssl
    setup_monitoring
    create_management_scripts
    final_setup
    show_success
}

# Run main installation
main "$@"

