#!/bin/bash

# PropTrader Pro Server Setup Script
# This script sets up a fresh server for PropTrader Pro deployment

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="PropTrader Pro"
APP_USER="deployer"
APP_DIR="/var/www/proptrader-pro"
DB_NAME="proptrader_pro"
DB_USER="proptrader"
REDIS_PASSWORD=$(openssl rand -base64 32)

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

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

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

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

# Check if running as root
check_root() {
    if [[ $EUID -ne 0 ]]; then
        error "This script must be run as root"
    fi
}

# Update system packages
update_system() {
    log "Updating system packages..."
    
    apt update && apt upgrade -y
    
    # Install essential packages
    apt install -y curl wget git unzip zip build-essential \
        software-properties-common apt-transport-https \
        ca-certificates gnupg lsb-release htop \
        ufw fail2ban unattended-upgrades
    
    log "System packages updated"
}

# Configure firewall
setup_firewall() {
    log "Setting up firewall..."
    
    # Configure UFW
    ufw default deny incoming
    ufw default allow outgoing
    ufw allow ssh
    ufw allow 80/tcp
    ufw allow 443/tcp
    
    # Enable firewall
    ufw --force enable
    
    log "Firewall configured"
}

# Install PHP
install_php() {
    log "Installing PHP 8.2..."
    
    # Add PHP PPA
    add-apt-repository -y ppa:ondrej/php
    apt update
    
    # Install PHP and extensions
    apt install -y php8.2 php8.2-fpm php8.2-cli \
        php8.2-mysql php8.2-redis php8.2-mbstring \
        php8.2-xml php8.2-curl php8.2-zip \
        php8.2-gd php8.2-intl php8.2-bcmath \
        php8.2-json php8.2-opcache php8.2-tokenizer \
        php8.2-soap php8.2-xmlrpc
    
    # Configure PHP
    sed -i 's/memory_limit = .*/memory_limit = 512M/' /etc/php/8.2/fpm/php.ini
    sed -i 's/max_execution_time = .*/max_execution_time = 300/' /etc/php/8.2/fpm/php.ini
    sed -i 's/upload_max_filesize = .*/upload_max_filesize = 50M/' /etc/php/8.2/fpm/php.ini
    sed -i 's/post_max_size = .*/post_max_size = 50M/' /etc/php/8.2/fpm/php.ini
    
    # Configure OPcache
    sed -i 's/opcache.enable = .*/opcache.enable = 1/' /etc/php/8.2/fpm/php.ini
    sed -i 's/opcache.memory_consumption = .*/opcache.memory_consumption = 128/' /etc/php/8.2/fpm/php.ini
    sed -i 's/opcache.max_accelerated_files = .*/opcache.max_accelerated_files = 4000/' /etc/php/8.2/fpm/php.ini
    
    # Restart PHP-FPM
    systemctl restart php8.2-fpm
    systemctl enable php8.2-fpm
    
    log "PHP 8.2 installed and configured"
}

# Install Nginx
install_nginx() {
    log "Installing Nginx..."
    
    apt install -y nginx
    
    # Create Nginx configuration
    cat > /etc/nginx/sites-available/proptrader-pro << 'EOF'
server {
    listen 80;
    server_name _;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name _;

    root /var/www/proptrader-pro/public;
    index index.php index.html;

    # SSL Configuration (to be updated with actual certificates)
    ssl_certificate /etc/ssl/certs/proptrader-pro.crt;
    ssl_certificate_key /etc/ssl/private/proptrader-pro.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # Security Headers
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

    # Gzip Compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;

    # PHP-FPM Configuration
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_read_timeout 300;
    }

    # Laravel Configuration
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # Static Assets
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # Security
    location ~ /\.ht {
        deny all;
    }
}
EOF

    # Enable site
    ln -s /etc/nginx/sites-available/proptrader-pro /etc/nginx/sites-enabled/
    rm -f /etc/nginx/sites-enabled/default
    
    # Test and restart Nginx
    nginx -t
    systemctl restart nginx
    systemctl enable nginx
    
    log "Nginx installed and configured"
}

# Install MySQL
install_mysql() {
    log "Installing MySQL..."
    
    # Install MySQL
    apt install -y mysql-server
    
    # Secure MySQL installation
    mysql -e "
        ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'SecureRootPassword123!';
        DELETE FROM mysql.user WHERE User='';
        DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
        DROP DATABASE IF EXISTS test;
        DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
        FLUSH PRIVILEGES;
    "
    
    # Create database and user
    mysql -e "
        CREATE DATABASE $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
        CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY 'SecureDbPassword123!';
        GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost';
        FLUSH PRIVILEGES;
    "
    
    # Configure MySQL
    cat > /etc/mysql/mysql.conf.d/mysqld.cnf << 'EOF'
[mysqld]
innodb_buffer_pool_size = 2G
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
query_cache_size = 64M
query_cache_type = 1
max_connections = 200
thread_cache_size = 50
table_open_cache = 4000
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
EOF
    
    systemctl restart mysql
    systemctl enable mysql
    
    log "MySQL installed and configured"
}

# Install Redis
install_redis() {
    log "Installing Redis..."
    
    apt install -y redis-server
    
    # Configure Redis
    sed -i "s/^bind .*/bind 127.0.0.1/" /etc/redis/redis.conf
    sed -i "s/^# requirepass .*/requirepass $REDIS_PASSWORD/" /etc/redis/redis.conf
    sed -i "s/^maxmemory .*/maxmemory 1gb/" /etc/redis/redis.conf
    sed -i "s/^maxmemory-policy .*/maxmemory-policy allkeys-lru/" /etc/redis/redis.conf
    
    systemctl restart redis-server
    systemctl enable redis-server
    
    log "Redis installed and configured"
}

# Install Node.js
install_nodejs() {
    log "Installing Node.js..."
    
    # Install Node.js 18 LTS
    curl -fsSL https://deb.nodesource.com/setup_18.x | bash -
    apt-get install -y nodejs
    
    # Install Yarn
    npm install -g yarn
    
    log "Node.js 18 LTS installed"
}

# Install Composer
install_composer() {
    log "Installing Composer..."
    
    # Download and install Composer
    php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
    php composer-setup.php --install-dir=/usr/local/bin --filename=composer
    php -r "unlink('composer-setup.php');"
    
    log "Composer installed"
}

# Create application user
create_app_user() {
    log "Creating application user..."
    
    # Create user
    adduser --disabled-password --gecos "" $APP_USER
    
    # Add user to www-data group
    usermod -a -G www-data $APP_USER
    
    # Create SSH directory
    mkdir -p /home/$APP_USER/.ssh
    chmod 700 /home/$APP_USER/.ssh
    chown $APP_USER:$APP_USER /home/$APP_USER/.ssh
    
    log "Application user created: $APP_USER"
}

# Create application directory
create_app_directory() {
    log "Creating application directory..."
    
    # Create directory
    mkdir -p $APP_DIR
    
    # Set ownership
    chown $APP_USER:www-data $APP_DIR
    chmod 775 $APP_DIR
    
    log "Application directory created: $APP_DIR"
}

# Install SSL certificate (Let's Encrypt)
install_ssl() {
    log "Installing SSL certificate..."
    
    # Install Certbot
    apt install -y certbot python3-certbot-nginx
    
    # Note: SSL certificate will be obtained after domain is pointed to this server
    warning "SSL certificate will be obtained after domain is configured"
    
    log "Certbot installed for SSL certificates"
}

# Setup backup directory
setup_backup_directory() {
    log "Setting up backup directory..."
    
    # Create backup directory
    mkdir -p /var/backups/proptrader-pro
    
    # Create backup scripts
    cat > /usr/local/bin/backup-database.sh << EOF
#!/bin/bash
DATE=\$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/var/backups/proptrader-pro"
DB_NAME="$DB_NAME"
DB_USER="$DB_USER"
DB_PASS="SecureDbPassword123!"

mkdir -p \$BACKUP_DIR

# Create backup
mysqldump -u \$DB_USER -p\$DB_PASS \$DB_NAME | gzip > \$BACKUP_DIR/db_backup_\$DATE.sql.gz

# Keep only last 7 days
find \$BACKUP_DIR -name "db_backup_*.sql.gz" -mtime +7 -delete

echo "Database backup completed: \$BACKUP_DIR/db_backup_\$DATE.sql.gz"
EOF

    cat > /usr/local/bin/backup-application.sh << EOF
#!/bin/bash
DATE=\$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/var/backups/proptrader-pro"
APP_DIR="$APP_DIR"

mkdir -p \$BACKUP_DIR

# Create application backup
tar -czf \$BACKUP_DIR/app_backup_\$DATE.tar.gz -C \$APP_DIR .

# Keep only last 7 days
find \$BACKUP_DIR -name "app_backup_*.tar.gz" -mtime +7 -delete

echo "Application backup completed: \$BACKUP_DIR/app_backup_\$DATE.tar.gz"
EOF

    # Make scripts executable
    chmod +x /usr/local/bin/backup-database.sh
    chmod +x /usr/local/bin/backup-application.sh
    
    # Setup cron jobs
    (crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/backup-database.sh") | crontab -
    (crontab -l 2>/dev/null; echo "0 3 * * 0 /usr/local/bin/backup-application.sh") | crontab -
    
    log "Backup directory and scripts configured"
}

# Setup monitoring
setup_monitoring() {
    log "Setting up monitoring..."
    
    # Install monitoring tools
    apt install -y prometheus grafana
    
    # Configure Prometheus
    cat > /etc/prometheus/prometheus.yml << 'EOF'
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'proptrader-pro'
    static_configs:
      - targets: ['localhost:9090']
    metrics_path: '/metrics'
EOF

    # Start monitoring services
    systemctl enable prometheus
    systemctl start prometheus
    systemctl enable grafana-server
    systemctl start grafana-server
    
    log "Monitoring setup completed"
}

# Setup log rotation
setup_log_rotation() {
    log "Setting up log rotation..."
    
    cat > /etc/logrotate.d/proptrader-pro << 'EOF'
/var/www/proptrader-pro/storage/logs/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 644 www-data www-data
    postrotate
        systemctl reload php8.2-fpm
    endscript
}
EOF

    log "Log rotation configured"
}

# Setup security
setup_security() {
    log "Setting up security..."
    
    # Configure fail2ban
    cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3

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

[nginx-http-auth]
enabled = true
filter = nginx-http-auth
logpath = /var/log/nginx/error.log

[nginx-limit-req]
enabled = true
filter = nginx-limit-req
logpath = /var/log/nginx/error.log
EOF

    systemctl restart fail2ban
    systemctl enable fail2ban
    
    # Configure unattended-upgrades
    cat > /etc/apt/apt.conf.d/50unattended-upgrades << 'EOF'
Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}";
    "${distro_id}:${distro_codename}-security";
};
Unattended-Upgrade::Automatic-Reboot "false";
EOF

    echo 'APT::Periodic::Update-Package-Lists "1";' > /etc/apt/apt.conf.d/20auto-upgrades
    echo 'APT::Periodic::Unattended-Upgrade "1";' >> /etc/apt/apt.conf.d/20auto-upgrades
    echo 'APT::Periodic::AutocleanInterval "7";' >> /etc/apt/apt.conf.d/20auto-upgrades
    
    systemctl enable unattended-upgrades
    
    log "Security setup completed"
}

# Display setup summary
display_summary() {
    log "Server setup completed!"
    
    echo ""
    echo "=== Setup Summary ==="
    echo "Application Name: $APP_NAME"
    echo "Application Directory: $APP_DIR"
    echo "Application User: $APP_USER"
    echo "Database Name: $DB_NAME"
    echo "Database User: $DB_USER"
    echo "Redis Password: $REDIS_PASSWORD"
    echo ""
    echo "=== Important Information ==="
    echo "1. Add your domain to DNS pointing to this server"
    echo "2. Run: certbot --nginx -d yourdomain.com to obtain SSL certificate"
    echo "3. Update .env file with your application settings"
    echo "4. Run deployment script: ./scripts/deploy.sh"
    echo ""
    echo "=== Services Status ==="
    systemctl status nginx | grep Active
    systemctl status php8.2-fpm | grep Active
    systemctl status mysql | grep Active
    systemctl status redis-server | grep Active
    echo ""
    echo "=== Next Steps ==="
    echo "1. Clone your application repository"
    echo "2. Configure environment variables"
    echo "3. Run deployment script"
    echo "4. Configure monitoring and alerts"
}

# Main function
main() {
    log "Starting server setup for $APP_NAME..."
    
    check_root
    update_system
    setup_firewall
    install_php
    install_nginx
    install_mysql
    install_redis
    install_nodejs
    install_composer
    create_app_user
    create_app_directory
    install_ssl
    setup_backup_directory
    setup_monitoring
    setup_log_rotation
    setup_security
    
    display_summary
    
    log "Server setup completed successfully!"
}

# Run main function
main
