#!/bin/bash

# =======================================================
# APPY - Fully Automated Ubuntu 24.04 VPS Setup
# =======================================================
# This script provides complete automation for:
# - PHP 8.4 with all required extensions
# - MySQL 8.0 installation and configuration
# - Nginx with PHP-FPM
# - Node.js 20 LTS with PM2
# - Java 17 (OpenJDK)
# - Android SDK (API 35, Build Tools 35.0.0)
# - Laravel application deployment
# - Builder server setup
# - Let's Encrypt SSL certificate
# =======================================================

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

# Logging configuration
INSTALL_LOG="/home/install.log"
LOG_MAX_SIZE=10485760  # 10MB

# Configuration variables
APP_NAME="Appy"
APPY_DIR="/home/appy"
BUILDER_DIR="/home/appy-builder"
ANDROID_SDK_DIR="/opt/android-sdk"
DB_HOST="localhost"
DB_PORT="3306"
DB_NAME="appy"
BUILDER_PORT="8080"
DOMAIN=""
SITE_URL=""
ADMIN_EMAIL=""
PURCHASE_CODE=""

# Auto-generated credentials
MYSQL_ROOT_PASSWORD=""
DB_USERNAME=""
DB_PASSWORD=""
ADMIN_PASSWORD=""
BUILDER_KEY=""

# Domain handling variables
CANONICAL_DOMAIN=""
WWW_DOMAIN=""
DOMAIN_TYPE=""
NEEDS_WWW_REDIRECT=false

# Initialize logging system
setup_logging() {
    echo "========================================" > "$INSTALL_LOG"
    echo "APPY INSTALLATION LOG" >> "$INSTALL_LOG"
    echo "Started: $(date)" >> "$INSTALL_LOG"
    echo "Script: $0" >> "$INSTALL_LOG"
    echo "Arguments: $*" >> "$INSTALL_LOG"
    echo "========================================" >> "$INSTALL_LOG"
    echo "" >> "$INSTALL_LOG"

    if [[ -f "$INSTALL_LOG" ]] && [[ $(stat -c%s "$INSTALL_LOG" 2>/dev/null || stat -f%z "$INSTALL_LOG" 2>/dev/null || echo 0) -gt $LOG_MAX_SIZE ]]; then
        mv "$INSTALL_LOG" "${INSTALL_LOG}.old"
        setup_logging
        return
    fi

    echo -e "${BLUE}[INFO]${NC} Logging system initialized - output will be saved to $INSTALL_LOG"
}

# Log functions with dual output (console + file)
log_info() {
    local msg="$1"
    echo -e "${BLUE}[INFO]${NC} $msg"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [INFO] $msg" >> "$INSTALL_LOG"
}

log_success() {
    local msg="$1"
    echo -e "${GREEN}[SUCCESS]${NC} $msg"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [SUCCESS] $msg" >> "$INSTALL_LOG"
}

log_warning() {
    local msg="$1"
    echo -e "${YELLOW}[WARNING]${NC} $msg"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [WARNING] $msg" >> "$INSTALL_LOG"
}

log_error() {
    local msg="$1"
    echo -e "${RED}[ERROR]${NC} $msg"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR] $msg" >> "$INSTALL_LOG"
}

log_header() {
    echo -e "\n${CYAN}=================================${NC}"
    echo -e "${CYAN} $1 ${NC}"
    echo -e "${CYAN}=================================${NC}\n"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [HEADER] $1" >> "$INSTALL_LOG"
}

log_highlight() {
    echo -e "\n${MAGENTA}═══════════════════════════════════════════════════════════════════${NC}"
    echo -e "${MAGENTA}  $1  ${NC}"
    echo -e "${MAGENTA}═══════════════════════════════════════════════════════════════════${NC}\n"
}

log_wait() {
    local msg="$1"
    echo -e "${YELLOW}[WAIT]${NC} $msg - ${CYAN}Please wait, this may take a few minutes...${NC}"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [WAIT] $msg" >> "$INSTALL_LOG"
}

log_progress() {
    local msg="$1"
    echo -e "${BLUE}[PROGRESS]${NC} $msg"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [PROGRESS] $msg" >> "$INSTALL_LOG"
}

# Generate secure random password (alphanumeric only to avoid shell escaping issues)
generate_password() {
    local length=${1:-16}
    openssl rand -base64 48 | tr -dc 'a-zA-Z0-9' | head -c "$length"
}

# Generate secure random string for usernames
generate_username() {
    echo "appy_$(openssl rand -hex 4)"
}

# Auto-generate all credentials
generate_credentials() {
    log_header "GENERATING SECURE CREDENTIALS"

    MYSQL_ROOT_PASSWORD=$(generate_password 20)
    DB_PASSWORD=$(generate_password 16)
    ADMIN_PASSWORD=$(generate_password 12)
    DB_USERNAME=$(generate_username)
    BUILDER_KEY=$(openssl rand -hex 16)

    log_success "All credentials generated automatically"
    log_info "MySQL root password: 20 characters"
    log_info "Database password: 16 characters"
    log_info "Admin password: 12 characters"
    log_info "Builder server key: 32 characters"
    log_info "Database username: $DB_USERNAME"
}

# Validate and process domain input
validate_and_process_domain() {
    local input_domain="$1"

    input_domain=$(echo "$input_domain" | sed 's|^https\?://||' | sed 's|/.*||' | tr '[:upper:]' '[:lower:]')

    if [[ -z "$input_domain" ]]; then
        log_error "Domain name cannot be empty"
        return 1
    fi

    if [[ "$input_domain" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] ||
       [[ "$input_domain" =~ ^[0-9a-fA-F:]+:[0-9a-fA-F:]*$ ]]; then
        log_error "IP addresses are not allowed as domain names"
        log_info "SSL certificates require proper domain names, not IP addresses"
        log_info "Please use a domain name like: example.com or subdomain.example.com"
        return 1
    fi

    if [[ ! "$input_domain" =~ ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*\.[a-z]{2,}$ ]]; then
        log_error "Invalid domain format: $input_domain"
        log_info "Domain must be a valid format like: example.com or subdomain.example.com"
        return 1
    fi

    local dot_count=$(echo "$input_domain" | tr -cd '.' | wc -c)

    if [[ "$input_domain" =~ ^www\. ]]; then
        DOMAIN_TYPE="www_input"
        CANONICAL_DOMAIN="${input_domain#www.}"
        WWW_DOMAIN="$input_domain"
        NEEDS_WWW_REDIRECT=true
        log_info "WWW domain detected: $input_domain → canonical: $CANONICAL_DOMAIN"
    elif [[ $dot_count -eq 1 ]]; then
        DOMAIN_TYPE="root"
        CANONICAL_DOMAIN="$input_domain"
        WWW_DOMAIN="www.$input_domain"
        NEEDS_WWW_REDIRECT=true
        log_info "Root domain detected: $input_domain → will redirect www.$input_domain"
    else
        DOMAIN_TYPE="subdomain"
        CANONICAL_DOMAIN="$input_domain"
        WWW_DOMAIN=""
        NEEDS_WWW_REDIRECT=false
        log_info "Subdomain detected: $input_domain → no www redirect needed"
    fi

    DOMAIN="$CANONICAL_DOMAIN"
    return 0
}

# Get domain name from user
get_domain() {
    local input_domain

    echo ""
    echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "${MAGENTA}                                    DOMAIN SETUP REQUIRED${NC}"
    echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo ""
    echo -e "${CYAN}${BOLD}USER INPUT REQUIRED - PLEASE PROVIDE YOUR DOMAIN NAME${NC}"
    echo ""
    echo -e "${YELLOW}Please enter your domain name for SSL certificate:${NC}"
    echo -e "${YELLOW}This will be used to generate your SSL certificate via Let's Encrypt${NC}"
    echo -e "${GREEN}Examples: ${CYAN}example.com${NC} or ${CYAN}subdomain.example.com${NC}"
    echo -e "${RED}Note: IP addresses are not allowed${NC}"
    echo ""
    echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"

    while true; do
        echo -en "${CYAN}${BOLD}>>> Enter your domain name: ${NC}"
        read input_domain

        if validate_and_process_domain "$input_domain"; then
            break
        else
            echo ""
            log_warning "Please try again with a valid domain name"
            echo ""
        fi
    done

    SITE_URL="https://${CANONICAL_DOMAIN}"
    ADMIN_EMAIL="admin@${CANONICAL_DOMAIN}"

    echo ""
    log_success "Domain configuration:"
    log_info "  Primary URL: $SITE_URL"
    log_info "  Admin email: $ADMIN_EMAIL"
    if [[ "$NEEDS_WWW_REDIRECT" == "true" ]]; then
        log_info "  WWW redirect: https://$WWW_DOMAIN → https://$CANONICAL_DOMAIN"
    fi
    echo ""
}

# Get purchase code from user
get_purchase_code() {
    echo ""
    echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "${MAGENTA}                                  LICENSE VERIFICATION (OPTIONAL)${NC}"
    echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo ""
    echo -e "${YELLOW}Enter your CodeCanyon purchase code (or press Enter to skip):${NC}"
    echo -e "${GREEN}Example: ${CYAN}ABC123-DEF456-GHI789${NC}"
    echo ""
    echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -en "${CYAN}${BOLD}>>> Enter your purchase code: ${NC}"
    read PURCHASE_CODE

    if [[ -z "$PURCHASE_CODE" ]]; then
        log_info "Purchase code skipped - can be set later in admin panel"
    else
        log_success "Purchase code accepted: ${PURCHASE_CODE:0:10}..."
    fi
    echo ""
}

# Check if running as root
check_root() {
    if [[ $EUID -ne 0 ]]; then
        log_error "This script must be run as root"
        log_info "Please run: sudo ./autosetup.sh"
        exit 1
    fi
    log_info "Running as root user"
}

# Check available disk space
check_disk_space() {
    local required_gb=${1:-20}
    local available_kb=$(df / | awk 'NR==2 {print $4}')
    local available_gb=$((available_kb / 1024 / 1024))

    if [[ $available_gb -lt $required_gb ]]; then
        log_error "Insufficient disk space!"
        log_error "Required: ${required_gb}GB, Available: ${available_gb}GB"
        log_info "Android SDK alone requires ~10GB. Please free up space or use a larger disk."
        exit 1
    fi
    log_success "Disk space check passed: ${available_gb}GB available"
}

# Organize files from CodeCanyon ZIP structure
organize_uploaded_files() {
    log_header "ORGANIZING UPLOADED FILES"

    # Detect script location
    SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
    log_info "Script running from: $SCRIPT_DIR"

    # Check if running from /home/Install/ (CodeCanyon ZIP structure)
    if [[ "$SCRIPT_DIR" == "/home/Install" ]]; then
        log_info "Detected CodeCanyon ZIP structure in /home/"

        # Check if Laravel files are directly in /home/Install/ (artisan exists here)
        if [[ -f "/home/Install/artisan" ]] && [[ ! -d "$APPY_DIR" ]]; then
            log_progress "Moving Laravel app to $APPY_DIR..."
            mkdir -p "$APPY_DIR"
            # Move everything except the script itself
            for item in /home/Install/*; do
                if [[ "$(basename "$item")" != "autosetup.sh" ]]; then
                    mv "$item" "$APPY_DIR/"
                fi
            done
            # Also move hidden files like .env.example
            for item in /home/Install/.*; do
                if [[ "$(basename "$item")" != "." ]] && [[ "$(basename "$item")" != ".." ]]; then
                    mv "$item" "$APPY_DIR/" 2>/dev/null || true
                fi
            done
            log_success "Laravel app moved to $APPY_DIR"
        # Fallback: Check if appy/ subfolder exists (old structure)
        elif [[ -d "/home/Install/appy" ]] && [[ ! -d "$APPY_DIR" ]]; then
            log_progress "Moving Laravel app to $APPY_DIR..."
            mv /home/Install/appy "$APPY_DIR"
            log_success "Laravel app moved to $APPY_DIR"
        fi

        # Move Builder/prebuilt/ contents to /home/appy-builder/
        if [[ -d "/home/Builder/prebuilt" ]] && [[ ! -d "$BUILDER_DIR" ]]; then
            log_progress "Moving Builder to $BUILDER_DIR..."
            mv /home/Builder/prebuilt "$BUILDER_DIR"
            log_success "Builder moved to $BUILDER_DIR"
        fi
    else
        log_info "Files expected to be pre-organized in $APPY_DIR and $BUILDER_DIR"
    fi
}

# Verify uploaded files
verify_upload_structure() {
    log_header "VERIFYING UPLOADED FILES"

    if [[ ! -d "$APPY_DIR" ]] || [[ ! -f "$APPY_DIR/artisan" ]]; then
        log_error "Laravel application not found at $APPY_DIR"
        echo ""
        echo -e "${YELLOW}Please upload the CodeCanyon ZIP contents to /home/ via SFTP${NC}"
        echo -e "${CYAN}Expected structure after upload:${NC}"
        echo -e "  /home/"
        echo -e "    ├── Documentation/"
        echo -e "    ├── Install/"
        echo -e "    │   ├── app/"
        echo -e "    │   ├── config/"
        echo -e "    │   ├── artisan"
        echo -e "    │   ├── autosetup.sh"
        echo -e "    │   └── ..."
        echo -e "    └── Builder/"
        echo -e "        └── prebuilt/"
        echo ""
        echo -e "${CYAN}Then run: ${GREEN}bash /home/Install/autosetup.sh${NC}"
        exit 1
    fi

    if [[ ! -d "$BUILDER_DIR" ]] || [[ ! -f "$BUILDER_DIR/appy-builder-linux" ]]; then
        log_error "Builder server not found at $BUILDER_DIR"
        echo ""
        echo -e "${YELLOW}Please ensure Builder/prebuilt/ folder exists in /home/${NC}"
        echo -e "${CYAN}Expected structure:${NC}"
        echo -e "  /home/Builder/prebuilt/"
        echo -e "    ├── appy-builder-linux"
        echo -e "    ├── templates/"
        echo -e "    └── storage/"
        exit 1
    fi

    log_success "All required files found"
    log_info "  Laravel app: $APPY_DIR"
    log_info "  Builder: $BUILDER_DIR"
}

# Update system packages
update_system() {
    log_header "UPDATING SYSTEM PACKAGES"

    log_wait "Updating package repositories"
    export DEBIAN_FRONTEND=noninteractive
    apt update -y >/dev/null 2>&1

    log_wait "Upgrading system packages"
    apt upgrade -y >/dev/null 2>&1

    log_wait "Installing essential packages"
    apt install -y curl wget gnupg2 software-properties-common apt-transport-https ca-certificates git openssl unzip zip >/dev/null 2>&1

    log_success "System packages updated successfully"
}

# Install PHP 8.4
install_php() {
    log_header "INSTALLING PHP 8.4"

    log_wait "Adding PHP repository"
    add-apt-repository ppa:ondrej/php -y >/dev/null 2>&1
    apt update >/dev/null 2>&1

    log_wait "Installing PHP 8.4 and extensions"
    apt install -y \
        php8.4-fpm \
        php8.4-cli \
        php8.4-common \
        php8.4-bcmath \
        php8.4-curl \
        php8.4-dom \
        php8.4-fileinfo \
        php8.4-gd \
        php8.4-mbstring \
        php8.4-mysql \
        php8.4-xml \
        php8.4-zip \
        php8.4-tokenizer \
        php8.4-opcache \
        php8.4-intl >/dev/null 2>&1

    log_progress "Configuring PHP-FPM for production"
    PHP_INI="/etc/php/8.4/fpm/php.ini"
    sed -i 's/upload_max_filesize = .*/upload_max_filesize = 100M/' $PHP_INI
    sed -i 's/post_max_size = .*/post_max_size = 100M/' $PHP_INI
    sed -i 's/memory_limit = .*/memory_limit = 256M/' $PHP_INI
    sed -i 's/max_execution_time = .*/max_execution_time = 120/' $PHP_INI

    systemctl restart php8.4-fpm
    systemctl enable php8.4-fpm

    PHP_VERSION=$(php -v | head -n 1)
    log_success "PHP installed: $PHP_VERSION"
}

# Install MySQL 8.0
install_mysql() {
    log_header "INSTALLING MYSQL 8.0"

    log_wait "Installing MySQL server and client"
    apt install -y mysql-server mysql-client >/dev/null 2>&1

    log_progress "Starting MySQL service"
    systemctl start mysql
    systemctl enable mysql

    log_wait "Securing MySQL installation"
    sleep 5

    # Set root password (try without password first for fresh installs, then with password for existing)
    if ! mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '$MYSQL_ROOT_PASSWORD';" 2>/dev/null; then
        log_error "Failed to set MySQL root password"
        exit 1
    fi

    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "DELETE FROM mysql.user WHERE User='';"
    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');"
    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "DROP DATABASE IF EXISTS test;"
    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';"
    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "FLUSH PRIVILEGES;"

    log_success "MySQL 8.0 installed and secured"
}

# Create database and user
create_database() {
    log_header "CREATING APPY DATABASE"

    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "CREATE DATABASE IF NOT EXISTS $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "CREATE USER IF NOT EXISTS '$DB_USERNAME'@'localhost' IDENTIFIED BY '$DB_PASSWORD';"
    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USERNAME'@'localhost';"
    mysql -u root -p"$MYSQL_ROOT_PASSWORD" -e "FLUSH PRIVILEGES;"

    if mysql -u "$DB_USERNAME" -p"$DB_PASSWORD" -e "USE $DB_NAME; SELECT 1;" >/dev/null 2>&1; then
        log_success "Database '$DB_NAME' created successfully"
        log_success "User '$DB_USERNAME' created with full privileges"
    else
        log_error "Failed to create database or user"
        exit 1
    fi
}

# Install Nginx
install_nginx() {
    log_header "INSTALLING NGINX"

    log_wait "Installing Nginx web server"
    apt install -y nginx >/dev/null 2>&1

    systemctl start nginx
    systemctl enable nginx

    # Create Nginx configuration for Laravel
    if [[ "$NEEDS_WWW_REDIRECT" == "true" ]]; then
        cat > "/etc/nginx/sites-available/$CANONICAL_DOMAIN" <<EOF
# WWW to Non-WWW Redirect
server {
    listen 80;
    server_name $WWW_DOMAIN;
    return 301 http://$CANONICAL_DOMAIN\$request_uri;
}

# Main Laravel Application
server {
    listen 80;
    server_name $CANONICAL_DOMAIN;
    root $APPY_DIR/public;
    index index.php index.html;

    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    client_max_body_size 100M;

    location / {
        try_files \$uri \$uri/ /index.php?\$query_string;
    }

    location ~ \.php\$ {
        fastcgi_pass unix:/var/run/php/php8.4-fpm.sock;
        fastcgi_param SCRIPT_FILENAME \$realpath_root\$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_hide_header X-Powered-By;
    }

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

    location ~ /\.(?!well-known).* {
        deny all;
    }

    location ~ \.(env|log|bak|config|sql|fla|psd|ini|sh|inc|swp|dist)\$ {
        deny all;
        return 404;
    }

    location /adminer {
        alias /var/www/html/adminer.php;
        fastcgi_pass unix:/var/run/php/php8.4-fpm.sock;
        fastcgi_index adminer.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /var/www/html/adminer.php;
    }
}
EOF
    else
        cat > "/etc/nginx/sites-available/$CANONICAL_DOMAIN" <<EOF
server {
    listen 80;
    server_name $CANONICAL_DOMAIN;
    root $APPY_DIR/public;
    index index.php index.html;

    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    client_max_body_size 100M;

    location / {
        try_files \$uri \$uri/ /index.php?\$query_string;
    }

    location ~ \.php\$ {
        fastcgi_pass unix:/var/run/php/php8.4-fpm.sock;
        fastcgi_param SCRIPT_FILENAME \$realpath_root\$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_hide_header X-Powered-By;
    }

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

    location ~ /\.(?!well-known).* {
        deny all;
    }

    location ~ \.(env|log|bak|config|sql|fla|psd|ini|sh|inc|swp|dist)\$ {
        deny all;
        return 404;
    }

    location /adminer {
        alias /var/www/html/adminer.php;
        fastcgi_pass unix:/var/run/php/php8.4-fpm.sock;
        fastcgi_index adminer.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /var/www/html/adminer.php;
    }
}
EOF
    fi

    ln -sf "/etc/nginx/sites-available/$CANONICAL_DOMAIN" /etc/nginx/sites-enabled/
    rm -f /etc/nginx/sites-enabled/default

    log_progress "Testing Nginx configuration"
    if ! nginx -t 2>/dev/null; then
        log_error "Nginx configuration test failed"
        nginx -t
        exit 1
    fi
    systemctl reload nginx

    log_success "Nginx installed and configured for $CANONICAL_DOMAIN"
}

# Install SSL certificate
install_ssl() {
    log_header "INSTALLING SSL CERTIFICATE"

    apt install -y certbot python3-certbot-nginx >/dev/null 2>&1

    SERVER_IP=$(curl -s -4 ifconfig.me || curl -s -4 ipecho.net/plain || echo "Unable to detect IP")

    echo ""
    echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "${MAGENTA}                                    DNS CONFIGURATION REQUIRED${NC}"
    echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo ""
    echo -e "${CYAN}${BOLD}USER ACTION REQUIRED - CONFIGURE DNS BEFORE CONTINUING${NC}"
    echo ""
    if [[ "$NEEDS_WWW_REDIRECT" == "true" ]]; then
        echo -e "${YELLOW}IMPORTANT: Make sure both domains point to this server's IP!${NC}"
        echo -e "${GREEN}Required DNS Records:${NC}"
        echo -e "  ${CYAN}$CANONICAL_DOMAIN ${GREEN}→ ${CYAN}$SERVER_IP${NC}"
        echo -e "  ${CYAN}$WWW_DOMAIN ${GREEN}→ ${CYAN}$SERVER_IP${NC}"
    else
        echo -e "${YELLOW}IMPORTANT: Make sure your domain points to this server's IP!${NC}"
        echo -e "${GREEN}Required DNS Record: ${CYAN}$CANONICAL_DOMAIN ${GREEN}→ ${CYAN}$SERVER_IP${NC}"
    fi
    echo ""
    echo -e "${YELLOW}You can verify DNS propagation with:${NC}"
    echo -e "  • Online tool: ${CYAN}https://dnschecker.org${NC}"
    echo ""
    echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -en "${CYAN}${BOLD}>>> Press Enter when DNS is configured and ready: ${NC}"
    read

    log_info "Verifying domain resolution..."

    if [[ "$NEEDS_WWW_REDIRECT" == "true" ]]; then
        log_info "Obtaining SSL certificate for $CANONICAL_DOMAIN and $WWW_DOMAIN..."
        if certbot --nginx -d "$CANONICAL_DOMAIN" -d "$WWW_DOMAIN" --non-interactive --agree-tos --email "$ADMIN_EMAIL" --redirect; then
            log_success "SSL certificate installed for both domains"
        else
            log_error "Failed to obtain SSL certificate"
            log_warning "Continuing without SSL - you can set it up manually later"
        fi
    else
        log_info "Obtaining SSL certificate for $CANONICAL_DOMAIN..."
        if certbot --nginx -d "$CANONICAL_DOMAIN" --non-interactive --agree-tos --email "$ADMIN_EMAIL" --redirect; then
            log_success "SSL certificate installed for $CANONICAL_DOMAIN"
        else
            log_error "Failed to obtain SSL certificate"
            log_warning "Continuing without SSL - you can set it up manually later"
        fi
    fi

    systemctl enable certbot.timer
    systemctl start certbot.timer

    log_success "SSL setup completed"
}

# Install Adminer database manager
install_adminer() {
    log_header "INSTALLING ADMINER DATABASE MANAGER"

    log_wait "Downloading Adminer"
    curl -sL https://github.com/vrana/adminer/releases/download/v5.4.1/adminer-5.4.1-mysql-en.php -o /var/www/html/adminer.php

    chown www-data:www-data /var/www/html/adminer.php
    chmod 644 /var/www/html/adminer.php

    log_success "Adminer installed - access at http://$CANONICAL_DOMAIN/adminer"
}

# Install Node.js and PM2
install_nodejs() {
    log_header "INSTALLING NODE.JS 20 LTS"

    log_wait "Adding NodeSource repository"
    curl -fsSL https://deb.nodesource.com/setup_20.x | bash - >/dev/null 2>&1

    log_wait "Installing Node.js"
    apt install -y nodejs >/dev/null 2>&1

    NODE_VERSION=$(node --version)
    NPM_VERSION=$(npm --version)

    log_success "Node.js installed: $NODE_VERSION"
    log_success "npm installed: $NPM_VERSION"

    log_wait "Installing PM2 process manager"
    npm install -g pm2 >/dev/null 2>&1

    log_success "PM2 installed globally"
}

# Install Java 17
install_java() {
    log_header "INSTALLING JAVA 17"

    log_wait "Installing OpenJDK 17"
    apt install -y openjdk-17-jdk >/dev/null 2>&1

    # Set environment variables
    cat > /etc/profile.d/java.sh <<'EOF'
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export PATH=$PATH:$JAVA_HOME/bin
EOF
    chmod +x /etc/profile.d/java.sh

    # Add to root's bashrc and profile (per documentation pattern)
    if ! grep -q "JAVA_HOME" /root/.bashrc 2>/dev/null; then
        echo "" >> /root/.bashrc
        echo "# Java environment variables" >> /root/.bashrc
        echo "source /etc/profile.d/java.sh" >> /root/.bashrc
    fi

    if ! grep -q "JAVA_HOME" /root/.profile 2>/dev/null; then
        echo "" >> /root/.profile
        echo "# Java environment variables" >> /root/.profile
        echo "source /etc/profile.d/java.sh" >> /root/.profile
    fi

    source /etc/profile.d/java.sh

    JAVA_VERSION=$(java -version 2>&1 | head -n 1)
    log_success "Java installed: $JAVA_VERSION"
}

# Install Android SDK
install_android_sdk() {
    log_header "INSTALLING ANDROID SDK"

    mkdir -p $ANDROID_SDK_DIR/cmdline-tools
    cd $ANDROID_SDK_DIR/cmdline-tools || { log_error "Failed to enter $ANDROID_SDK_DIR/cmdline-tools"; exit 1; }

    log_wait "Downloading Android command-line tools"
    if ! wget -q https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip -O cmdline-tools.zip; then
        log_error "Failed to download Android command-line tools"
        exit 1
    fi

    log_progress "Extracting command-line tools"
    if ! unzip -q cmdline-tools.zip; then
        log_error "Failed to extract Android command-line tools"
        exit 1
    fi
    mv cmdline-tools latest
    rm -f cmdline-tools.zip

    # Set environment variables
    cat > /etc/profile.d/android.sh <<EOF
export ANDROID_HOME=$ANDROID_SDK_DIR
export PATH=\$PATH:\$ANDROID_HOME/cmdline-tools/latest/bin:\$ANDROID_HOME/platform-tools
EOF
    chmod +x /etc/profile.d/android.sh

    # Add to root's bashrc and profile (per documentation pattern)
    if ! grep -q "ANDROID_HOME" /root/.bashrc 2>/dev/null; then
        echo "" >> /root/.bashrc
        echo "# Android SDK environment variables" >> /root/.bashrc
        echo "source /etc/profile.d/android.sh" >> /root/.bashrc
    fi

    if ! grep -q "ANDROID_HOME" /root/.profile 2>/dev/null; then
        echo "" >> /root/.profile
        echo "# Android SDK environment variables" >> /root/.profile
        echo "source /etc/profile.d/android.sh" >> /root/.profile
    fi

    source /etc/profile.d/android.sh

    export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
    export ANDROID_HOME=$ANDROID_SDK_DIR
    export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools

    log_wait "Accepting Android SDK licenses"
    yes | $ANDROID_SDK_DIR/cmdline-tools/latest/bin/sdkmanager --licenses >/dev/null 2>&1

    log_wait "Installing SDK components (platform-tools, android-35, build-tools-35.0.0)"
    $ANDROID_SDK_DIR/cmdline-tools/latest/bin/sdkmanager \
        "platform-tools" \
        "platforms;android-35" \
        "build-tools;35.0.0" >/dev/null 2>&1

    log_success "Android SDK installed successfully"
}

# Setup Laravel application
setup_laravel() {
    log_header "SETTING UP LARAVEL APPLICATION"

    cd $APPY_DIR || { log_error "Failed to enter $APPY_DIR"; exit 1; }

    log_progress "Creating .env configuration file"
    cat > $APPY_DIR/.env <<EOF
APP_NAME="$APP_NAME"
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_DEMO=false
APP_TIMEZONE=UTC
APP_URL=$SITE_URL

DB_CONNECTION=mysql
DB_HOST=$DB_HOST
DB_PORT=$DB_PORT
DB_DATABASE=$DB_NAME
DB_USERNAME=$DB_USERNAME
DB_PASSWORD=$DB_PASSWORD

SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=true
QUEUE_CONNECTION=sync

CACHE_STORE=database
FILESYSTEM_DISK=local
EOF

    log_progress "Setting file permissions"
    chown -R www-data:www-data $APPY_DIR
    find $APPY_DIR -type d -exec chmod 755 {} \;
    find $APPY_DIR -type f -exec chmod 644 {} \;
    chmod +x $APPY_DIR/artisan
    chmod -R 775 $APPY_DIR/storage
    chmod -R 775 $APPY_DIR/bootstrap/cache

    log_progress "Generating application key"
    php artisan key:generate --force

    log_progress "Clearing configuration cache"
    php artisan config:clear

    log_wait "Running database migrations"
    if ! php artisan migrate --force; then
        log_error "Database migration failed"
        exit 1
    fi

    log_wait "Running database seeders"
    php artisan db:seed --class=PlanSeeder --force
    php artisan db:seed --class=SystemSettingSeeder --force
    php artisan db:seed --class=PlatformPluginsSeeder --force
    php artisan db:seed --class=LanguageSeeder --force
    php artisan db:seed --class=EmailTemplateSeeder --force
    php artisan db:seed --class=PaymentGatewayPluginsSeeder --force

    log_progress "Creating admin user"
    php artisan tinker --execute="
        \$plan = \App\Models\Plan::orderBy('price')->first();
        \App\Models\User::create([
            'name' => 'Administrator',
            'email' => '$ADMIN_EMAIL',
            'password' => bcrypt('$ADMIN_PASSWORD'),
            'role' => 'admin',
            'status' => 'active',
            'plan_id' => \$plan?->id,
            'build_credits' => \$plan?->monthly_build_credits ?? 100,
            'email_verified_at' => now(),
        ]);
    " >/dev/null 2>&1

    log_progress "Marking installation as completed"
    php artisan tinker --execute="
        \App\Models\SystemSetting::set('installation_completed', true, 'boolean', 'app');
        \App\Models\SystemSetting::set('site_name', '$APP_NAME', 'string', 'general');
        \App\Models\SystemSetting::set('purchase_code', '$PURCHASE_CODE', 'string', 'general');
    " >/dev/null 2>&1

    log_progress "Creating storage symlink"
    php artisan storage:link

    log_progress "Publishing Livewire assets"
    php artisan livewire:publish --assets

    log_progress "Optimizing Laravel for production"
    php artisan config:cache
    php artisan route:cache
    php artisan view:cache

    log_success "Laravel application setup completed"
}

# Setup Builder server
setup_builder() {
    log_header "SETTING UP BUILDER SERVER"

    cd $BUILDER_DIR || { log_error "Failed to enter $BUILDER_DIR"; exit 1; }

    chmod +x appy-builder-linux
    mkdir -p storage
    mkdir -p templates

    log_progress "Loading environment variables for PM2"
    source /root/.bashrc

    log_wait "Starting builder server with PM2"

    pm2 start ./appy-builder-linux \
        --name "appy-builder" \
        -- \
        --key="$BUILDER_KEY" \
        --site-url="$SITE_URL" \
        --port="$BUILDER_PORT"

    pm2 save
    pm2 startup systemd -u root --hp /root >/dev/null 2>&1

    log_success "Builder server started on port $BUILDER_PORT"
}

# Register builder in database
register_builder() {
    log_header "REGISTERING BUILDER IN DATABASE"

    cd $APPY_DIR || { log_error "Failed to enter $APPY_DIR"; exit 1; }

    php artisan tinker --execute="
        use App\Models\AppBuilder;
        use App\Services\PluginManager;

        \$pluginManager = app(PluginManager::class);
        \$allPlatformIds = \$pluginManager->getActivePlatforms()
            ->map(fn (\$p) => \$p->getPlatformId())
            ->values()
            ->toArray();

        AppBuilder::firstOrCreate(
            ['url' => 'http://127.0.0.1', 'port' => $BUILDER_PORT],
            [
                'name' => 'Local Builder',
                'url' => 'http://127.0.0.1',
                'port' => $BUILDER_PORT,
                'server_key' => '$BUILDER_KEY',
                'max_queue' => 5,
                'platforms' => \$allPlatformIds,
                'status' => 'active',
                'credit_cost' => 1,
            ]
        );
    " >/dev/null 2>&1

    log_success "Builder registered in database"
}

# Configure firewall
configure_firewall() {
    log_header "CONFIGURING FIREWALL"

    apt install -y ufw >/dev/null 2>&1

    ufw default deny incoming
    ufw default allow outgoing
    ufw allow ssh
    ufw allow 'Nginx Full'

    ufw --force enable

    log_success "Firewall configured"
}

# Verify installation
verify_installation() {
    log_header "VERIFYING INSTALLATION"

    if systemctl is-active --quiet nginx; then
        log_success "Nginx is running"
    else
        log_warning "Nginx is not running"
    fi

    if systemctl is-active --quiet php8.4-fpm; then
        log_success "PHP-FPM is running"
    else
        log_warning "PHP-FPM is not running"
    fi

    if systemctl is-active --quiet mysql; then
        log_success "MySQL is running"
    else
        log_warning "MySQL is not running"
    fi

    if pm2 list | grep -q "appy-builder.*online"; then
        log_success "Builder server is running"
    else
        log_warning "Builder server is not running"
    fi

    if [[ -f "/etc/letsencrypt/live/$CANONICAL_DOMAIN/fullchain.pem" ]]; then
        log_success "SSL certificate installed"
    else
        log_warning "SSL certificate not found"
    fi
}

# Display final information
show_final_info() {
    log_highlight "APPY INSTALLATION COMPLETED!"

    echo -e "${GREEN}Your Appy platform is now live!${NC}\n"

    echo -e "${YELLOW}ACCESS YOUR PLATFORM:${NC}"
    echo -e "  Website: ${CYAN}$SITE_URL${NC}"
    echo ""

    echo -e "${YELLOW}ADMIN LOGIN:${NC}"
    echo -e "  URL: ${CYAN}$SITE_URL/login${NC}"
    echo -e "  Email: ${ADMIN_EMAIL}"
    echo -e "  Password: ${ADMIN_PASSWORD}"
    echo ""

    echo -e "${YELLOW}DATABASE CREDENTIALS:${NC}"
    echo -e "  Host: ${DB_HOST}"
    echo -e "  Database: ${DB_NAME}"
    echo -e "  Username: ${DB_USERNAME}"
    echo -e "  Password: ${DB_PASSWORD}"
    echo -e "  MySQL Root: ${MYSQL_ROOT_PASSWORD}"
    echo ""

    echo -e "${YELLOW}BUILDER SERVER:${NC}"
    echo -e "  URL: http://127.0.0.1:${BUILDER_PORT}"
    echo -e "  Server Key: ${BUILDER_KEY}"
    echo ""

    echo -e "${YELLOW}SSL CERTIFICATE:${NC}"
    echo -e "  Status: ${GREEN}Active${NC}"
    echo -e "  Auto-renewal: ${GREEN}Enabled${NC}"
    echo -e "  Check: ${CYAN}sudo certbot certificates${NC}"
    echo ""

    echo -e "${YELLOW}DATABASE MANAGER:${NC}"
    echo -e "  Adminer: ${CYAN}https://$CANONICAL_DOMAIN/adminer${NC}"
    echo -e "  Username: ${CYAN}$DB_USERNAME${NC}"
    echo -e "  Password: ${CYAN}(see Database Credentials above)${NC}"
    echo ""

    echo -e "${YELLOW}PROCESS MANAGEMENT:${NC}"
    echo -e "  Status: ${CYAN}pm2 status${NC}"
    echo -e "  Logs: ${CYAN}pm2 logs appy-builder${NC}"
    echo -e "  Restart: ${CYAN}pm2 restart appy-builder${NC}"
    echo ""

    echo -e "${YELLOW}ENVIRONMENT VARIABLES:${NC}"
    echo -e "  Java: ${CYAN}source /etc/profile.d/java.sh${NC}"
    echo -e "  Android SDK: ${CYAN}source /etc/profile.d/android.sh${NC}"
    echo ""

    echo -e "${YELLOW}INSTALLATION PATHS:${NC}"
    echo -e "  Laravel App: ${CYAN}$APPY_DIR${NC}"
    echo -e "  Builder: ${CYAN}$BUILDER_DIR${NC}"
    echo -e "  Install Log: ${CYAN}$INSTALL_LOG${NC}"
    echo ""

    echo -e "${RED}IMPORTANT: Save these credentials now!${NC}"
}

# Show help
show_help() {
    echo ""
    echo -e "${CYAN}Appy - Fully Automated VPS Setup with SSL${NC}"
    echo ""
    echo -e "${YELLOW}Usage:${NC}"
    echo "  ./autosetup.sh [--domain yourdomain.com] [--purchase-code YOUR-CODE]"
    echo ""
    echo -e "${YELLOW}Prerequisites:${NC}"
    echo "  1. Fresh Ubuntu 24.04 LTS VPS"
    echo "  2. Upload CodeCanyon ZIP contents to /home/ (Install/, Builder/, Documentation/)"
    echo "  3. Domain name pointed to server IP"
    echo ""
    echo -e "${YELLOW}What gets installed:${NC}"
    echo "  • PHP 8.4 with all Laravel extensions"
    echo "  • MySQL 8.0 Database Server"
    echo "  • Nginx Web Server with PHP-FPM"
    echo "  • Node.js 20 LTS with PM2"
    echo "  • Java 17 (OpenJDK)"
    echo "  • Android SDK (API 35, Build Tools 35.0.0)"
    echo "  • Let's Encrypt SSL Certificate"
    echo "  • Adminer Database Manager"
    echo ""
    echo -e "${YELLOW}Auto-generated credentials:${NC}"
    echo "  • MySQL root password"
    echo "  • Database user and password"
    echo "  • Admin password"
    echo "  • Builder server key"
    echo ""
}

# Parse command line arguments
parse_arguments() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            --domain)
                if validate_and_process_domain "$2"; then
                    SITE_URL="https://${CANONICAL_DOMAIN}"
                    ADMIN_EMAIL="admin@${CANONICAL_DOMAIN}"
                    shift 2
                else
                    log_error "Invalid domain provided: $2"
                    exit 1
                fi
                ;;
            --purchase-code)
                PURCHASE_CODE="$2"
                shift 2
                ;;
            --help|-h)
                show_help
                exit 0
                ;;
            *)
                log_error "Unknown option: $1"
                show_help
                exit 1
                ;;
        esac
    done
}

# Main execution
main() {
    setup_logging "$@"

    log_highlight "APPY - AUTOMATED VPS SETUP"

    parse_arguments "$@"
    check_root
    check_disk_space 20
    organize_uploaded_files
    verify_upload_structure
    generate_credentials

    if [[ -z "$DOMAIN" ]]; then
        get_domain
    fi

    if [[ -z "$PURCHASE_CODE" ]]; then
        get_purchase_code
    fi

    echo ""
    echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "${MAGENTA}                                  READY TO BEGIN INSTALLATION${NC}"
    echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo ""
    echo -e "${YELLOW}Setup Preview:${NC}"
    echo -e "${GREEN}  Domain: ${CYAN}$CANONICAL_DOMAIN${NC}"
    echo -e "${GREEN}  Site URL: ${CYAN}$SITE_URL${NC}"
    echo -e "${GREEN}  Admin Email: ${CYAN}$ADMIN_EMAIL${NC}"
    echo -e "${GREEN}  SSL: ${CYAN}Let's Encrypt (auto-renewal enabled)${NC}"
    echo -e "${GREEN}  Passwords: ${CYAN}Auto-generated securely${NC}"
    echo ""
    echo -e "${YELLOW}This will install:${NC}"
    echo -e "${CYAN}  • PHP 8.4 + Extensions${NC}"
    echo -e "${CYAN}  • MySQL 8.0${NC}"
    echo -e "${CYAN}  • Nginx + PHP-FPM${NC}"
    echo -e "${CYAN}  • Node.js 20 + PM2${NC}"
    echo -e "${CYAN}  • Java 17 (OpenJDK)${NC}"
    echo -e "${CYAN}  • Android SDK (API 35)${NC}"
    echo -e "${CYAN}  • SSL Certificate${NC}"
    echo ""
    echo -e "${MAGENTA}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -en "${CYAN}${BOLD}>>> Continue with automated setup? (y/N): ${NC}"
    read -n 1 -r REPLY
    echo ""

    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        echo ""
        log_warning "Setup cancelled by user"
        exit 0
    fi

    echo ""
    log_success "Installation confirmed! Starting automated setup..."
    echo ""

    update_system
    install_php
    install_mysql
    create_database
    install_nginx
    install_ssl
    install_adminer
    install_nodejs
    install_java
    install_android_sdk
    setup_laravel
    setup_builder
    register_builder
    configure_firewall
    verify_installation

    show_final_info

    log_success "Full automation setup completed!"

    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [SUCCESS] Setup completed successfully - exiting" >> "$INSTALL_LOG"
    exit 0
}

main "$@"
