#!/bin/bash
# ═════════════════════════════════════════════════════════════════════════════
# StreCoin — Universal Installer
# ═════════════════════════════════════════════════════════════════════════════
# One-liner installation:
#   curl -sSL https://strecoin.com/install.sh | bash
#   
# Oder mit wget:
#   wget -qO- https://strecoin.com/install.sh | bash
# ═════════════════════════════════════════════════════════════════════════════

set -e

# ─────────────────────────────────────────────────────────────────────────────
# Konfiguration
# ─────────────────────────────────────────────────────────────────────────────
INSTALL_DIR="$HOME/StreCoin"
DATA_DIR="$INSTALL_DIR/data"
BIN_NAME="strecoin"
API_PORT="8080"
P2P_PORT="4001"

# Seed-Hosts für Bootstrap
SEED_HOSTS="46.225.110.38,46.101.146.133,104.207.130.139,5.161.86.91"

# ─────────────────────────────────────────────────────────────────────────────
# Farben (nur wenn Terminal interaktiv)
# ─────────────────────────────────────────────────────────────────────────────
if [ -t 1 ]; then
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[0;33m'
    BLUE='\033[0;34m'
    CYAN='\033[0;36m'
    BOLD='\033[1m'
    NC='\033[0m'
else
    RED='' GREEN='' YELLOW='' BLUE='' CYAN='' BOLD='' NC=''
fi

# ─────────────────────────────────────────────────────────────────────────────
# Logging
# ─────────────────────────────────────────────────────────────────────────────
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[OK]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
log_step() { echo -e "\n${BOLD}${CYAN}➤ $1${NC}"; }

# ─────────────────────────────────────────────────────────────────────────────
# Banner
# ─────────────────────────────────────────────────────────────────────────────
show_banner() {
    echo -e "${CYAN}"
    cat <<'EOF'
   ███████╗████████╗██████╗ ███████╗ ██████╗ ██████╗ ██╗███╗   ██╗
   ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██╔════╝██╔═══██╗██║████╗  ██║
   ███████╗   ██║   ██████╔╝█████╗  ██║     ██║   ██║██║██╔██╗ ██║
   ╚════██║   ██║   ██╔══██╗██╔══╝  ██║     ██║   ██║██║██║╚██╗██║
   ███████║   ██║   ██║  ██║███████╗╚██████╗╚██████╔╝██║██║ ╚████║
   ╚══════╝   ╚═╝   ╚═╝  ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝╚═╝  ╚═══╝
EOF
    echo -e "${NC}"
    echo -e "   ${BOLD}StreCoin Installer${NC} — Dezentrale Blockchain"
    echo -e "   ${CYAN}https://strecoin.com${NC}"
    echo ""
}

# ─────────────────────────────────────────────────────────────────────────────
# System-Erkennung
# ─────────────────────────────────────────────────────────────────────────────
detect_platform() {
    local os arch
    os=$(uname -s | tr '[:upper:]' '[:lower:]')
    arch=$(uname -m | tr '[:upper:]' '[:lower:]')
    
    case "$os" in
        linux)
            case "$arch" in
                x86_64|amd64) echo "linux-amd64" ;;
                aarch64|arm64) echo "linux-arm64" ;;
                armv7l) echo "linux-arm" ;;
                *) echo "linux-$arch" ;;
            esac
            ;;
        darwin)
            case "$arch" in
                x86_64|amd64) echo "darwin-amd64" ;;
                arm64|aarch64) echo "darwin-arm64" ;;
                *) echo "darwin-$arch" ;;
            esac
            ;;
        *)
            echo "unknown"
            ;;
    esac
}

get_download_url() {
    local platform=$1
    local base_url="https://strecoin.com/downloads"
    
    # Für Test/Local: Umgebungsvariable überschreibt
    if [ -n "$STRECOIN_INSTALL_URL" ]; then
        base_url="$STRECOIN_INSTALL_URL"
    fi
    
    echo "$base_url/strecoin-$platform"
}

# ─────────────────────────────────────────────────────────────────────────────
# Prüfungen
# ─────────────────────────────────────────────────────────────────────────────
check_requirements() {
    log_step "System-Prüfung"
    
    # OS prüfen
    PLATFORM=$(detect_platform)
    if [ "$PLATFORM" = "unknown" ]; then
        log_error "Unbekanntes Betriebssystem: $(uname -s)"
        log_info "Unterstützt: Linux (x64, ARM64), macOS (Intel, Apple Silicon)"
        exit 1
    fi
    
    log_info "Erkannt: ${BOLD}$PLATFORM${NC}"
    
    # curl oder wget prüfen
    if command -v curl &> /dev/null; then
        DOWNLOADER="curl"
    elif command -v wget &> /dev/null; then
        DOWNLOADER="wget"
    else
        log_error "Weder 'curl' noch 'wget' gefunden."
        log_info "Bitte installiere eines davon und versuche es erneut."
        exit 1
    fi
    
    log_info "Downloader: $DOWNLOADER"
    
    # Speicher prüfen (min. 100MB frei)
    local avail_mb
    if [ "$PLATFORM" = "darwin-amd64" ] || [ "$PLATFORM" = "darwin-arm64" ]; then
        avail_mb=$(df -m "$HOME" | tail -1 | awk '{print $4}')
    else
        avail_mb=$(df --output=avail "$HOME" | tail -1 | tr -d ' ')
        # In MB umrechnen (1K-Blöcke)
        avail_mb=$((avail_mb / 1024))
    fi
    
    if [ "$avail_mb" -lt 100 ]; then
        log_warn "Nur ${avail_mb}MB freier Speicher (empfohlen: 100MB+)"
    else
        log_info "Speicher: ${avail_mb}MB verfügbar"
    fi
    
    log_success "System-Prüfung bestanden"
}

# ─────────────────────────────────────────────────────────────────────────────
# Download
# ─────────────────────────────────────────────────────────────────────────────
download_binary() {
    log_step "Download"
    
    local url
    url=$(get_download_url "$PLATFORM")
    
    log_info "Lade StreCoin Binary herunter..."
    log_info "URL: $url"
    
    mkdir -p "$INSTALL_DIR"
    local tmp_file="$INSTALL_DIR/.strecoin.download"
    
    if [ "$DOWNLOADER" = "curl" ]; then
        if ! curl -fsSL --connect-timeout 30 --max-time 300 "$url" -o "$tmp_file" 2>/dev/null; then
            log_error "Download fehlgeschlagen (curl exit code: $?)"
            rm -f "$tmp_file"
            exit 1
        fi
    else
        if ! wget -q --timeout=30 --tries=3 "$url" -O "$tmp_file" 2>/dev/null; then
            log_error "Download fehlgeschlagen (wget exit code: $?)"
            rm -f "$tmp_file"
            exit 1
        fi
    fi
    
    # Überprüfe ob Datei existiert und nicht leer ist
    if [ ! -s "$tmp_file" ]; then
        log_error "Downloaded Datei ist leer"
        rm -f "$tmp_file"
        exit 1
    fi
    
    # Verschiebe an finale Position
    mv "$tmp_file" "$INSTALL_DIR/$BIN_NAME"
    chmod +x "$INSTALL_DIR/$BIN_NAME"
    
    log_success "Download abgeschlossen ($(du -h "$INSTALL_DIR/$BIN_NAME" | cut -f1))"
}

# ─────────────────────────────────────────────────────────────────────────────
# Installation
# ─────────────────────────────────────────────────────────────────────────────
install_strecoin() {
    log_step "Installation"
    
    # Verzeichnisse erstellen
    mkdir -p "$DATA_DIR" "$DATA_DIR/logs"
    
    # Start-Skript erstellen
    cat > "$INSTALL_DIR/start.sh" <<EOF
#!/bin/bash
# StreCoin Start-Skript
# Autogeneriert durch install.sh

INSTALL_DIR="$INSTALL_DIR"
DATA_DIR="$DATA_DIR"
export STRECOIN_SEED_HOSTS="$SEED_HOSTS"

cd "\$INSTALL_DIR"

# Prüfe ob bereits läuft
if pgrep -f "\$INSTALL_DIR/$BIN_NAME" > /dev/null; then
    echo "StreCoin läuft bereits!"
    echo "Dashboard: http://localhost:$API_PORT"
    exit 0
fi

echo "Starte StreCoin..."
echo "Dashboard wird verfügbar unter: http://localhost:$API_PORT"
echo ""

# Starte mit nohup für Hintergrund-Operation
exec "\$INSTALL_DIR/$BIN_NAME" \\
    --port "$API_PORT" \\
    --p2p-port "$P2P_PORT" \\
    --data "\$DATA_DIR" \\
    "\$@"
EOF
    chmod +x "$INSTALL_DIR/start.sh"
    
    # Autostart einrichten (je nach System)
    setup_autostart
    
    log_success "Installation abgeschlossen"
}

# ─────────────────────────────────────────────────────────────────────────────
# Autostart
# ─────────────────────────────────────────────────────────────────────────────
setup_autostart() {
    local os
    os=$(uname -s)
    
    case "$os" in
        Darwin)
            setup_macos_autostart
            ;;
        Linux)
            setup_linux_autostart
            ;;
    esac
}

setup_macos_autostart() {
    log_info "Richte macOS Autostart ein (launchd)..."
    
    local plist_path="$HOME/Library/LaunchAgents/com.strecoin.plist"
    
    cat > "$plist_path" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.strecoin</string>
    <key>ProgramArguments</key>
    <array>
        <string>$INSTALL_DIR/start.sh</string>
        <string>--no-browser</string>
    </array>
    <key>WorkingDirectory</key>
    <string>$INSTALL_DIR</string>
    <key>KeepAlive</key>
    <true/>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardOutPath</key>
    <string>$DATA_DIR/logs/strecoin.log</string>
    <key>StandardErrorPath</key>
    <string>$DATA_DIR/logs/strecoin.log</string>
</dict>
</plist>
EOF
    
    # Versuche zu laden (scheitert still falls nicht möglich)
    if command -v launchctl &> /dev/null; then
        launchctl load "$plist_path" 2>/dev/null || true
    fi
    
    log_success "Autostart eingerichtet (launchd)"
    log_info "Manuell starten: launchctl load ~/Library/LaunchAgents/com.strecoin.plist"
}

setup_linux_autostart() {
    # Prüfe ob systemd verfügbar (nicht auf allen Linux-Systemen)
    if command -v systemctl &> /dev/null && [ -d "$HOME/.config" ]; then
        log_info "Richte Linux Autostart ein (systemd user service)..."
        
        mkdir -p "$HOME/.config/systemd/user"
        
        cat > "$HOME/.config/systemd/user/strecoin.service" <<EOF
[Unit]
Description=StreCoin Blockchain Node
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
WorkingDirectory=$INSTALL_DIR
ExecStart=$INSTALL_DIR/start.sh --no-browser
Restart=always
RestartSec=10
Environment="STRECOIN_SEED_HOSTS=$SEED_HOSTS"

[Install]
WantedBy=default.target
EOF
        
        systemctl --user daemon-reload 2>/dev/null || true
        systemctl --user enable strecoin.service 2>/dev/null || true
        
        log_success "Autostart eingerichtet (systemd)"
        log_info "Manuell starten: systemctl --user start strecoin"
    else
        # Fallback: Desktop-Entry für GUI-Autostart
        if [ -d "$HOME/.config/autostart" ]; then
            log_info "Richte Desktop Autostart ein..."
            
            cat > "$HOME/.config/autostart/strecoin.desktop" <<EOF
[Desktop Entry]
Type=Application
Name=StreCoin
Exec=$INSTALL_DIR/start.sh
Icon=$INSTALL_DIR/strecoin.png
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Comment=StreCoin Blockchain Node
EOF
            log_success "Desktop Autostart eingerichtet"
        else
            log_warn "Kein Autostart-Mechanismus gefunden"
            log_info "Manuell starten mit: $INSTALL_DIR/start.sh"
        fi
    fi
}

# ─────────────────────────────────────────────────────────────────────────────
# Finale Summary
# ─────────────────────────────────────────────────────────────────────────────
show_summary() {
    log_step "Fertig!"
    
    echo -e "${GREEN}${BOLD}"
    cat <<'EOF'
   ╔══════════════════════════════════════════════════════════════════╗
   ║                                                                  ║
   ║   StreCoin wurde erfolgreich installiert!                        ║
   ║                                                                  ║
   ╚══════════════════════════════════════════════════════════════════╝
EOF
    echo -e "${NC}"
    
    echo -e "   ${BOLD}Installationsort:${NC} $INSTALL_DIR"
    echo -e "   ${BOLD}Datenverzeichnis:${NC} $DATA_DIR"
    echo -e "   ${BOLD}Dashboard:${NC} ${CYAN}http://localhost:$API_PORT${NC}"
    echo ""
    
    echo -e "   ${BOLD}Schnellbefehle:${NC}"
    echo -e "   • Starten:     ${CYAN}$INSTALL_DIR/start.sh${NC}"
    echo -e "   • Status:      ${CYAN}curl -s http://localhost:$API_PORT/api/system/status${NC}"
    echo -e "   • Logs:        ${CYAN}tail -f $DATA_DIR/logs/strecoin.log${NC}"
    echo ""
    
    echo -e "   ${BOLD}Nächste Schritte:${NC}"
    echo -e "   1. Öffne das Dashboard: ${CYAN}http://localhost:$API_PORT${NC}"
    echo -e "   2. Erstelle ein Wallet und initialisiere deinen ersten Node"
    echo -e "   3. Beginne mit dem Mining oder trete dem Netzwerk bei"
    echo ""
    
    # Prüfe ob Terminal interaktiv ist und frage nach sofortigem Start
    if [ -t 1 ] && [ -z "$STRECOIN_SKIP_START" ]; then
        echo -n "   Soll StreCoin jetzt gestartet werden? [J/n]: "
        read -r response
        if [[ ! "$response" =~ ^[Nn]$ ]]; then
            echo ""
            log_info "Starte StreCoin..."
            "$INSTALL_DIR/start.sh" &
            sleep 2
            log_success "StreCoin läuft! Dashboard: http://localhost:$API_PORT"
            
            # Versuche Browser zu öffnen
            if command -v open &> /dev/null; then
                open "http://localhost:$API_PORT" || true
            elif command -v xdg-open &> /dev/null; then
                xdg-open "http://localhost:$API_PORT" &>/dev/null || true
            fi
        fi
    fi
}

# ─────────────────────────────────────────────────────────────────────────────
# Hauptprogramm
# ─────────────────────────────────────────────────────────────────────────────
main() {
    # Argumente parsen
    while [[ $# -gt 0 ]]; do
        case $1 in
            --skip-start)
                export STRECOIN_SKIP_START=1
                shift
                ;;
            --install-dir)
                INSTALL_DIR="$2"
                DATA_DIR="$INSTALL_DIR/data"
                shift 2
                ;;
            --help|-h)
                echo "StreCoin Installer"
                echo ""
                echo "Verwendung: curl -sSL strecoin.com/install | bash"
                echo ""
                echo "Optionen:"
                echo "  --skip-start      Nicht automatisch starten"
                echo "  --install-dir PFAD  Anderes Installationsverzeichnis"
                echo ""
                exit 0
                ;;
            *)
                shift
                ;;
        esac
    done
    
    show_banner
    check_requirements
    download_binary
    install_strecoin
    show_summary
}

main "$@"
