#!/bin/bash

set -e

INSTALL_DIR="/opt/voiceforge"
SERVICE_NAME="voiceforge"
SERVICE_USER="voiceforge"
NODE_VERSION="20"
PORT="${PORT:-5000}"

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

print_banner() {
    echo -e "${BLUE}"
    echo "╔═══════════════════════════════════════════════════════════╗"
    echo "║                                                           ║"
    echo "║     ██╗   ██╗ ██████╗ ██╗ ██████╗███████╗                 ║"
    echo "║     ██║   ██║██╔═══██╗██║██╔════╝██╔════╝                 ║"
    echo "║     ██║   ██║██║   ██║██║██║     █████╗                   ║"
    echo "║     ╚██╗ ██╔╝██║   ██║██║██║     ██╔══╝                   ║"
    echo "║      ╚████╔╝ ╚██████╔╝██║╚██████╗███████╗                 ║"
    echo "║       ╚═══╝   ╚═════╝ ╚═╝ ╚═════╝╚══════╝                 ║"
    echo "║                                                           ║"
    echo "║     ███████╗ ██████╗ ██████╗  ██████╗ ███████╗           ║"
    echo "║     ██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██╔════╝           ║"
    echo "║     █████╗  ██║   ██║██████╔╝██║  ███╗█████╗             ║"
    echo "║     ██╔══╝  ██║   ██║██╔══██╗██║   ██║██╔══╝             ║"
    echo "║     ██║     ╚██████╔╝██║  ██║╚██████╔╝███████╗           ║"
    echo "║     ╚═╝      ╚═════╝ ╚═╝  ╚═╝ ╚═════╝ ╚══════╝           ║"
    echo "║                                                           ║"
    echo "║          Voice Transformation Application                 ║"
    echo "║                   Installer v1.0                          ║"
    echo "║                                                           ║"
    echo "╚═══════════════════════════════════════════════════════════╝"
    echo -e "${NC}"
}

log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

check_root() {
    if [[ $EUID -ne 0 ]]; then
        log_error "This script must be run as root (use sudo)"
        exit 1
    fi
}

check_os() {
    if [[ -f /etc/os-release ]]; then
        . /etc/os-release
        OS=$ID
        VERSION=$VERSION_ID
    else
        log_error "Cannot detect operating system"
        exit 1
    fi

    case $OS in
        ubuntu|debian)
            log_info "Detected $OS $VERSION"
            ;;
        centos|rhel|fedora|rocky|almalinux)
            log_info "Detected $OS $VERSION (RHEL-based)"
            ;;
        *)
            log_warn "Untested OS: $OS. Proceeding anyway..."
            ;;
    esac
}

install_dependencies_debian() {
    log_info "Updating package lists..."
    apt-get update -qq

    log_info "Installing system dependencies..."
    apt-get install -y -qq curl wget gnupg2 ca-certificates lsb-release git build-essential

    log_info "Installing FFmpeg..."
    apt-get install -y -qq ffmpeg

    if ! command -v node &> /dev/null || [[ $(node -v | cut -d'.' -f1 | tr -d 'v') -lt $NODE_VERSION ]]; then
        log_info "Installing Node.js $NODE_VERSION..."
        curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash -
        apt-get install -y -qq nodejs
    else
        log_info "Node.js $(node -v) already installed"
    fi
}

install_dependencies_rhel() {
    log_info "Installing EPEL repository..."
    yum install -y epel-release || dnf install -y epel-release

    log_info "Installing system dependencies..."
    yum install -y curl wget git gcc-c++ make || dnf install -y curl wget git gcc-c++ make

    log_info "Installing FFmpeg..."
    yum install -y ffmpeg ffmpeg-devel || dnf install -y ffmpeg ffmpeg-devel || {
        log_info "Adding RPM Fusion repository for FFmpeg..."
        yum install -y https://download1.rpmfusion.org/free/el/rpmfusion-free-release-$(rpm -E %rhel).noarch.rpm || true
        dnf install -y https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm || true
        yum install -y ffmpeg || dnf install -y ffmpeg
    }

    if ! command -v node &> /dev/null || [[ $(node -v | cut -d'.' -f1 | tr -d 'v') -lt $NODE_VERSION ]]; then
        log_info "Installing Node.js $NODE_VERSION..."
        curl -fsSL https://rpm.nodesource.com/setup_${NODE_VERSION}.x | bash -
        yum install -y nodejs || dnf install -y nodejs
    else
        log_info "Node.js $(node -v) already installed"
    fi
}

create_user() {
    if id "$SERVICE_USER" &>/dev/null; then
        log_info "User $SERVICE_USER already exists"
    else
        log_info "Creating system user $SERVICE_USER..."
        useradd --system --home-dir "$INSTALL_DIR" --shell /bin/false "$SERVICE_USER"
    fi
}

setup_application() {
    log_info "Setting up application directory..."
    
    mkdir -p "$INSTALL_DIR"
    
    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    
    if [[ -f "$SCRIPT_DIR/../package.json" ]]; then
        log_info "Copying application files..."
        cp -r "$SCRIPT_DIR/../"* "$INSTALL_DIR/" 2>/dev/null || true
        cp -r "$SCRIPT_DIR/../".* "$INSTALL_DIR/" 2>/dev/null || true
    else
        log_error "Application files not found. Please run from the extracted package directory."
        exit 1
    fi

    rm -rf "$INSTALL_DIR/deploy"

    log_info "Installing npm dependencies..."
    cd "$INSTALL_DIR"
    npm ci --production=false --silent 2>/dev/null || npm install --silent

    log_info "Building application..."
    npm run build

    if [[ ! -f "$INSTALL_DIR/.env" ]]; then
        log_info "Creating environment file..."
        cat > "$INSTALL_DIR/.env" << EOF
NODE_ENV=production
PORT=$PORT
SESSION_SECRET=$(openssl rand -hex 32)
EOF
    fi

    log_info "Setting permissions..."
    chown -R "$SERVICE_USER:$SERVICE_USER" "$INSTALL_DIR"
    chmod 600 "$INSTALL_DIR/.env"
}

create_systemd_service() {
    log_info "Creating systemd service..."
    
    cat > /etc/systemd/system/${SERVICE_NAME}.service << EOF
[Unit]
Description=VoiceForge - Voice Transformation Application
Documentation=https://github.com/voiceforge
After=network.target

[Service]
Type=simple
User=$SERVICE_USER
Group=$SERVICE_USER
WorkingDirectory=$INSTALL_DIR
ExecStart=/usr/bin/node $INSTALL_DIR/dist/index.cjs
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=$SERVICE_NAME

Environment=NODE_ENV=production
Environment=PORT=$PORT
EnvironmentFile=-$INSTALL_DIR/.env

ProtectSystem=strict
ProtectHome=true
ReadWritePaths=$INSTALL_DIR
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

    log_info "Reloading systemd daemon..."
    systemctl daemon-reload

    log_info "Enabling service to start on boot..."
    systemctl enable ${SERVICE_NAME}.service

    log_info "Starting service..."
    systemctl start ${SERVICE_NAME}.service
}

verify_installation() {
    log_info "Verifying installation..."
    
    sleep 3

    if systemctl is-active --quiet ${SERVICE_NAME}; then
        log_info "Service is running!"
    else
        log_error "Service failed to start. Check logs with: journalctl -u ${SERVICE_NAME} -f"
        exit 1
    fi

    if command -v ffmpeg &> /dev/null; then
        log_info "FFmpeg version: $(ffmpeg -version | head -n1)"
    else
        log_error "FFmpeg not found!"
        exit 1
    fi

    if command -v node &> /dev/null; then
        log_info "Node.js version: $(node -v)"
    else
        log_error "Node.js not found!"
        exit 1
    fi
}

print_success() {
    SERVER_IP=$(hostname -I | awk '{print $1}')
    
    echo ""
    echo -e "${GREEN}"
    echo "╔═══════════════════════════════════════════════════════════╗"
    echo "║                                                           ║"
    echo "║        ✓ Installation Completed Successfully!            ║"
    echo "║                                                           ║"
    echo "╠═══════════════════════════════════════════════════════════╣"
    echo "║                                                           ║"
    echo "║  Access your application at:                              ║"
    echo "║                                                           ║"
    printf "║  ➤ http://%-47s ║\n" "${SERVER_IP}:${PORT}"
    printf "║  ➤ http://%-47s ║\n" "localhost:${PORT}"
    echo "║                                                           ║"
    echo "╠═══════════════════════════════════════════════════════════╣"
    echo "║                                                           ║"
    echo "║  Useful Commands:                                         ║"
    echo "║                                                           ║"
    echo "║  • Check status:   systemctl status voiceforge            ║"
    echo "║  • View logs:      journalctl -u voiceforge -f            ║"
    echo "║  • Restart:        systemctl restart voiceforge           ║"
    echo "║  • Stop:           systemctl stop voiceforge              ║"
    echo "║                                                           ║"
    echo "╚═══════════════════════════════════════════════════════════╝"
    echo -e "${NC}"
}

main() {
    print_banner
    
    check_root
    check_os

    case $OS in
        ubuntu|debian)
            install_dependencies_debian
            ;;
        centos|rhel|fedora|rocky|almalinux)
            install_dependencies_rhel
            ;;
        *)
            log_warn "Using Debian-style installation for unknown OS"
            install_dependencies_debian
            ;;
    esac

    create_user
    setup_application
    create_systemd_service
    verify_installation
    print_success
}

main "$@"
