#!/bin/bash

# Interactive Setup Wizard for Custom PHP Framework Deployment
# Provides step-by-step guided configuration for production-ready deployments
# Domain: michaelschiemer.de | Email: kontakt@michaelschiemer.de | PHP: 8.4

set -euo pipefail

# Script configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../" && pwd)"
DEPLOYMENT_DIR="${SCRIPT_DIR}"

# Configuration state
CURRENT_STEP=1
TOTAL_STEPS=8
ENVIRONMENT=""
DOMAIN=""
EMAIL=""
SERVER_IP=""
SSH_KEY_PATH=""

# Configuration storage
declare -A CONFIG_VALUES
declare -A PASSWORD_STORE

# 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'
WHITE='\033[1;37m'
NC='\033[0m'

# Enhanced logging functions
log() { echo -e "${GREEN}[$(date +'%H:%M:%S')] ✅ $1${NC}"; }
warn() { echo -e "${YELLOW}[$(date +'%H:%M:%S')] ⚠️  $1${NC}"; }
error() { echo -e "${RED}[$(date +'%H:%M:%S')] ❌ $1${NC}"; }
info() { echo -e "${BLUE}[$(date +'%H:%M:%S')] ℹ️  $1${NC}"; }
success() { echo -e "${WHITE}[$(date +'%H:%M:%S')] 🎉 $1${NC}"; }

# Progress indicator
show_progress() {
    local step=$1
    local total=$2
    local description="$3"
    
    local progress=$((step * 100 / total))
    local bars=$((progress / 5))
    local spaces=$((20 - bars))
    
    printf "\n${PURPLE}[Step %d/%d] ${WHITE}%s${NC}\n" "$step" "$total" "$description"
    printf "${CYAN}Progress: [${GREEN}"
    printf "█%.0s" $(seq 1 $bars)
    printf "${CYAN}"
    printf "░%.0s" $(seq 1 $spaces)
    printf "${CYAN}] %d%%${NC}\n\n" "$progress"
}

# Welcome screen
show_welcome() {
    clear
    cat << 'EOF'

███████╗███████╗████████╗██╗   ██╗██████╗ 
██╔════╝██╔════╝╚══██╔══╝██║   ██║██╔══██╗
███████╗█████╗     ██║   ██║   ██║██████╔╝
╚════██║██╔══╝     ██║   ██║   ██║██╔═══╝ 
███████║███████╗   ██║   ╚██████╔╝██║     
╚══════╝╚══════╝   ╚═╝    ╚═════╝ ╚═╝     

EOF
    cat << EOF
${WHITE}Custom PHP Framework Deployment Setup Wizard${NC}
${CYAN}Domain: michaelschiemer.de | Email: kontakt@michaelschiemer.de | PHP: 8.4${NC}

${GREEN}This wizard will guide you through setting up a production-ready deployment:${NC}

✅ Environment configuration with secure defaults
✅ Automatic password generation and validation
✅ SSH key setup and server connectivity testing
✅ SSL/TLS certificate configuration
✅ Docker and Ansible integration
✅ Complete deployment validation

${YELLOW}Prerequisites:${NC} Internet connection, sudo access (if needed)
${YELLOW}Time Required:${NC} 10-15 minutes
${YELLOW}What You'll Need:${NC} Server details and domain information

${WHITE}Press Enter to start, or Ctrl+C to exit...${NC}
EOF
    read -r
}

# Step 1: Environment Selection
step_environment_selection() {
    show_progress $CURRENT_STEP $TOTAL_STEPS "Environment Selection"
    
    cat << EOF
${WHITE}Select Deployment Environment${NC}

${CYAN}Available environments:${NC}
1) ${GREEN}Development${NC} - Local development with debug enabled
2) ${YELLOW}Staging${NC}    - Pre-production testing environment
3) ${RED}Production${NC}  - Live production environment (recommended)

${WHITE}Which environment would you like to configure?${NC}
EOF
    
    while true; do
        printf "${CYAN}Enter choice (1-3): ${NC}"
        read -r choice
        
        case $choice in
            1)
                ENVIRONMENT="development"
                DOMAIN="dev.michaelschiemer.de"
                info "Selected: Development environment"
                break
                ;;
            2)
                ENVIRONMENT="staging"
                DOMAIN="staging.michaelschiemer.de"
                info "Selected: Staging environment"
                break
                ;;
            3)
                ENVIRONMENT="production"
                DOMAIN="michaelschiemer.de"
                info "Selected: Production environment"
                break
                ;;
            *)
                error "Invalid choice. Please enter 1, 2, or 3."
                ;;
        esac
    done
    
    CONFIG_VALUES[ENVIRONMENT]=$ENVIRONMENT
    CONFIG_VALUES[DOMAIN]=$DOMAIN
}

# Step 2: Domain and Contact Configuration
step_domain_configuration() {
    show_progress $CURRENT_STEP $TOTAL_STEPS "Domain and Contact Information"
    
    cat << EOF
${WHITE}Domain and Contact Configuration${NC}

Current settings:
• Environment: ${GREEN}${ENVIRONMENT}${NC}
• Suggested domain: ${GREEN}${DOMAIN}${NC}
• Contact email: ${GREEN}kontakt@michaelschiemer.de${NC}
EOF
    
    printf "\n${CYAN}Is this domain correct? [Y/n]: ${NC}"
    read -r confirm
    
    if [[ $confirm =~ ^[Nn]$ ]]; then
        printf "${CYAN}Enter your domain name: ${NC}"
        read -r custom_domain
        if [[ -n "$custom_domain" ]]; then
            DOMAIN="$custom_domain"
            CONFIG_VALUES[DOMAIN]="$custom_domain"
            info "Domain updated to: $custom_domain"
        fi
    fi
    
    EMAIL="kontakt@michaelschiemer.de"
    printf "${CYAN}Contact email for SSL certificates [${EMAIL}]: ${NC}"
    read -r custom_email
    if [[ -n "$custom_email" ]]; then
        EMAIL="$custom_email"
    fi
    
    CONFIG_VALUES[EMAIL]=$EMAIL
    success "Domain configuration completed"
}

# Step 3: Server Configuration
step_server_configuration() {
    show_progress $CURRENT_STEP $TOTAL_STEPS "Server Configuration"
    
    cat << EOF
${WHITE}Server Configuration${NC}

Enter your deployment server details:
EOF
    
    while true; do
        printf "${CYAN}Server IP address or hostname: ${NC}"
        read -r server_ip
        
        if [[ -n "$server_ip" ]]; then
            if [[ $server_ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] || [[ $server_ip =~ ^[a-zA-Z0-9.-]+$ ]]; then
                SERVER_IP="$server_ip"
                CONFIG_VALUES[SERVER_IP]="$server_ip"
                break
            else
                error "Invalid IP address or hostname format"
            fi
        else
            error "Server IP/hostname is required"
        fi
    done
    
    printf "${CYAN}SSH username [root]: ${NC}"
    read -r ssh_user
    ssh_user=${ssh_user:-root}
    CONFIG_VALUES[SSH_USER]="$ssh_user"
    
    printf "${CYAN}SSH port [22]: ${NC}"
    read -r ssh_port
    ssh_port=${ssh_port:-22}
    CONFIG_VALUES[SSH_PORT]="$ssh_port"
    
    info "Server: ${ssh_user}@${SERVER_IP}:${ssh_port}"
    success "Server configuration completed"
}

# Step 4: SSH Key Setup
step_ssh_key_setup() {
    show_progress $CURRENT_STEP $TOTAL_STEPS "SSH Key Configuration"
    
    cat << EOF
${WHITE}SSH Key Setup${NC}

We need SSH access to your server for deployment.
EOF
    
    local default_key="$HOME/.ssh/production"
    printf "${CYAN}SSH private key path [${default_key}]: ${NC}"
    read -r key_path
    SSH_KEY_PATH=${key_path:-$default_key}
    
    if [[ ! -f "$SSH_KEY_PATH" ]]; then
        warn "SSH key not found: $SSH_KEY_PATH"
        printf "${CYAN}Generate new SSH key pair? [Y/n]: ${NC}"
        read -r generate_key
        
        if [[ ! $generate_key =~ ^[Nn]$ ]]; then
            info "Generating SSH key pair..."
            
            mkdir -p "$(dirname "$SSH_KEY_PATH")"
            ssh-keygen -t ed25519 -C "deploy@${DOMAIN}" -f "$SSH_KEY_PATH" -N ""
            
            success "SSH key pair generated:"
            info "Private key: $SSH_KEY_PATH"
            info "Public key: ${SSH_KEY_PATH}.pub"
            
            cat << EOF

${YELLOW}📋 COPY THIS PUBLIC KEY TO YOUR SERVER:${NC}

$(cat "${SSH_KEY_PATH}.pub")

${YELLOW}Add this key to ~/.ssh/authorized_keys on your server.${NC}

EOF
            printf "${CYAN}Press Enter when you've added the key to your server...${NC}"
            read -r
        fi
    else
        success "Found existing SSH key: $SSH_KEY_PATH"
    fi
    
    CONFIG_VALUES[SSH_KEY_PATH]="$SSH_KEY_PATH"
}

# Step 5: Test Server Connectivity
step_test_connectivity() {
    show_progress $CURRENT_STEP $TOTAL_STEPS "Server Connectivity Test"
    
    cat << EOF
${WHITE}Testing Server Connectivity${NC}

Testing SSH connection to ${CONFIG_VALUES[SSH_USER]}@${CONFIG_VALUES[SERVER_IP]}...
EOF
    
    if ssh -i "$SSH_KEY_PATH" -p "${CONFIG_VALUES[SSH_PORT]}" \
           -o ConnectTimeout=10 -o BatchMode=yes \
           "${CONFIG_VALUES[SSH_USER]}@${CONFIG_VALUES[SERVER_IP]}" \
           "echo 'Connection successful'" 2>/dev/null; then
        success "SSH connection test passed"
        
        info "Testing server requirements..."
        local server_info
        server_info=$(ssh -i "$SSH_KEY_PATH" -p "${CONFIG_VALUES[SSH_PORT]}" \
                          "${CONFIG_VALUES[SSH_USER]}@${CONFIG_VALUES[SERVER_IP]}" \
                          "uname -a && free -h && df -h /" 2>/dev/null)
        
        echo -e "${BLUE}Server Information:${NC}"
        echo "$server_info"
        
    else
        error "SSH connection failed"
        cat << EOF

${YELLOW}Troubleshooting tips:${NC}
1. Verify the server IP and SSH port
2. Ensure your SSH public key is in ~/.ssh/authorized_keys on the server
3. Check if SSH service is running on the server
4. Verify firewall allows SSH connections

EOF
        printf "${CYAN}Continue anyway? [y/N]: ${NC}"
        read -r continue_anyway
        if [[ ! $continue_anyway =~ ^[Yy]$ ]]; then
            error "Setup cancelled due to connectivity issues"
            exit 1
        fi
    fi
}

# Step 6: Secure Password Generation
step_password_generation() {
    show_progress $CURRENT_STEP $TOTAL_STEPS "Secure Credential Generation"
    
    cat << EOF
${WHITE}Generating Secure Credentials${NC}

Creating secure passwords and keys for your deployment...
EOF
    
    if ! command -v openssl >/dev/null 2>&1; then
        error "OpenSSL not found. Please install OpenSSL first."
        exit 1
    fi
    
    info "Generating database passwords..."
    PASSWORD_STORE[DB_PASSWORD]=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25)
    PASSWORD_STORE[DB_ROOT_PASSWORD]=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25)
    
    info "Generating Redis password..."
    PASSWORD_STORE[REDIS_PASSWORD]=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25)
    
    info "Generating application key..."
    PASSWORD_STORE[APP_KEY]=$(openssl rand -base64 32)
    
    if [[ "$ENVIRONMENT" == "production" ]]; then
        info "Generating monitoring passwords..."
        PASSWORD_STORE[GRAFANA_ADMIN_PASSWORD]=$(openssl rand -base64 16 | tr -d "=+/" | cut -c1-16)
    fi
    
    success "All credentials generated securely"
    
    # Show password strength
    cat << EOF

${CYAN}Password Strength Summary:${NC}
• Database passwords: 25 characters, alphanumeric
• Redis password: 25 characters, alphanumeric
• Application key: 32 characters, base64 encoded
• All passwords cryptographically secure
EOF
}

# Step 7: Configuration File Creation
step_create_configuration() {
    show_progress $CURRENT_STEP $TOTAL_STEPS "Configuration File Creation"
    
    cat << EOF
${WHITE}Creating Configuration Files${NC}

Building environment configuration for ${ENVIRONMENT}...
EOF
    
    local env_file="${DEPLOYMENT_DIR}/applications/environments/.env.${ENVIRONMENT}"
    local template_file="${env_file}.template"
    
    if [[ ! -f "$template_file" ]]; then
        error "Template file not found: $template_file"
        exit 1
    fi
    
    info "Creating .env.${ENVIRONMENT} from template..."
    cp "$template_file" "$env_file"
    
    # Apply configurations
    info "Applying domain and email settings..."
    sed -i "s|DOMAIN_NAME=.*|DOMAIN_NAME=${CONFIG_VALUES[DOMAIN]}|g" "$env_file"
    sed -i "s|MAIL_FROM_ADDRESS=.*|MAIL_FROM_ADDRESS=${CONFIG_VALUES[EMAIL]}|g" "$env_file"
    
    # Apply generated passwords
    info "Applying secure credentials..."
    for key in "${!PASSWORD_STORE[@]}"; do
        local value="${PASSWORD_STORE[$key]}"
        sed -i "s|${key}=\*\*\* REQUIRED \*\*\*|${key}=${value}|g" "$env_file"
        sed -i "s|${key}=changeme|${key}=${value}|g" "$env_file"
    done
    
    # Environment-specific settings
    if [[ "$ENVIRONMENT" == "production" ]]; then
        sed -i 's|APP_DEBUG=.*|APP_DEBUG=false|g' "$env_file"
        sed -i 's|LOG_LEVEL=.*|LOG_LEVEL=warning|g' "$env_file"
    fi
    
    # Set secure permissions
    chmod 600 "$env_file"
    
    success "Configuration file created: $env_file"
    
    # Update Ansible inventory
    info "Updating Ansible inventory..."
    local inventory_file="${DEPLOYMENT_DIR}/infrastructure/inventories/${ENVIRONMENT}/hosts.yml"
    
    if [[ -f "$inventory_file" ]]; then
        # Backup original
        cp "$inventory_file" "${inventory_file}.backup"
        
        # Update server details
        sed -i "s|ansible_host:.*|ansible_host: ${CONFIG_VALUES[SERVER_IP]}|g" "$inventory_file"
        sed -i "s|ansible_user:.*|ansible_user: ${CONFIG_VALUES[SSH_USER]}|g" "$inventory_file"
        sed -i "s|ansible_port:.*|ansible_port: ${CONFIG_VALUES[SSH_PORT]}|g" "$inventory_file"
        sed -i "s|ansible_ssh_private_key_file:.*|ansible_ssh_private_key_file: ${CONFIG_VALUES[SSH_KEY_PATH]}|g" "$inventory_file"
        
        success "Ansible inventory updated: $inventory_file"
    else
        warn "Ansible inventory not found: $inventory_file"
    fi
}

# Step 8: Final Validation and Summary
step_final_validation() {
    show_progress $CURRENT_STEP $TOTAL_STEPS "Final Validation"
    
    cat << EOF
${WHITE}Final Validation and Summary${NC}

Running configuration validation...
EOF
    
    # Validate configuration
    local env_file="${DEPLOYMENT_DIR}/applications/environments/.env.${ENVIRONMENT}"
    
    info "Validating environment configuration..."
    if grep -q "\*\*\* REQUIRED \*\*\*" "$env_file" 2>/dev/null; then
        error "Some required fields are still unfilled:"
        grep "\*\*\* REQUIRED \*\*\*" "$env_file"
        exit 1
    fi
    
    success "All required fields are configured"
    
    # Test Docker Compose configuration
    info "Validating Docker Compose configuration..."
    cd "$PROJECT_ROOT"
    if docker-compose -f docker-compose.yml -f "deployment/applications/docker-compose.${ENVIRONMENT}.yml" config >/dev/null 2>&1; then
        success "Docker Compose configuration is valid"
    else
        warn "Docker Compose validation failed - may need manual review"
    fi
    
    # Show summary
    cat << EOF

${WHITE}🎉 SETUP WIZARD COMPLETED SUCCESSFULLY! 🎉${NC}

${CYAN}Configuration Summary:${NC}
• Environment: ${WHITE}${ENVIRONMENT}${NC}
• Domain: ${WHITE}${CONFIG_VALUES[DOMAIN]}${NC}
• Server: ${WHITE}${CONFIG_VALUES[SSH_USER]}@${CONFIG_VALUES[SERVER_IP]}:${CONFIG_VALUES[SSH_PORT]}${NC}
• SSH Key: ${WHITE}${CONFIG_VALUES[SSH_KEY_PATH]}${NC}
• Configuration: ${WHITE}.env.${ENVIRONMENT}${NC}

${CYAN}Generated Secure Credentials:${NC}
• Database passwords: ${GREEN}Generated${NC}
• Redis password: ${GREEN}Generated${NC}
• Application key: ${GREEN}Generated${NC}
EOF

    if [[ "$ENVIRONMENT" == "production" ]]; then
        echo "• Monitoring passwords: ${GREEN}Generated${NC}"
    fi

    cat << EOF

${CYAN}Files Created/Updated:${NC}
• ${YELLOW}deployment/applications/environments/.env.${ENVIRONMENT}${NC}
• ${YELLOW}deployment/infrastructure/inventories/${ENVIRONMENT}/hosts.yml${NC}
• ${YELLOW}${CONFIG_VALUES[SSH_KEY_PATH]} (if generated)${NC}

${CYAN}Next Steps:${NC}
1. Review configuration: ${YELLOW}less deployment/applications/environments/.env.${ENVIRONMENT}${NC}
2. Test deployment: ${YELLOW}./deployment/deploy.sh ${ENVIRONMENT} --dry-run${NC}
3. Deploy: ${YELLOW}./deployment/deploy.sh ${ENVIRONMENT}${NC}

${GREEN}Your Custom PHP Framework is ready for deployment!${NC}
${CYAN}Domain: ${CONFIG_VALUES[DOMAIN]} | Environment: ${ENVIRONMENT}${NC}

EOF
}

# Main wizard flow
main() {
    show_welcome
    
    # Execute wizard steps
    CURRENT_STEP=1; step_environment_selection; ((CURRENT_STEP++))
    CURRENT_STEP=2; step_domain_configuration; ((CURRENT_STEP++))
    CURRENT_STEP=3; step_server_configuration; ((CURRENT_STEP++))
    CURRENT_STEP=4; step_ssh_key_setup; ((CURRENT_STEP++))
    CURRENT_STEP=5; step_test_connectivity; ((CURRENT_STEP++))
    CURRENT_STEP=6; step_password_generation; ((CURRENT_STEP++))
    CURRENT_STEP=7; step_create_configuration; ((CURRENT_STEP++))
    CURRENT_STEP=8; step_final_validation; ((CURRENT_STEP++))
    
    success "Setup wizard completed successfully!"
}

# Error handling
cleanup() {
    local exit_code=$?
    if [ $exit_code -ne 0 ]; then
        error "Setup wizard failed with exit code: $exit_code"
        echo
        echo -e "${RED}If you need help, check the troubleshooting guide or start over.${NC}"
    fi
}

trap cleanup EXIT

# Execute if run directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi