#!/bin/bash

# EC2 Deployment Script for Orbit App
# This script sets up and deploys the application on an EC2 instance

set -e  # Exit on any error

echo "🚀 Starting EC2 deployment for Orbit App..."

# 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="orbit-app"
DOMAIN="your-domain.com"  # Replace with your domain
EMAIL="your-email@example.com"  # Replace with your email

echo -e "${BLUE}📋 Configuration:${NC}"
echo "App Name: $APP_NAME"
echo "Domain: $DOMAIN"
echo "Email: $EMAIL"

# Update system
echo -e "${YELLOW}🔄 Updating system packages...${NC}"
sudo apt update && sudo apt upgrade -y

# Install Docker and Docker Compose
echo -e "${YELLOW}🐳 Installing Docker and Docker Compose...${NC}"
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common

# Add Docker's official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Add Docker repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Install Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io

# Install Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

# Add current user to docker group
sudo usermod -aG docker $USER

# Install Nginx
echo -e "${YELLOW}🌐 Installing Nginx...${NC}"
sudo apt install -y nginx

# Install Certbot for SSL
echo -e "${YELLOW}🔒 Installing Certbot for SSL certificates...${NC}"
sudo apt install -y certbot python3-certbot-nginx

# Create application directory
echo -e "${YELLOW}📁 Creating application directory...${NC}"
sudo mkdir -p /opt/$APP_NAME
sudo chown $USER:$USER /opt/$APP_NAME

# Clone or copy application files
echo -e "${YELLOW}📂 Setting up application files...${NC}"
cd /opt/$APP_NAME

# If you're copying files from your local machine, use scp:
# scp -r /path/to/your/app/* ubuntu@your-ec2-ip:/opt/$APP_NAME/

# Or if you're using Git:
# git clone https://github.com/your-username/your-repo.git .

# Create production environment file
echo -e "${YELLOW}⚙️ Creating production environment file...${NC}"
cat > .env.production << EOF
# Database Configuration
DATABASE_URL=mongodb://admin:your_secure_mongodb_password@mongodb:27017/orbitapp?authSource=admin
DATABASE_TYPE=mongodb

# MongoDB Configuration (for Docker)
MONGO_ROOT_USERNAME=admin
MONGO_ROOT_PASSWORD=your_secure_mongodb_password_here

# OpenAI Configuration
OPENAI_API_KEY=your_openai_api_key_here
OPENAI_MODEL=gpt-4
OPENAI_MAX_TOKENS=2000

# Server Configuration
PORT=8080
NODE_ENV=production

# Session Configuration
SESSION_SECRET=your_very_long_random_session_secret_here_min_32_chars

# CORS Configuration
CORS_ORIGIN=https://$DOMAIN

# Logging Configuration
LOG_LEVEL=info
LOG_FORMAT=json

# File Upload Configuration
UPLOAD_MAX_FILE_SIZE=10485760
UPLOAD_ALLOWED_TYPES=.pdf,.png,.jpg,.jpeg,.gif,.txt,.md,.json,.csv

# Supabase Configuration
VITE_SUPABASE_URL=your_supabase_project_url
VITE_SUPABASE_ANON_KEY=your_supabase_anon_key_here
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key_here

# Stripe Configuration (for payments)
STRIPE_SECRET_KEY=your_stripe_secret_key_here
STRIPE_WEBHOOK_SECRET=whsec_your_stripe_webhook_secret_here

# Google Analytics 4 Configuration
VITE_GA4_MEASUREMENT_ID=G-XXXXXXXXXX

# Frontend URL
FRONTEND_URL=https://$DOMAIN
EOF

# Create production docker-compose file
echo -e "${YELLOW}🐳 Creating production Docker Compose configuration...${NC}"
cat > docker-compose.prod.yml << EOF
version: '3.8'

services:
  # MongoDB Database
  mongodb:
    image: mongo:7.0
    container_name: ${APP_NAME}-mongodb
    environment:
      MONGO_INITDB_DATABASE: orbitapp
      MONGO_INITDB_ROOT_USERNAME: \${MONGO_ROOT_USERNAME}
      MONGO_INITDB_ROOT_PASSWORD: \${MONGO_ROOT_PASSWORD}
    volumes:
      - mongodb_data:/data/db
    healthcheck:
      test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - ${APP_NAME}-network
    restart: unless-stopped

  # Redis for session storage
  redis:
    image: redis:7-alpine
    container_name: ${APP_NAME}-redis
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - ${APP_NAME}-network
    restart: unless-stopped

  # Main Application
  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: ${APP_NAME}-app
    env_file:
      - .env.production
    environment:
      # Database
      DATABASE_URL: mongodb://\${MONGO_ROOT_USERNAME}:\${MONGO_ROOT_PASSWORD}@mongodb:27017/orbitapp?authSource=admin
      DATABASE_TYPE: mongodb
      
      # Server
      NODE_ENV: production
      PORT: 8080
      
      # CORS
      CORS_ORIGIN: https://$DOMAIN
      
      # Frontend URL
      FRONTEND_URL: https://$DOMAIN
    ports:
      - "127.0.0.1:8080:8080"
    volumes:
      - uploads_data:/app/uploads
    depends_on:
      mongodb:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - ${APP_NAME}-network
    restart: unless-stopped

volumes:
  mongodb_data:
    driver: local
  redis_data:
    driver: local
  uploads_data:
    driver: local

networks:
  ${APP_NAME}-network:
    driver: bridge
EOF

# Create Nginx configuration
echo -e "${YELLOW}🌐 Creating Nginx configuration...${NC}"
sudo tee /etc/nginx/sites-available/$APP_NAME > /dev/null << EOF
server {
    listen 80;
    server_name $DOMAIN www.$DOMAIN;

    # Redirect HTTP to HTTPS
    return 301 https://\$server_name\$request_uri;
}

server {
    listen 443 ssl http2;
    server_name $DOMAIN www.$DOMAIN;

    # SSL configuration will be added by Certbot

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;

    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_proxied expired no-cache no-store private must-revalidate auth;
    gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/javascript;

    # Client max body size for file uploads
    client_max_body_size 10M;

    # Proxy to application
    location / {
        proxy_pass http://127.0.0.1:8080;
        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;
        proxy_read_timeout 86400;
    }

    # Health check endpoint
    location /health {
        proxy_pass http://127.0.0.1:8080/api/health;
        access_log off;
    }
}
EOF

# Enable the site
sudo ln -sf /etc/nginx/sites-available/$APP_NAME /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default

# Test Nginx configuration
sudo nginx -t

# Reload Nginx
sudo systemctl reload nginx

# Build and start the application
echo -e "${YELLOW}🔨 Building and starting the application...${NC}"
docker-compose -f docker-compose.prod.yml build
docker-compose -f docker-compose.prod.yml up -d

# Wait for application to start
echo -e "${YELLOW}⏳ Waiting for application to start...${NC}"
sleep 30

# Check application health
echo -e "${YELLOW}🏥 Checking application health...${NC}"
if curl -f http://127.0.0.1:8080/api/health > /dev/null 2>&1; then
    echo -e "${GREEN}✅ Application is healthy!${NC}"
else
    echo -e "${RED}❌ Application health check failed${NC}"
    docker-compose -f docker-compose.prod.yml logs app
    exit 1
fi

# Setup SSL certificate (only if domain is configured)
if [ "$DOMAIN" != "your-domain.com" ]; then
    echo -e "${YELLOW}🔒 Setting up SSL certificate...${NC}"
    sudo certbot --nginx -d $DOMAIN -d www.$DOMAIN --non-interactive --agree-tos --email $EMAIL
    
    # Setup automatic renewal
    (crontab -l 2>/dev/null; echo "0 12 * * * /usr/bin/certbot renew --quiet") | crontab -
fi

# Setup log rotation
echo -e "${YELLOW}📝 Setting up log rotation...${NC}"
sudo tee /etc/logrotate.d/$APP_NAME > /dev/null << EOF
/opt/$APP_NAME/logs/*.log {
    daily
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 644 $USER $USER
    postrotate
        docker-compose -f /opt/$APP_NAME/docker-compose.prod.yml restart app
    endscript
}
EOF

# Create systemd service for auto-start
echo -e "${YELLOW}🔧 Creating systemd service...${NC}"
sudo tee /etc/systemd/system/$APP_NAME.service > /dev/null << EOF
[Unit]
Description=Orbit App
Requires=docker.service
After=docker.service

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

[Install]
WantedBy=multi-user.target
EOF

# Enable and start the service
sudo systemctl enable $APP_NAME
sudo systemctl start $APP_NAME

# Setup firewall
echo -e "${YELLOW}🔥 Setting up firewall...${NC}"
sudo ufw allow ssh
sudo ufw allow 'Nginx Full'
sudo ufw --force enable

# Create backup script
echo -e "${YELLOW}💾 Creating backup script...${NC}"
cat > backup.sh << 'EOF'
#!/bin/bash
# Backup script for Orbit App

BACKUP_DIR="/opt/backups"
DATE=$(date +%Y%m%d_%H%M%S)
APP_DIR="/opt/orbit-app"

# Create backup directory
mkdir -p $BACKUP_DIR

# Backup MongoDB data
docker exec orbit-app-mongodb mongodump --out /tmp/backup
docker cp orbit-app-mongodb:/tmp/backup $BACKUP_DIR/mongodb_backup_$DATE

# Backup uploads
tar -czf $BACKUP_DIR/uploads_backup_$DATE.tar.gz -C $APP_DIR uploads/

# Backup environment file
cp $APP_DIR/.env.production $BACKUP_DIR/env_backup_$DATE

# Clean old backups (keep last 7 days)
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete
find $BACKUP_DIR -name "mongodb_backup_*" -mtime +7 -exec rm -rf {} \;
find $BACKUP_DIR -name "env_backup_*" -mtime +7 -delete

echo "Backup completed: $BACKUP_DIR"
EOF

chmod +x backup.sh

# Setup daily backup cron job
(crontab -l 2>/dev/null; echo "0 2 * * * /opt/$APP_NAME/backup.sh") | crontab -

echo -e "${GREEN}🎉 Deployment completed successfully!${NC}"
echo -e "${BLUE}📋 Next steps:${NC}"
echo "1. Update .env.production with your real API keys"
echo "2. Configure your domain DNS to point to this server"
echo "3. Run: sudo certbot --nginx -d your-domain.com"
echo "4. Test your application at: https://$DOMAIN"
echo ""
echo -e "${BLUE}🔧 Useful commands:${NC}"
echo "View logs: docker-compose -f docker-compose.prod.yml logs -f"
echo "Restart app: docker-compose -f docker-compose.prod.yml restart"
echo "Update app: git pull && docker-compose -f docker-compose.prod.yml up -d --build"
echo "Backup: ./backup.sh" 