#!/bin/bash

# AirwavePBX v2.0.1 Standalone Installer
# Fixed for Ubuntu 24.04 LTS - Uses standard repositories

set -e

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

# Print colored output
print_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
print_error() { echo -e "${RED}[ERROR]${NC} $1"; }

# Configuration variables
AIRWAVE_VERSION="2.0.1"
INSTALL_DIR="/opt/airwavepbx"
CONFIG_DIR="/etc/airwavepbx"
LOG_DIR="/var/log/airwavepbx"
DATA_DIR="/var/lib/airwavepbx"
SSL_DIR="/etc/letsencrypt"

# Header
echo "============================================="
echo "AirwavePBX v${AIRWAVE_VERSION} Installer"
echo "Standalone Architecture (No External Dependencies)"
echo "============================================="
echo

# Check if running as root
if [[ $EUID -ne 0 ]]; then
   print_error "This script must be run as root"
   exit 1
fi

# Check Ubuntu version
if ! grep -q "Ubuntu 24.04" /etc/os-release; then
    print_warning "This installer is designed for Ubuntu 24.04 LTS"
    read -p "Continue anyway? (y/N) " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        exit 1
    fi
fi

# Function to check if a command exists
command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# Function to generate secure password
generate_password() {
    openssl rand -base64 32 | tr -d "=+/" | cut -c1-25
}

# Check DNS resolution
check_dns() {
    print_info "Checking DNS resolution..."
    if ! nslookup google.com >/dev/null 2>&1; then
        print_warning "DNS resolution issues detected"
        print_info "Adding Google DNS servers..."
        echo "nameserver 8.8.8.8" >> /etc/resolv.conf
        echo "nameserver 8.8.4.4" >> /etc/resolv.conf
    fi
}

# Detect existing Let's Encrypt certificates
detect_letsencrypt() {
    print_info "Checking for existing Let's Encrypt certificates..."
    
    if [ -d "$SSL_DIR/live" ]; then
        EXISTING_DOMAINS=$(ls -1 "$SSL_DIR/live" 2>/dev/null | grep -v README || true)
        if [ -n "$EXISTING_DOMAINS" ]; then
            print_success "Found existing Let's Encrypt certificates:"
            echo "$EXISTING_DOMAINS" | while read domain; do
                echo "  - $domain"
            done
            
            echo
            read -p "Would you like to use an existing certificate? (y/N) " -n 1 -r
            echo
            if [[ $REPLY =~ ^[Yy]$ ]]; then
                echo "Available domains:"
                select DOMAIN in $EXISTING_DOMAINS "Enter new domain"; do
                    if [ "$DOMAIN" = "Enter new domain" ]; then
                        read -p "Enter your domain name: " DOMAIN
                        USE_EXISTING_CERT=false
                    else
                        USE_EXISTING_CERT=true
                    fi
                    break
                done
            else
                read -p "Enter your domain name: " DOMAIN
                USE_EXISTING_CERT=false
            fi
        else
            read -p "Enter your domain name: " DOMAIN
            USE_EXISTING_CERT=false
        fi
    else
        read -p "Enter your domain name: " DOMAIN
        USE_EXISTING_CERT=false
    fi
}

# Install dependencies
install_dependencies() {
    print_info "Installing dependencies..."
    
    # Update package list
    apt-get update
    
    # Core packages
    PACKAGES=(
        curl
        wget
        gnupg
        lsb-release
        ca-certificates
        software-properties-common
        apt-transport-https
        build-essential
        git
        python3
        python3-pip
        nginx
        certbot
        python3-certbot-nginx
        ufw
        net-tools
        jq
        sqlite3
        redis-server
        supervisor
    )
    
    # Install packages
    for pkg in "${PACKAGES[@]}"; do
        if ! dpkg -l | grep -q "^ii  $pkg "; then
            print_info "Installing $pkg..."
            apt-get install -y "$pkg"
        fi
    done
    
    # Install Node.js 20.x
    if ! command_exists node || ! node --version | grep -q "v20"; then
        print_info "Installing Node.js 20.x..."
        curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
        apt-get install -y nodejs
    fi
    
    # Install PM2
    if ! command_exists pm2; then
        print_info "Installing PM2..."
        npm install -g pm2
    fi
    
    print_success "Dependencies installed"
}

# Install and configure Asterisk
install_asterisk() {
    print_info "Installing Asterisk..."
    
    # Install from standard Ubuntu repository
    ASTERISK_PACKAGES=(
        asterisk
        asterisk-core-sounds-en
        asterisk-core-sounds-en-wav
        asterisk-moh-opsound-wav
        asterisk-modules
    )
    
    apt-get install -y "${ASTERISK_PACKAGES[@]}"
    
    # Enable and start Asterisk
    systemctl enable asterisk
    systemctl start asterisk
    
    # Create AirwavePBX user for Asterisk AMI/ARI
    print_info "Configuring Asterisk for AirwavePBX..."
    
    # Generate AMI password
    AMI_PASSWORD=$(generate_password)
    
    # Save password for later use
    echo "AMI_PASSWORD=$AMI_PASSWORD" > "$CONFIG_DIR/asterisk-credentials.txt"
    chmod 600 "$CONFIG_DIR/asterisk-credentials.txt"
    
    # AMI configuration
    cat >> /etc/asterisk/manager.conf << EOF

[airwavepbx]
secret = $AMI_PASSWORD
deny = 0.0.0.0/0.0.0.0
permit = 127.0.0.1/255.255.255.255
read = all
write = all
writetimeout = 5000
EOF

    # ARI configuration
    cat > /etc/asterisk/ari.conf << EOF
[general]
enabled = yes
pretty = yes

[airwavepbx]
type = user
password = $AMI_PASSWORD
read_only = no
EOF

    # Enable HTTP for ARI
    cat > /etc/asterisk/http.conf << EOF
[general]
enabled = yes
bindaddr = 127.0.0.1
bindport = 8088
EOF

    # Create directories for AirwavePBX configs
    mkdir -p /etc/asterisk/airwavepbx
    chown asterisk:asterisk /etc/asterisk/airwavepbx
    chmod 775 /etc/asterisk/airwavepbx
    
    # Create empty config files
    touch /etc/asterisk/airwavepbx/sip.conf
    touch /etc/asterisk/airwavepbx/extensions.conf
    chown asterisk:asterisk /etc/asterisk/airwavepbx/*.conf
    chmod 664 /etc/asterisk/airwavepbx/*.conf
    
    # Add includes to main config files
    if ! grep -q "#include airwavepbx/sip.conf" /etc/asterisk/sip.conf; then
        echo "#include airwavepbx/sip.conf" >> /etc/asterisk/sip.conf
    fi
    
    if ! grep -q "#include airwavepbx/extensions.conf" /etc/asterisk/extensions.conf; then
        echo "#include airwavepbx/extensions.conf" >> /etc/asterisk/extensions.conf
    fi
    
    # Restart Asterisk
    systemctl restart asterisk
    
    print_success "Asterisk installed and configured"
}

# Configure firewall
configure_firewall() {
    print_info "Configuring firewall..."
    
    # Enable UFW
    ufw --force enable
    
    # Allow SSH
    ufw allow ssh
    
    # Web ports
    ufw allow 80/tcp comment "HTTP"
    ufw allow 443/tcp comment "HTTPS"
    
    # SIP ports
    ufw allow 5060/tcp comment "SIP TCP"
    ufw allow 5060/udp comment "SIP UDP"
    ufw allow 5061/tcp comment "SIP TLS"
    
    # RTP ports
    ufw allow 10000:20000/udp comment "RTP Media"
    
    # Asterisk HTTP/ARI (local only)
    # Port 8088 is already restricted to localhost in http.conf
    
    print_success "Firewall configured"
}

# Install AirwavePBX
install_airwavepbx() {
    print_info "Installing AirwavePBX..."
    
    # Create directories
    mkdir -p "$INSTALL_DIR"
    mkdir -p "$CONFIG_DIR"
    mkdir -p "$LOG_DIR"
    mkdir -p "$DATA_DIR/data"
    
    # Create airwavepbx user
    if ! id -u airwavepbx >/dev/null 2>&1; then
        useradd -r -s /bin/false -d /var/lib/airwavepbx airwavepbx
    fi
    
    # Add airwavepbx to asterisk group
    usermod -a -G asterisk airwavepbx
    
    # Copy application files
    print_info "Copying application files..."
    cp -r src public package.json package-lock.json next.config.js tsconfig.json tailwind.config.ts postcss.config.js "$INSTALL_DIR/" 2>/dev/null || true
    cp -r api "$INSTALL_DIR/" 2>/dev/null || true
    
    # Install Node.js dependencies for API
    cd "$INSTALL_DIR"
    if [ -d "api" ]; then
        cd api
        print_info "Installing API dependencies..."
        npm install --production
        cd ..
    fi
    
    # Install Next.js dependencies
    print_info "Installing application dependencies..."
    npm install --production
    
    # Build Next.js application
    print_info "Building AirwavePBX frontend..."
    npm run build
    
    # Generate configuration
    print_info "Generating configuration..."
    
    # Load AMI password
    source "$CONFIG_DIR/asterisk-credentials.txt"
    
    cat > "$CONFIG_DIR/airwavepbx.env" << EOF
# AirwavePBX Configuration
NODE_ENV=production
PORT=3000
API_PORT=3001

# Domain
DOMAIN=$DOMAIN
ADMIN_EMAIL=$ADMIN_EMAIL

# Security
JWT_SECRET=$(generate_password)
SESSION_SECRET=$(generate_password)

# Asterisk
AMI_PASSWORD=$AMI_PASSWORD

# Database
DATABASE_PATH=$DATA_DIR/data/airwavepbx.db
EOF

    # Create PM2 ecosystem file
    cat > "$INSTALL_DIR/ecosystem.config.js" << EOF
module.exports = {
  apps: [
    {
      name: 'airwavepbx-frontend',
      script: 'npm',
      args: 'start',
      cwd: '$INSTALL_DIR',
      env_file: '$CONFIG_DIR/airwavepbx.env'
    },
    {
      name: 'airwavepbx-api',
      script: 'api/server.js',
      cwd: '$INSTALL_DIR',
      env_file: '$CONFIG_DIR/airwavepbx.env'
    }
  ]
};
EOF

    # Set permissions
    chown -R airwavepbx:airwavepbx "$INSTALL_DIR"
    chown -R airwavepbx:airwavepbx "$DATA_DIR"
    chown -R airwavepbx:airwavepbx "$LOG_DIR"
    chmod 600 "$CONFIG_DIR/airwavepbx.env"
    
    # Start services with PM2
    print_info "Starting AirwavePBX services..."
    cd "$INSTALL_DIR"
    pm2 start ecosystem.config.js
    pm2 save
    pm2 startup systemd -u root --hp /root
    
    print_success "AirwavePBX installed"
}

# Configure Nginx
configure_nginx() {
    print_info "Configuring Nginx..."
    
    cat > /etc/nginx/sites-available/airwavepbx << EOF
server {
    listen 80;
    server_name $DOMAIN;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host \$host;
        proxy_cache_bypass \$http_upgrade;
    }

    location /api/ {
        proxy_pass http://localhost:3001/api/;
        proxy_http_version 1.1;
        proxy_set_header Host \$host;
    }

    location /ws {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host \$host;
    }
}
EOF

    ln -sf /etc/nginx/sites-available/airwavepbx /etc/nginx/sites-enabled/
    rm -f /etc/nginx/sites-enabled/default
    nginx -t
    systemctl reload nginx
    
    print_success "Nginx configured"
}

# Configure SSL
configure_ssl() {
    if [ "$USE_EXISTING_CERT" = true ]; then
        print_info "Using existing Let's Encrypt certificate for $DOMAIN"
        certbot --nginx -d "$DOMAIN" --redirect --quiet --non-interactive
    else
        print_info "Obtaining new Let's Encrypt certificate..."
        certbot --nginx -d "$DOMAIN" --redirect --agree-tos --email "$ADMIN_EMAIL" --non-interactive
    fi
    
    systemctl enable certbot.timer
    systemctl start certbot.timer
    
    print_success "SSL configured"
}

# Create management script
create_management_script() {
    cat > /usr/local/bin/airwavepbx << 'EOF'
#!/bin/bash

case "$1" in
    start)
        pm2 start all
        ;;
    stop)
        pm2 stop all
        ;;
    restart)
        pm2 restart all
        ;;
    status)
        pm2 status
        echo
        echo "Asterisk Status:"
        systemctl status asterisk --no-pager | head -10
        ;;
    logs)
        pm2 logs --lines 50
        ;;
    fix-permissions)
        chown -R airwavepbx:airwavepbx /opt/airwavepbx
        chown -R airwavepbx:airwavepbx /var/lib/airwavepbx
        chown -R airwavepbx:airwavepbx /var/log/airwavepbx
        usermod -a -G asterisk airwavepbx
        chmod 664 /etc/asterisk/airwavepbx/*.conf
        echo "Permissions fixed"
        ;;
    *)
        echo "Usage: airwavepbx {start|stop|restart|status|logs|fix-permissions}"
        exit 1
        ;;
esac
EOF

    chmod +x /usr/local/bin/airwavepbx
}

# Main installation
main() {
    check_dns
    detect_letsencrypt
    read -p "Enter admin email address: " ADMIN_EMAIL
    
    echo
    echo "Installation Summary:"
    echo "  Domain: $DOMAIN"
    echo "  Admin Email: $ADMIN_EMAIL"
    echo "  Architecture: Standalone (Direct Asterisk)"
    echo
    read -p "Continue? (y/N) " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        exit 1
    fi
    
    install_dependencies
    install_asterisk
    configure_firewall
    install_airwavepbx
    configure_nginx
    configure_ssl
    create_management_script
    
    echo
    echo "============================================="
    echo "Installation Complete!"
    echo "============================================="
    echo
    print_success "AirwavePBX v${AIRWAVE_VERSION} installed successfully!"
    echo
    echo "Access your system at: https://$DOMAIN"
    echo "Username: admin"
    echo "Password: admin (change this immediately!)"
    echo
    echo "Management: airwavepbx {start|stop|restart|status|logs}"
    echo
}

main "$@"