#!/bin/bash

# =============================================================================
# PRODUCTION DEPLOYMENT SCRIPT FOR EC2
# =============================================================================
# This script sets up your BrixelApp for production deployment on EC2
# Run this script on your EC2 instance after initial setup

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

# 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 command exists
command_exists() {
    command -v "$1" >/dev/null 2>&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"
        exit 1
    fi
}

# Function to check prerequisites
check_prerequisites() {
    print_status "Checking prerequisites..."
    
    # Check if running on Ubuntu/Debian
    if ! command_exists apt-get; then
        print_error "This script is designed for Ubuntu/Debian systems"
        exit 1
    fi
    
    # Check if Docker is installed
    if ! command_exists docker; then
        print_error "Docker is not installed. Please install Docker first."
        exit 1
    fi
    
    # Check if Docker Compose is installed
    if ! command_exists docker-compose; then
        print_error "Docker Compose is not installed. Please install Docker Compose first."
        exit 1
    fi
    
    # Check if running as non-root user
    check_root
    
    print_success "Prerequisites check passed"
}

# Function to update system
update_system() {
    print_status "Updating system packages..."
    sudo apt-get update
    sudo apt-get upgrade -y
    print_success "System updated"
}

# Function to install additional packages
install_packages() {
    print_status "Installing required packages..."
    
    sudo apt-get install -y \
        curl \
        wget \
        git \
        certbot \
        python3-certbot-nginx \
        ufw \
        fail2ban \
        htop \
        nginx \
        unzip
    
    print_success "Packages installed"
}

# Function to configure firewall
configure_firewall() {
    print_status "Configuring firewall..."
    
    # Reset firewall
    sudo ufw --force reset
    
    # Set default policies
    sudo ufw default deny incoming
    sudo ufw default allow outgoing
    
    # Allow SSH
    sudo ufw allow ssh
    
    # Allow HTTP and HTTPS
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    
    # Enable firewall
    sudo ufw --force enable
    
    print_success "Firewall configured"
}

# Function to configure fail2ban
configure_fail2ban() {
    print_status "Configuring fail2ban..."
    
    # Create fail2ban configuration
    sudo tee /etc/fail2ban/jail.local > /dev/null <<EOF
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3

[nginx-http-auth]
enabled = true
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3
EOF
    
    # Restart fail2ban
    sudo systemctl restart fail2ban
    sudo systemctl enable fail2ban
    
    print_success "Fail2ban configured"
}

# Function to create application directory
create_app_directory() {
    print_status "Creating application directory..."
    
    # Create app directory
    sudo mkdir -p /opt/brixelapp
    sudo chown $USER:$USER /opt/brixelapp
    
    # Create necessary subdirectories
    mkdir -p /opt/brixelapp/{logs,uploads,ssl,mongo-init}
    
    print_success "Application directory created"
}

# Function to setup SSL certificates
setup_ssl() {
    print_status "Setting up SSL certificates..."
    
    # Check if domain is provided
    if [ -z "$DOMAIN" ]; then
        print_warning "No domain provided. SSL setup skipped."
        print_warning "You can set up SSL later with: sudo certbot --nginx -d yourdomain.com"
        return
    fi
    
    # Stop nginx if running
    sudo systemctl stop nginx 2>/dev/null || true
    
    # Create temporary nginx config for certbot
    sudo tee /etc/nginx/sites-available/brixelapp-temp > /dev/null <<EOF
server {
    listen 80;
    server_name $DOMAIN;
    
    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }
    
    location / {
        return 301 https://\$server_name\$request_uri;
    }
}
EOF
    
    # Enable site
    sudo ln -sf /etc/nginx/sites-available/brixelapp-temp /etc/nginx/sites-enabled/
    sudo rm -f /etc/nginx/sites-enabled/default
    
    # Start nginx
    sudo systemctl start nginx
    
    # Get SSL certificate
    sudo certbot --nginx -d $DOMAIN --non-interactive --agree-tos --email admin@$DOMAIN
    
    # Copy certificates to app directory
    sudo cp /etc/letsencrypt/live/$DOMAIN/fullchain.pem /opt/brixelapp/ssl/cert.pem
    sudo cp /etc/letsencrypt/live/$DOMAIN/privkey.pem /opt/brixelapp/ssl/key.pem
    sudo chown $USER:$USER /opt/brixelapp/ssl/*
    
    # Set up auto-renewal
    (crontab -l 2>/dev/null; echo "0 12 * * * /usr/bin/certbot renew --quiet") | crontab -
    
    print_success "SSL certificates configured"
}

# Function to generate secure secrets
generate_secrets() {
    print_status "Generating secure secrets..."
    
    # Generate session secret
    SESSION_SECRET=$(openssl rand -base64 64)
    
    # Generate JWT secret
    JWT_SECRET=$(openssl rand -base64 64)
    
    # Generate MongoDB password
    MONGO_PASSWORD=$(openssl rand -base64 32)
    
    # Generate Redis password
    REDIS_PASSWORD=$(openssl rand -base64 32)
    
    # Create .env.production file
    cat > /opt/brixelapp/.env.production <<EOF
# =============================================================================
# PRODUCTION ENVIRONMENT VARIABLES
# =============================================================================
# Generated automatically by deploy-production.sh
# Update these values with your actual API keys and configuration

# =============================================================================
# APPLICATION
# =============================================================================
NODE_ENV=production
PORT=8080

# =============================================================================
# DATABASE (MongoDB)
# =============================================================================
MONGO_ROOT_USERNAME=admin
MONGO_ROOT_PASSWORD=$MONGO_PASSWORD
MONGO_DATABASE=brixelapp
MONGODB_URI=mongodb://admin:$MONGO_PASSWORD@mongodb:27017/brixelapp?authSource=admin

# =============================================================================
# REDIS
# =============================================================================
REDIS_PASSWORD=$REDIS_PASSWORD
REDIS_URL=redis://:$REDIS_PASSWORD@redis:6379

# =============================================================================
# SESSION & AUTHENTICATION
# =============================================================================
SESSION_SECRET=$SESSION_SECRET
JWT_SECRET=$JWT_SECRET

# =============================================================================
# CORS & SECURITY
# =============================================================================
CORS_ORIGIN=https://$DOMAIN
FRONTEND_URL=https://$DOMAIN

# =============================================================================
# SUPABASE
# =============================================================================
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your_supabase_anon_key_here
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key_here

# =============================================================================
# OPENAI
# =============================================================================
OPENAI_API_KEY=sk-your_openai_api_key_here
OPENAI_MODEL=gpt-4
OPENAI_MAX_TOKENS=2000

# =============================================================================
# STRIPE
# =============================================================================
STRIPE_SECRET_KEY=sk_live_your_stripe_secret_key_here
STRIPE_WEBHOOK_SECRET=whsec_your_stripe_webhook_secret_here

# =============================================================================
# GOOGLE ANALYTICS
# =============================================================================
GA4_PROPERTY_ID=your_ga4_property_id_here
GA4_KEY_FILE=/path/to/your/service-account-key.json

# =============================================================================
# FILE UPLOADS
# =============================================================================
UPLOAD_DIR=/app/uploads
MAX_FILE_SIZE=10485760

# =============================================================================
# RATE LIMITING
# =============================================================================
RATE_LIMIT_WINDOW=900000
RATE_LIMIT_MAX=100

# =============================================================================
# LOGGING
# =============================================================================
LOG_LEVEL=info
LOG_FORMAT=json

# =============================================================================
# DOMAIN
# =============================================================================
DOMAIN=$DOMAIN
EOF
    
    print_success "Secure secrets generated"
    print_warning "IMPORTANT: Update the API keys in /opt/brixelapp/.env.production with your actual values"
}

# Function to deploy application
deploy_application() {
    print_status "Deploying application..."
    
    # Change to app directory
    cd /opt/brixelapp
    
    # Copy application files (assuming they're in the current directory)
    if [ -f "docker-compose.production.yml" ]; then
        cp docker-compose.production.yml .
    fi
    
    if [ -f "nginx.production.conf" ]; then
        cp nginx.production.conf .
    fi
    
    # Build and start containers
    docker-compose -f docker-compose.production.yml down 2>/dev/null || true
    docker-compose -f docker-compose.production.yml build --no-cache
    docker-compose -f docker-compose.production.yml up -d
    
    # Wait for containers to be healthy
    print_status "Waiting for containers to be healthy..."
    sleep 30
    
    # Check container status
    if docker-compose -f docker-compose.production.yml ps | grep -q "Up"; then
        print_success "Application deployed successfully"
    else
        print_error "Application deployment failed"
        docker-compose -f docker-compose.production.yml logs
        exit 1
    fi
}

# Function to setup monitoring
setup_monitoring() {
    print_status "Setting up monitoring..."
    
    # Create log rotation configuration
    sudo tee /etc/logrotate.d/brixelapp > /dev/null <<EOF
/opt/brixelapp/logs/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 644 $USER $USER
}
EOF
    
    # Create systemd service for auto-restart
    sudo tee /etc/systemd/system/brixelapp.service > /dev/null <<EOF
[Unit]
Description=BrixelApp Production
Requires=docker.service
After=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/brixelapp
ExecStart=/usr/local/bin/docker-compose -f docker-compose.production.yml up -d
ExecStop=/usr/local/bin/docker-compose -f docker-compose.production.yml down
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target
EOF
    
    # Enable and start service
    sudo systemctl daemon-reload
    sudo systemctl enable brixelapp
    
    print_success "Monitoring configured"
}

# Function to display final instructions
display_instructions() {
    print_success "Production deployment completed!"
    echo
    echo "Next steps:"
    echo "1. Update API keys in /opt/brixelapp/.env.production"
    echo "2. Restart the application: sudo systemctl restart brixelapp"
    echo "3. Check application status: sudo systemctl status brixelapp"
    echo "4. View logs: docker-compose -f /opt/brixelapp/docker-compose.production.yml logs -f"
    echo "5. Access your application at: https://$DOMAIN"
    echo
    echo "Security checklist:"
    echo "✅ Firewall configured"
    echo "✅ Fail2ban configured"
    echo "✅ SSL certificates installed"
    echo "✅ Secure secrets generated"
    echo "⚠️  Update API keys in .env.production"
    echo "⚠️  Configure backup strategy"
    echo "⚠️  Set up monitoring alerts"
}

# Main execution
main() {
    echo "============================================================================="
    echo "                    BRIXELAPP PRODUCTION DEPLOYMENT"
    echo "============================================================================="
    echo
    
    # Check if domain is provided
    if [ -z "$1" ]; then
        print_error "Usage: $0 <your-domain.com>"
        print_error "Example: $0 myapp.example.com"
        exit 1
    fi
    
    DOMAIN=$1
    
    print_status "Starting production deployment for domain: $DOMAIN"
    
    # Run deployment steps
    check_prerequisites
    update_system
    install_packages
    configure_firewall
    configure_fail2ban
    create_app_directory
    setup_ssl
    generate_secrets
    deploy_application
    setup_monitoring
    display_instructions
}

# Run main function with all arguments
main "$@" 