#!/bin/bash

# =============================================================================
# IntelliCall AI - Setup & Customization Wizard
# =============================================================================
# This script guides you through the complete setup of the IntelliCall AI
# platform, including the Node.js backend and Next.js frontend.
# Run with: bash setup.sh (or ./setup.sh)
# =============================================================================

# set -e # Removed to allow guided error handling

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

# Paths
PROJECT_ROOT="$(dirname "$0")/.."
BACKEND_DIR="$PROJECT_ROOT/backend"
FRONTEND_DIR="$PROJECT_ROOT/frontend"

# UI Functions
print_header() {
    echo ""
    echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
    echo -e "${BOLD}${CYAN}  $1${NC}"
    echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
    echo ""
}

print_success() { echo -e "${GREEN}✅ $1${NC}"; }
print_error() { echo -e "${RED}❌ $1${NC}"; }
print_warning() { echo -e "${YELLOW}⚠️  $1${NC}"; }
print_info() { echo -e "${CYAN}ℹ️  $1${NC}"; }
print_step() { echo -e "${BOLD}${BLUE}▶ $1${NC}"; }
print_box() {
    local title=$1
    echo -e "${CYAN}╭───────────────────────────────────────────────────────────╮${NC}"
    echo -e "${CYAN}│ ${BOLD}${YELLOW}$title${NC}${CYAN}$([[ ${#title} -lt 58 ]] && printf ' %.0s' $(seq 1 $((58 - ${#title}))))│${NC}"
    echo -e "${CYAN}├───────────────────────────────────────────────────────────┤${NC}"
}
print_box_footer() {
    echo -e "${CYAN}╰───────────────────────────────────────────────────────────╯${NC}"
}

# Helper: Backup file
backup_file() {
    if [ -f "$1" ]; then
        local backup_path="$1.bak.$(date +%Y%m%d_%H%M%S)"
        cp "$1" "$backup_path"
        print_info "Backup created: $(basename "$backup_path")"
    fi
}

# Helper: Get input with default
get_input() {
    local prompt=$1
    local default=$2
    local result
    read -p "  $prompt [$default]: " result
    echo "${result:-$default}"
}

# Helper: Get secret input (no echo)
get_secret() {
    local prompt=$1
    local result
    read -s -r -p "  $prompt: " result
    echo "" >&2 
    printf "%s" "$result"
}

# Helper: Update or Add key in .env file
update_env_var() {
    local file=$1
    local key=$2
    local value=$3

    if [ ! -f "$file" ]; then
        echo "$key=$value" > "$file"
    else
        if grep -q "^$key=" "$file"; then
            sed "s#^$key=.*#$key=$value#" "$file" > "$file.tmp" && mv "$file.tmp" "$file"
        else
            echo "$key=$value" >> "$file"
        fi
    fi
}

# -----------------------------------------------------------------------------
# STEP 1: DEPENDENCY CHECKS
# -----------------------------------------------------------------------------
check_dependencies() {
    print_header "Checking Dependencies"
    local MISSING_DEPS=0

    print_step "Checking Node.js..."
    if command -v node &> /dev/null; then
        NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
        if [ "$NODE_VERSION" -ge 18 ]; then
            print_success "Node.js v$(node -v | cut -d'v' -f2) found"
        else
            print_error "Node.js version too old. Found v$(node -v), need v18+"
            MISSING_DEPS=1
        fi
    else
        print_error "Node.js not found"
        MISSING_DEPS=1
    fi

    print_step "Checking npm..."
    if command -v npm &> /dev/null; then
        print_success "npm v$(npm -v) found"
    else
        print_error "npm not found"
        MISSING_DEPS=1
    fi

    if [ $MISSING_DEPS -eq 1 ]; then
        print_error "Please install missing dependencies and run setup again."
        exit 1
    fi
    print_success "All required dependencies found!"
}

# -----------------------------------------------------------------------------
# STEP 2: MONGODB TEST
# -----------------------------------------------------------------------------
test_mongodb() {
    local url=$1
    print_step "Testing MongoDB connection..."
    if command -v mongosh &> /dev/null; then
        if ! mongosh "$url" --eval "db.runCommand({ ping: 1 })" --quiet > /dev/null 2>&1; then
            return 1
        fi
    elif command -v mongo &> /dev/null; then
        if ! mongo "$url" --eval "db.runCommand({ ping: 1 })" --quiet > /dev/null 2>&1; then
            return 1
        fi
    else
        print_warning "No MongoDB client found to test connection. Assuming URL is correct."
        return 0
    fi
    return 0
}

# -----------------------------------------------------------------------------
# STEP 2.5: NGROK HELPER
# -----------------------------------------------------------------------------
print_ngrok_info() {
    print_box "🌍 NGROK GUIDE (LOCAL TESTING)"
    echo -e "${CYAN}│${NC} 1. Install: ${BOLD}brew install ngrok${NC} (macOS)      ${CYAN}│${NC}"
    echo -e "${CYAN}│${NC} 2. Connect: ${BOLD}ngrok config add-authtoken <TOKEN>${NC}        ${CYAN}│${NC}"
    echo -e "${CYAN}│${NC} 3. Run: ${BOLD}ngrok http 5001${NC}                                ${CYAN}│${NC}"
    echo -e "${CYAN}│${NC} 4. Copy the ${BOLD}Forwarding URL${NC} (https://...) to BASE_URL ${CYAN}│${NC}"
    print_box_footer
}

# -----------------------------------------------------------------------------
# OPTION 1: FULL SETUP
# -----------------------------------------------------------------------------
run_full_setup() {
    print_header "Full / Initial Setup"
    
    check_dependencies

    # Configuration Prompts
    print_header "Step 2: Configuration"
    
    local MONGODB_URI=$(get_input "MongoDB URI" "mongodb://localhost:27017/intellicall-ai")
    local BACKEND_PORT=$(get_input "Backend API Port" "5001")
    
    if ! test_mongodb "$MONGODB_URI"; then
        print_error "Cannot connect to MongoDB at $MONGODB_URI"
        print_info "Make sure your MongoDB server is running or your Atlas IP is whitelisted."
        exit 1
    fi
    print_success "MongoDB connection successful!"

    print_step "Authentication Setup"
    print_info "Google OAuth is used for login. Get these from Google Cloud Console."
    local GOOGLE_ID=$(get_input "Google Client ID" "your_google_client_id")
    local GOOGLE_SECRET=$(get_input "Google Client Secret" "your_google_client_secret")
    
    print_step "URLs Configuration"
    print_info "Twilio needs a PUBLIC URL to send voice streams to your machine."
    read -p "  Do you need help setting up ngrok for local testing? [y/N]: " WANT_NGROK
    if [[ $WANT_NGROK =~ ^[Yy]$ ]]; then
        print_ngrok_info
    fi
    
    local BASE_URL=$(get_input "Backend Base URL (URL of THIS machine)" "http://localhost:5001")
    local CLIENT_URL=$(get_input "Frontend Client URL" "http://localhost:3000")

    # Generate Secret
    print_step "Generating secure JWT secret..."
    local JWT_SECRET=$(openssl rand -base64 32 2>/dev/null || cat /dev/urandom | head -c 32 | base64)
    print_success "JWT secret generated."

    # Write Backend .env
    print_header "Step 3: Configuring Backend & Core API"
    print_info "Creating backend environment configuration..."
    backup_file "$BACKEND_DIR/.env"
    cat > "$BACKEND_DIR/.env" << EOF
# IntelliCall AI Backend Configuration
PORT=$BACKEND_PORT
MONGODB_URI=$MONGODB_URI
NODE_ENV=development
JWT_SECRET=$JWT_SECRET
BASE_URL=$BASE_URL

# Google OAuth
GOOGLE_CLIENT_ID=$GOOGLE_ID
GOOGLE_CLIENT_SECRET=$GOOGLE_SECRET
CLIENT_URL=$CLIENT_URL
EOF
    print_success "Backend .env created"

    print_step "Installing backend dependencies (this may take a minute)..."
    if (cd "$BACKEND_DIR" && npm install --silent); then
        print_success "Backend dependencies installed"
    else
        print_warning "Automated backend installation skipped/failed."
        print_info "Please run 'npm install' manually in the 'backend' folder later."
    fi

    # Write Frontend .env
    print_header "Step 4: Configuring Frontend Dashboard"
    print_info "Connecting frontend to backend API..."
    backup_file "$FRONTEND_DIR/.env"
    cat > "$FRONTEND_DIR/.env" << EOF
# IntelliCall AI Frontend Configuration
NEXT_PUBLIC_API_URL=$BASE_URL/api
EOF
    print_success "Frontend .env created"

    print_step "Installing frontend dependencies (this may take a minute)..."
    if (cd "$FRONTEND_DIR" && npm install --silent); then
        print_success "Frontend dependencies installed"
    else
        print_warning "Automated frontend installation skipped/failed."
        print_info "Please run 'npm install' manually in the 'frontend' folder later."
    fi

    # Runtime Validation
    print_header "Step 5: Starting Backend & Validation"
    print_step "Starting backend server..."
    cd "$BACKEND_DIR"
    npm run start &
    local BACKEND_PID=$!
    sleep 5

    print_step "Verifying backend connection..."
    local MAX_RETRIES=15
    local RETRY_COUNT=0
    local BACKEND_OK=0

    while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
        if curl -s "http://localhost:$BACKEND_PORT/health" | grep -q "success"; then
            BACKEND_OK=1
            break
        fi
        RETRY_COUNT=$((RETRY_COUNT + 1))
        sleep 2
    done

    kill $BACKEND_PID 2>/dev/null
    
    if [ $BACKEND_OK -eq 1 ]; then
        print_success "Backend server validated successfully!"
    else
        print_warning "Backend validation skipped or failed."
        print_info "Don't worry, you can still start the server manually for debugging."
    fi

    print_header "🎉 Full Setup Complete!"
    
    print_box "🚀 NEXT STEPS TO GET STARTED"
    echo -e "${CYAN}│${NC} 1. Open TWO terminal windows.                              ${CYAN}│${NC}"
    echo -e "${CYAN}│${NC} 2. In Window 1 (Backend):                                  ${CYAN}│${NC}"
    echo -e "${CYAN}│${NC}    ${BOLD}cd backend && npm run dev${NC}                               ${CYAN}│${NC}"
    echo -e "${CYAN}│${NC} 3. In Window 2 (Frontend):                                 ${CYAN}│${NC}"
    echo -e "${CYAN}│${NC}    ${BOLD}cd frontend && npm run dev${NC}                              ${CYAN}│${NC}"
    echo -e "${CYAN}│${NC} 4. Open ${BOLD}http://localhost:3000${NC} in your browser.             ${CYAN}│${NC}"
    echo -e "${CYAN}│${NC} 5. Sign in via Google. ${BOLD}First user is automatically ADMIN.${NC}  ${CYAN}│${NC}"
    print_box_footer
    
    echo ""
    print_info "Need help? Check the ${BOLD}Documentation/QuickStart.html${NC} file."
    print_success "IntelliCall AI is now configured and ready for production logic!"
}

# -----------------------------------------------------------------------------
# OPTION 2: FRONTEND CUSTOMIZATION
# -----------------------------------------------------------------------------
customize_frontend() {
    print_header "Frontend Customization"
    local ENV_FILE="$FRONTEND_DIR/.env"
    
    if [ ! -f "$ENV_FILE" ]; then
        print_warning "Frontend not yet configured. Run Full Setup first."
        return
    fi

    local CURRENT_API=$(grep "^NEXT_PUBLIC_API_URL=" "$ENV_FILE" | cut -d'=' -f2 || echo "http://localhost:5001/api")
    local API_URL=$(get_input "Backend API URL" "$CURRENT_API")

    print_step "Applying changes..."
    backup_file "$ENV_FILE"
    update_env_var "$ENV_FILE" "NEXT_PUBLIC_API_URL" "$API_URL"
    
    print_success "Frontend configuration updated!"
}

# -----------------------------------------------------------------------------
# OPTION 3: BACKEND CUSTOMIZATION
# -----------------------------------------------------------------------------
customize_backend() {
    print_header "Backend Customization"
    local ENV_FILE="$BACKEND_DIR/.env"

    if [ ! -f "$ENV_FILE" ]; then
        print_warning "Backend not yet configured. Run Full Setup first."
        return
    fi

    print_info "Keep current values by pressing Enter."
    
    # Load current values
    while IFS='=' read -r key value; do
        if [[ ! $key =~ ^# && -n $key ]]; then
            eval "CUR_$key='$value'"
        fi
    done < "$ENV_FILE"

    local NEW_PORT=$(get_input "API Port" "$CUR_PORT")
    local NEW_MONGO=$(get_input "MongoDB URI" "$CUR_MONGODB_URI")
    local NEW_GOOGLE_ID=$(get_input "Google Client ID" "$CUR_GOOGLE_CLIENT_ID")
    local NEW_GOOGLE_SECRET=$(get_input "Google Client Secret" "$CUR_GOOGLE_CLIENT_SECRET")
    local NEW_BASE_URL=$(get_input "Base URL" "$CUR_BASE_URL")
    local NEW_CLIENT_URL=$(get_input "Client URL" "$CUR_CLIENT_URL")

    print_step "Updating environment values..."
    backup_file "$ENV_FILE"
    
    update_env_var "$ENV_FILE" "PORT" "$NEW_PORT"
    update_env_var "$ENV_FILE" "MONGODB_URI" "$NEW_MONGO"
    update_env_var "$ENV_FILE" "GOOGLE_CLIENT_ID" "$NEW_GOOGLE_ID"
    update_env_var "$ENV_FILE" "GOOGLE_CLIENT_SECRET" "$NEW_GOOGLE_SECRET"
    update_env_var "$ENV_FILE" "BASE_URL" "$NEW_BASE_URL"
    update_env_var "$ENV_FILE" "CLIENT_URL" "$NEW_CLIENT_URL"

    # Sync Frontend API URL if Base URL changed
    if [ "$NEW_BASE_URL" != "$CUR_BASE_URL" ]; then
        local FE_ENV="$FRONTEND_DIR/.env"
        if [ -f "$FE_ENV" ]; then
            print_step "Syncing Frontend API URL..."
            update_env_var "$FE_ENV" "NEXT_PUBLIC_API_URL" "$NEW_BASE_URL/api"
        fi
    fi

    print_success "Backend configuration updated!"
    print_info "Restart the backend server for changes to take effect."
}

# -----------------------------------------------------------------------------
# MAIN MENU LOOP
# -----------------------------------------------------------------------------
while true; do
    clear
    echo -e "${CYAN}"
    echo "  IntelliCall AI Setup"
    echo -e "${NC}"
    echo -e "${BOLD}  IntelliCall AI Ultimate Setup & Customization Wizard${NC}"
    echo "  ================================================="
    echo "  1) Full / Initial Setup (Recommended)"
    echo "  2) Frontend Customization (Next.js)"
    echo "  3) Backend Customization (Node.js)"
    echo "  4) Exit"
    echo "  ================================================="
    echo ""
    read -p "  Select an option [1-4]: " CHOICE

    case $CHOICE in
        1) run_full_setup ;;
        2) customize_frontend ;;
        3) customize_backend ;;
        4) print_info "Exiting Setup Wizard. Goodbye!"; exit 0 ;;
        *) print_error "Invalid option. Please try again." ;;
    esac

    echo ""
    echo -e "${YELLOW}  Press Enter to return to the main menu...${NC}"
    read
done
