#!/bin/bash
# AirwavePBX v1.0.7 Interactive Installer
# Target OS: Debian 12

set -e

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

# Version
INSTALLER_VERSION="1.0.7"
AIRWAVE_VERSION="1.0.7"

# Paths
INSTALL_DIR="/opt/airwavepbx"
DATA_DIR="/var/lib/airwavepbx"
LOG_DIR="/var/log/airwavepbx"
BACKUP_DIR="/var/backups/airwavepbx"
TEMP_DIR="/tmp/airwavepbx-${INSTALLER_VERSION}"
SSL_DIR="/etc/letsencrypt"

# Script directory (where installer was extracted)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# Detection variables
CURRENT_VERSION=""
CURRENT_PORT=""
ASTERISK_VERSION=""
SSL_DOMAIN=""
HAS_AIRWAVE=false
HAS_ASTERISK=false
HAS_SSL=false

# Print banner
print_banner() {
    clear
    echo -e "${CYAN}"
    echo "╔══════════════════════════════════════════════════════════════════╗"
    echo "║                    AirwavePBX v${INSTALLER_VERSION} Installer                   ║"
    echo "╚══════════════════════════════════════════════════════════════════╝"
    echo -e "${NC}"
}

# Logging functions
print_step() {
    echo -e "\n${MAGENTA}▶${NC} ${BOLD}$1${NC}"
}

print_info() {
    echo -e "  ${BLUE}ℹ${NC} $1"
}

print_success() {
    echo -e "  ${GREEN}✓${NC} $1"
}

print_error() {
    echo -e "  ${RED}✗${NC} $1"
}

print_warning() {
    echo -e "  ${YELLOW}⚠${NC} $1"
}

# Detect existing installation
detect_installation() {
    print_step "Detecting existing installation..."
    
    # Check AirwavePBX
    if [[ -f "$INSTALL_DIR/airwavepbx" ]]; then
        HAS_AIRWAVE=true
        # Try to get version
        if CURRENT_VERSION=$("$INSTALL_DIR/airwavepbx" -version 2>/dev/null); then
            CURRENT_VERSION=$(echo "$CURRENT_VERSION" | grep -oP 'v\K[\d.]+' || echo "unknown")
        else
            CURRENT_VERSION="unknown"
        fi
        
        # Get port from config
        if [[ -f "$INSTALL_DIR/config.yaml" ]]; then
            CURRENT_PORT=$(grep -A1 "server:" "$INSTALL_DIR/config.yaml" | grep "port:" | awk '{print $2}' || echo "unknown")
        fi
        
        print_success "AirwavePBX v${CURRENT_VERSION} found (port ${CURRENT_PORT})"
    else
        print_info "AirwavePBX not installed"
    fi
    
    # Check Asterisk
    if command -v asterisk &> /dev/null; then
        HAS_ASTERISK=true
        ASTERISK_VERSION=$(asterisk -V | grep -oP 'Asterisk \K[\d.]+' || echo "unknown")
        print_success "Asterisk ${ASTERISK_VERSION} found"
    else
        print_info "Asterisk not installed"
    fi
    
    # Check SSL certificates
    if [[ -d "$SSL_DIR/live" ]]; then
        SSL_DOMAIN=$(ls "$SSL_DIR/live" 2>/dev/null | head -1)
        if [[ -n "$SSL_DOMAIN" ]]; then
            HAS_SSL=true
            print_success "LetsEncrypt certs found for: $SSL_DOMAIN"
        fi
    else
        print_info "No LetsEncrypt certificates found"
    fi
}

# Create backup
create_backup() {
    local backup_name="$1"
    print_step "Creating backup..."
    
    mkdir -p "$BACKUP_DIR"
    local timestamp=$(date +%Y%m%d-%H%M%S)
    local backup_file="$BACKUP_DIR/${backup_name}-${timestamp}.tar.gz"
    
    local backup_items=""
    [[ -d "$INSTALL_DIR" ]] && backup_items="$backup_items $INSTALL_DIR"
    [[ -d "$DATA_DIR" ]] && backup_items="$backup_items $DATA_DIR"
    [[ -d "/etc/asterisk" ]] && backup_items="$backup_items /etc/asterisk"
    
    if [[ -n "$backup_items" ]]; then
        tar -czf "$backup_file" $backup_items 2>/dev/null || true
        print_success "Backup created: $backup_file"
    else
        print_info "Nothing to backup"
    fi
}

# Show menu
show_menu() {
    echo ""
    echo "Choose installation type:"
    echo ""
    echo "1) Smart Update (Recommended)"
    echo -e "   ${GREEN}✓${NC} Updates AirwavePBX to v${INSTALLER_VERSION}"
    echo -e "   ${GREEN}✓${NC} Preserves: LetsEncrypt, Asterisk, database"
    echo -e "   ${RED}✗${NC} Replaces: AirwavePBX configs/binaries"
    echo ""
    echo "2) Fix AirwavePBX Only - Keep Phone System"
    echo -e "   ${GREEN}✓${NC} Fresh AirwavePBX install"
    echo -e "   ${GREEN}✓${NC} Preserves: LetsEncrypt, Asterisk entirely"
    echo -e "   ${RED}✗${NC} Removes: AirwavePBX data/configs only"
    echo ""
    echo "3) Complete PBX Rebuild"
    echo -e "   ${GREEN}✓${NC} Fresh install of BOTH systems"
    echo -e "   ${GREEN}✓${NC} Preserves: LetsEncrypt certificates only"
    echo -e "   ${RED}✗${NC} Removes: AirwavePBX + Asterisk"
    echo -e "   ${YELLOW}⚠️  WARNING: 20+ minute rebuild${NC}"
    echo ""
    echo "4) Repair Current Installation"
    echo -e "   ${GREEN}✓${NC} Fix port, permissions, configs"
    echo -e "   ${GREEN}✓${NC} Keep everything, just fix issues"
    echo ""
    echo "5) Remove Everything - Keep SSL Certs"
    echo -e "   ${GREEN}✓${NC} Preserves: LetsEncrypt certificates only"
    echo -e "   ${RED}✗${NC} Removes: AirwavePBX + Asterisk + all data"
    echo "   Perfect for: Repurposing server"
    echo ""
    echo "6) Complete Removal - DANGER!"
    echo -e "   ${RED}✗${NC} Removes EVERYTHING including SSL certs"
    echo -e "   ${YELLOW}⚠️  WARNING: Cannot be undone!${NC}"
    echo ""
    
    read -p "Select [1-6] (default: 1): " choice
    choice=${choice:-1}
    
    case $choice in
        1) smart_update ;;
        2) fix_airwave_only ;;
        3) complete_rebuild ;;
        4) repair_installation ;;
        5) remove_keep_ssl ;;
        6) complete_removal ;;
        *) 
            print_error "Invalid choice"
            show_menu
            ;;
    esac
}

# Option 1: Smart Update
smart_update() {
    print_step "Performing Smart Update..."
    create_backup "pre-update"
    
    # Stop service
    systemctl stop airwavepbx 2>/dev/null || true
    
    # Update binary
    print_info "Installing new binary..."
    go build -C "$SCRIPT_DIR/src" -ldflags "-X main.Version=${INSTALLER_VERSION}" -o "$INSTALL_DIR/airwavepbx" ./cmd/main.go
    chmod +x "$INSTALL_DIR/airwavepbx"
    
    # Update web files
    print_info "Updating web interface..."
    cp -r "$SCRIPT_DIR/src/web/static" "$INSTALL_DIR/web/"
    
    # Update config preserving custom values
    print_info "Updating configuration..."
    update_config_smart
    
    # Update systemd service
    print_info "Updating systemd service..."
    cp "$SCRIPT_DIR/configs/airwavepbx.service" /etc/systemd/system/
    systemctl daemon-reload
    
    # Fix permissions
    fix_permissions
    
    # Start service
    systemctl start airwavepbx
    
    print_success "Smart update complete!"
}

# Option 2: Fix AirwavePBX Only
fix_airwave_only() {
    print_step "Fixing AirwavePBX (preserving Asterisk)..."
    create_backup "pre-fix"
    
    # Stop and remove AirwavePBX
    systemctl stop airwavepbx 2>/dev/null || true
    systemctl disable airwavepbx 2>/dev/null || true
    
    # Remove AirwavePBX files
    rm -rf "$INSTALL_DIR"
    rm -rf "$DATA_DIR"
    rm -rf "$LOG_DIR"
    rm -f /etc/systemd/system/airwavepbx.service
    
    # Fresh install
    fresh_airwave_install
    
    print_success "AirwavePBX fixed!"
}

# Option 3: Complete Rebuild
complete_rebuild() {
    print_step "Complete PBX Rebuild..."
    print_warning "This will take 20+ minutes"
    read -p "Are you sure? [y/N]: " confirm
    
    if [[ "$confirm" != "y" ]]; then
        show_menu
        return
    fi
    
    create_backup "pre-rebuild"
    
    # Remove everything except SSL
    remove_airwave_complete
    remove_asterisk_complete
    
    # Install both fresh
    install_asterisk
    fresh_airwave_install
    
    print_success "Complete rebuild finished!"
}

# Option 4: Repair Installation
repair_installation() {
    print_step "Repairing current installation..."
    
    # Fix config
    if [[ -f "$INSTALL_DIR/config.yaml" ]]; then
        print_info "Fixing configuration..."
        sed -i 's/port: 8080/port: 443/' "$INSTALL_DIR/config.yaml"
        sed -i 's|tls_cert:.*|tls_cert: /etc/letsencrypt/live/'$SSL_DOMAIN'/fullchain.pem|' "$INSTALL_DIR/config.yaml"
        sed -i 's|tls_key:.*|tls_key: /etc/letsencrypt/live/'$SSL_DOMAIN'/privkey.pem|' "$INSTALL_DIR/config.yaml"
    fi
    
    # Fix systemd service
    print_info "Fixing systemd service..."
    if [[ -f /etc/systemd/system/airwavepbx.service ]]; then
        if ! grep -q "AmbientCapabilities=CAP_NET_BIND_SERVICE" /etc/systemd/system/airwavepbx.service; then
            sed -i '/\[Service\]/a AmbientCapabilities=CAP_NET_BIND_SERVICE' /etc/systemd/system/airwavepbx.service
        fi
    fi
    
    # Fix web interface
    print_info "Fixing web interface..."
    if [[ -f "$INSTALL_DIR/web/static/index.html" ]]; then
        sed -i 's|airwave-logo-light.svg|AirwavePBX-horizontal-with-text.png|g' "$INSTALL_DIR/web/static/index.html"
        sed -i 's|airwave-logo-dark.svg|AirwavePBX-horizontal-with-text-cloud.png|g' "$INSTALL_DIR/web/static/index.html"
    fi
    
    # Copy logo files if missing
    if [[ ! -d "$INSTALL_DIR/web/static/logos" ]]; then
        mkdir -p "$INSTALL_DIR/web/static/logos"
        cp "$SCRIPT_DIR/logos/"*.png "$INSTALL_DIR/web/static/logos/" 2>/dev/null || true
    fi
    
    # Fix permissions
    fix_permissions
    
    # Restart service
    systemctl daemon-reload
    systemctl restart airwavepbx
    
    print_success "Repair complete!"
}

# Option 5: Remove Everything except SSL
remove_keep_ssl() {
    print_step "Removing all PBX components (keeping SSL)..."
    print_warning "This will remove AirwavePBX and Asterisk completely"
    read -p "Are you sure? [y/N]: " confirm
    
    if [[ "$confirm" != "y" ]]; then
        show_menu
        return
    fi
    
    create_backup "pre-removal"
    
    remove_airwave_complete
    remove_asterisk_complete
    
    print_success "All PBX components removed"
    print_success "SSL certificates preserved at $SSL_DIR"
    print_info "Your server is now clean except for SSL certificates"
}

# Option 6: Complete Removal
complete_removal() {
    print_step "COMPLETE REMOVAL - This will delete EVERYTHING!"
    print_error "This includes SSL certificates and cannot be undone!"
    read -p "Type 'DELETE ALL' to confirm: " confirm
    
    if [[ "$confirm" != "DELETE ALL" ]]; then
        print_info "Cancelled"
        show_menu
        return
    fi
    
    remove_airwave_complete
    remove_asterisk_complete
    
    # Also remove SSL
    print_warning "Removing SSL certificates..."
    rm -rf "$SSL_DIR"
    
    print_success "Complete removal finished"
}

# Helper: Fresh AirwavePBX install
fresh_airwave_install() {
    print_info "Installing AirwavePBX v${INSTALLER_VERSION}..."
    
    # Create directories
    mkdir -p "$INSTALL_DIR"/{web/static,logs}
    mkdir -p "$DATA_DIR"
    mkdir -p "$LOG_DIR"
    
    # Build and install binary
    print_info "Building AirwavePBX..."
    cd "$SCRIPT_DIR/src"
    go build -ldflags "-X main.Version=${INSTALLER_VERSION}" -o "$INSTALL_DIR/airwavepbx" ./cmd/main.go
    chmod +x "$INSTALL_DIR/airwavepbx"
    
    # Copy web files
    cp -r web/static/* "$INSTALL_DIR/web/static/"
    
    # Copy logos
    cp -r "$SCRIPT_DIR/logos" "$INSTALL_DIR/web/static/"
    
    # Copy FontAwesome
    if [[ -d "$SCRIPT_DIR/fap" ]]; then
        cp -r "$SCRIPT_DIR/fap" "$INSTALL_DIR/web/static/"
    fi
    
    # Create config
    create_config
    
    # Install systemd service
    cp "$SCRIPT_DIR/configs/airwavepbx.service" /etc/systemd/system/
    systemctl daemon-reload
    systemctl enable airwavepbx
    
    # Create user
    if ! id -u airwave &>/dev/null; then
        useradd -r -s /bin/false airwave
    fi
    
    # Fix permissions
    fix_permissions
    
    # Start service
    systemctl start airwavepbx
}

# Helper: Create config
create_config() {
    local config_file="$INSTALL_DIR/config.yaml"
    local domain=${SSL_DOMAIN:-"localhost"}
    local ami_password=$(openssl rand -hex 16)
    local admin_password=$(openssl rand -base64 12 | tr -d "=+/" | cut -c1-16)
    local api_key=$(openssl rand -hex 32)
    
    cat > "$config_file" << EOF
# AirwavePBX Configuration
server:
  host: "0.0.0.0"
  port: 443
  tls_enabled: true
  tls_cert: "/etc/letsencrypt/live/${domain}/fullchain.pem"
  tls_key: "/etc/letsencrypt/live/${domain}/privkey.pem"

database:
  path: "${DATA_DIR}/airwavepbx.db"

asterisk:
  ami_host: "127.0.0.1"
  ami_port: 5038
  ami_username: "airwave"
  ami_password: "${ami_password}"

admin:
  username: "admin"
  password: "${admin_password}"

api:
  key: "${api_key}"
  cors_origins: ["*"]

logging:
  level: "info"
  file: "${LOG_DIR}/airwavepbx.log"
EOF

    # Save credentials
    cat > /root/airwavepbx-credentials.txt << EOF
AirwavePBX v${INSTALLER_VERSION} Credentials
=====================================
Admin Username: admin
Admin Password: ${admin_password}
API Key: ${api_key}
AMI Password: ${ami_password}
EOF
    chmod 600 /root/airwavepbx-credentials.txt
}

# Helper: Update config smartly
update_config_smart() {
    local config_file="$INSTALL_DIR/config.yaml"
    
    if [[ -f "$config_file" ]]; then
        # Update port
        sed -i 's/port: [0-9]*/port: 443/' "$config_file"
        
        # Update SSL paths if domain exists
        if [[ -n "$SSL_DOMAIN" ]]; then
            sed -i "s|tls_cert:.*|tls_cert: \"/etc/letsencrypt/live/${SSL_DOMAIN}/fullchain.pem\"|" "$config_file"
            sed -i "s|tls_key:.*|tls_key: \"/etc/letsencrypt/live/${SSL_DOMAIN}/privkey.pem\"|" "$config_file"
        fi
    else
        create_config
    fi
}

# Helper: Fix permissions
fix_permissions() {
    chown -R airwave:airwave "$INSTALL_DIR"
    chown -R airwave:airwave "$DATA_DIR"
    chown -R airwave:airwave "$LOG_DIR"
    chmod 755 "$INSTALL_DIR"
}

# Helper: Remove AirwavePBX completely
remove_airwave_complete() {
    print_info "Removing AirwavePBX..."
    
    systemctl stop airwavepbx 2>/dev/null || true
    systemctl disable airwavepbx 2>/dev/null || true
    
    rm -rf "$INSTALL_DIR"
    rm -rf "$DATA_DIR"
    rm -rf "$LOG_DIR"
    rm -f /etc/systemd/system/airwavepbx.service
    
    # Remove database
    if command -v sudo -u postgres &> /dev/null; then
        sudo -u postgres dropdb airwavepbx 2>/dev/null || true
    fi
    
    # Remove user
    userdel airwave 2>/dev/null || true
}

# Helper: Remove Asterisk completely
remove_asterisk_complete() {
    print_info "Removing Asterisk..."
    
    systemctl stop asterisk 2>/dev/null || true
    systemctl disable asterisk 2>/dev/null || true
    
    apt-get remove --purge -y asterisk* 2>/dev/null || true
    
    rm -rf /etc/asterisk
    rm -rf /var/lib/asterisk
    rm -rf /var/spool/asterisk
    rm -rf /var/log/asterisk
    rm -rf /usr/lib/asterisk
}

# Helper: Install Asterisk
install_asterisk() {
    print_info "Installing Asterisk..."
    
    apt-get update
    apt-get install -y asterisk asterisk-modules
    
    # Basic configuration
    cat > /etc/asterisk/manager.conf << 'EOF'
[general]
enabled = yes
port = 5038
bindaddr = 127.0.0.1

[airwave]
secret = ad91caad1fe740c0313786cda778e9b6
permit = 127.0.0.1/255.255.255.255
read = all
write = all
EOF
    
    systemctl enable asterisk
    systemctl start asterisk
}

# Post-install test
run_post_install_test() {
    print_step "Running Post-Install Tests..."
    echo "=============================="
    echo ""
    
    local all_passed=true
    
    # 1. Service Status
    echo "1. Service Status:"
    if systemctl is-active airwavepbx &>/dev/null; then
        print_success "airwavepbx.service: active (running)"
    else
        print_error "airwavepbx.service: not running"
        all_passed=false
    fi
    
    if systemctl is-active asterisk &>/dev/null; then
        print_success "asterisk.service: active (running)"
    else
        print_warning "asterisk.service: not running (optional)"
    fi
    echo ""
    
    # 2. Port Check
    echo "2. Port Check:"
    if netstat -tlnp 2>/dev/null | grep -q ":443.*airwavepbx"; then
        print_success "Port 443: airwavepbx listening"
    else
        print_error "Port 443: not listening"
        all_passed=false
    fi
    
    if netstat -tlnp 2>/dev/null | grep -q ":5060.*asterisk"; then
        print_success "Port 5060: asterisk listening"
    else
        print_warning "Port 5060: not listening (optional)"
    fi
    echo ""
    
    # 3. SSL Certificate
    echo "3. SSL Certificate:"
    if [[ -n "$SSL_DOMAIN" ]] && [[ -f "/etc/letsencrypt/live/$SSL_DOMAIN/fullchain.pem" ]]; then
        print_success "Valid cert for: $SSL_DOMAIN"
        # Check expiry
        local expiry=$(openssl x509 -enddate -noout -in "/etc/letsencrypt/live/$SSL_DOMAIN/fullchain.pem" | cut -d= -f2)
        print_info "Expires: $expiry"
    else
        print_warning "No SSL certificate found"
    fi
    echo ""
    
    # 4. Web Interface Test
    echo "4. Web Interface Test:"
    if [[ -n "$SSL_DOMAIN" ]]; then
        echo "   Testing https://$SSL_DOMAIN ..."
        if curl -k -s -o /dev/null -w "%{http_code}" "https://localhost" | grep -q "200\|301\|302"; then
            print_success "HTTPS responds: OK"
        else
            print_error "HTTPS not responding"
            all_passed=false
        fi
    fi
    echo ""
    
    # 5. Show access info
    if [[ "$all_passed" == true ]]; then
        echo ""
        print_success "All tests passed! ✅"
        echo ""
        if [[ -n "$SSL_DOMAIN" ]]; then
            echo "Access your PBX at: https://$SSL_DOMAIN"
        else
            echo "Access your PBX at: https://your-server-ip"
        fi
        
        if [[ -f /root/airwavepbx-credentials.txt ]]; then
            echo ""
            cat /root/airwavepbx-credentials.txt
        fi
    else
        echo ""
        print_warning "Some tests failed. Please check the logs."
    fi
}

# Main execution
main() {
    # Check if running as root
    if [[ $EUID -ne 0 ]]; then
        print_error "This script must be run as root"
        exit 1
    fi
    
    print_banner
    detect_installation
    show_menu
    
    # Ask about post-install test
    echo ""
    read -p "Would you like to run a post-install test? [Y/n]: " run_test
    run_test=${run_test:-Y}
    
    if [[ "$run_test" =~ ^[Yy]$ ]]; then
        run_post_install_test
    fi
    
    # Final message
    echo ""
    print_info "Installation files preserved at: $TEMP_DIR/"
    print_info "To remove them: rm -rf $TEMP_DIR/"
    echo ""
    print_success "Installation complete!"
}

# Run main
main "$@"