#!/bin/bash

################################################################################
# Paperless-ngx Automatische Installation
################################################################################
#
# Was macht dieses Skript?
# ------------------------
# Dieses Skript richtet dir eine komplette Paperless-ngx Umgebung ein - ein
# schickes Dokumenten-Management-System, mit dem du deine ganzen Papiere
# digitalisieren und durchsuchbar machen kannst. Stell dir vor wie Evernote,
# aber für eingescannte Rechnungen, Verträge und den ganzen Papierkram.
#
# Das Skript kümmert sich um:
# - Docker Installation (falls noch nicht vorhanden)
# - Eine saubere Verzeichnisstruktur unter /opt und /var/lib
# - Paperless-ngx mit PostgreSQL Datenbank
# - Redis für die Queue/Cache-Verwaltung
# - Portainer Agent, damit du deine Container bequem verwalten kannst
# - Praktische Helper-Skripte für Status, Logs, Backups und Updates
#
# Nach dem Durchlauf hast du:
# - Paperless-ngx auf Port 8000
# - Portainer Agent auf Port 9001
# - Alle Daten schön sortiert in /var/lib/paperless-ngx
# - Backup-Ordner unter /var/backups/paperless-ngx
#
# Zeitaufwand: ~5-10 Minuten (je nach Internetverbindung)
#
################################################################################

# Wenn irgendwas schiefgeht, hör sofort auf - keinen Murks hinterlassen
set -e

echo "================================================"
echo "Paperless-ngx Installation + Portainer Agent"
echo "================================================"
echo ""

# Ein bisschen Farbe schadet nie - macht die Ausgabe lesbarer
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# Hier legen wir fest, wo was hinkommt
# /opt = Programme und Configs (das ist der Linux-Standard für sowas)
# /var/lib = Daten die sich ändern (Datenbanken, Dokumente, etc.)
# /var/backups = Na Rate mal... Backups halt
INSTALL_BASE="/opt/paperless-ngx"
DATA_BASE="/var/lib/paperless-ngx"
BACKUP_BASE="/var/backups/paperless-ngx"

echo -e "${BLUE}Verzeichnisstruktur:${NC}"
echo "  Installation: $INSTALL_BASE"
echo "  Daten:        $DATA_BASE"
echo "  Backups:      $BACKUP_BASE"
echo ""

################################################################################
# Schritt 1: System auf aktuellen Stand bringen
################################################################################
# Bevor wir loslegen, holen wir uns die neuesten Paketinfos und Updates
# Das verhindert komische Versionskonflikte später
echo -e "${GREEN}[1/13] System wird aktualisiert...${NC}"
sudo apt update && sudo apt upgrade -y

################################################################################
# Schritt 2: Grundlegende Tools installieren
################################################################################
# Diese Tools brauchen wir, um Docker sicher zu installieren
# ca-certificates = Für HTTPS-Verbindungen
# curl = Zum Runterladen von Dateien
# gnupg = Für die Signatur-Überprüfung der Docker-Pakete
echo ""
echo -e "${GREEN}[2/13] Installiere Abhängigkeiten...${NC}"
sudo apt install -y ca-certificates curl gnupg

################################################################################
# Schritt 3: Docker's GPG-Schlüssel hinzufügen
################################################################################
# Docker signiert seine Pakete digital, damit niemand böse Sachen unterjubeln kann
# Wir holen uns den offiziellen Schlüssel und speichern ihn sicher ab
echo ""
echo -e "${GREEN}[3/13] Füge Docker GPG-Key hinzu...${NC}"

# Erstelle das Verzeichnis für die Schlüssel, falls es noch nicht existiert
sudo install -m 0755 -d /etc/apt/keyrings

# Lade den Docker GPG-Schlüssel runter und konvertiere ihn ins richtige Format
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# Mach den Schlüssel für alle lesbar (aber nicht beschreibbar!)
sudo chmod a+r /etc/apt/keyrings/docker.gpg

################################################################################
# Schritt 4: Docker Repository hinzufügen
################################################################################
# Jetzt sagen wir dem Paketmanager: "Hey, hol dir Docker von der offiziellen Quelle!"
# Die Version aus den Debian-Repos ist meistens veraltet, deshalb nehmen wir die direkt von Docker
echo ""
echo -e "${GREEN}[4/13] Füge Docker Repository hinzu...${NC}"
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

################################################################################
# Schritt 5: Docker installieren
################################################################################
# Jetzt wird's ernst - wir installieren Docker und alle dazugehörigen Tools
# docker-ce = Docker Engine (das Herzstück)
# docker-ce-cli = Kommandozeilen-Tool
# containerd.io = Container Runtime
# docker-compose-plugin = Für Multi-Container Apps (brauchen wir für Paperless!)
echo ""
echo -e "${GREEN}[5/13] Installiere Docker...${NC}"
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

################################################################################
# Schritt 6: Benutzer zur Docker-Gruppe hinzufügen
################################################################################
# Normalerweise braucht man sudo für Docker-Befehle
# Indem wir uns zur docker-Gruppe hinzufügen, können wir Docker ohne sudo nutzen
# Aber Achtung: Das wird erst nach dem nächsten Login aktiv!
echo ""
echo -e "${GREEN}[6/13] Füge Benutzer zur Docker-Gruppe hinzu...${NC}"
sudo usermod -aG docker $USER

################################################################################
# Schritt 7: Verzeichnisstruktur aufbauen
################################################################################
# Jetzt bauen wir die Ordnerstruktur auf - alles schön organisiert
# So weiß man später noch, wo was liegt (auch nach 6 Monaten noch!)
echo ""
echo -e "${GREEN}[7/13] Erstelle Verzeichnisstruktur...${NC}"

# Die drei Hauptordner
sudo mkdir -p $INSTALL_BASE    # Hier landen docker-compose.yml und Configs
sudo mkdir -p $DATA_BASE       # Hier kommen alle Daten rein
sudo mkdir -p $BACKUP_BASE     # Hier landen die Backups

# Unterordner für die verschiedenen Datentypen
# data = SQLite Datenbank (falls du mal von PostgreSQL wechseln willst)
# media = Deine verarbeiteten Dokumente (PDFs mit OCR-Text)
# consume = Der "Eingangskorb" - leg hier neue Dokumente rein, Paperless holt sie sich
# export = Wenn du mal Dokumente exportieren willst, landen sie hier
# postgres = Die PostgreSQL Datenbank-Dateien
# redis = Redis speichert hier seine Daten (für die Job-Queue)
sudo mkdir -p $DATA_BASE/data
sudo mkdir -p $DATA_BASE/media
sudo mkdir -p $DATA_BASE/consume
sudo mkdir -p $DATA_BASE/export
sudo mkdir -p $DATA_BASE/postgres
sudo mkdir -p $DATA_BASE/redis

# Gib dem aktuellen Benutzer die Rechte - sonst hat Docker nachher Probleme
sudo chown -R $USER:$USER $INSTALL_BASE
sudo chown -R $USER:$USER $DATA_BASE
sudo chown -R $USER:$USER $BACKUP_BASE

# Zeig mal was wir gebaut haben (tree ist schöner, aber nicht immer installiert)
echo ""
echo -e "${BLUE}Erstellte Verzeichnisse:${NC}"
tree -L 2 $DATA_BASE 2>/dev/null || ls -la $DATA_BASE

################################################################################
# Schritt 8: Paperless-ngx Config-Dateien holen
################################################################################
# Wir laden die offiziellen Docker Compose Dateien vom Paperless-ngx GitHub
# docker-compose.yml = Definiert welche Container gestartet werden
# docker-compose.env = Umgebungsvariablen (Passwörter, Einstellungen, etc.)
echo ""
echo -e "${GREEN}[8/13] Lade Paperless-ngx Konfiguration herunter...${NC}"
cd $INSTALL_BASE
curl -L https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/docker-compose.postgres.yml -o docker-compose.yml
curl -L https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/docker/compose/docker-compose.env -o docker-compose.env

################################################################################
# Schritt 9: Pfade anpassen
################################################################################
# Die Standard-Config nutzt relative Pfade (./data, ./media, etc.)
# Das ist unpraktisch, weil du dann immer im richtigen Ordner sein musst
# Wir ersetzen das mit absoluten Pfaden zu unseren schön organisierten Ordnern
echo ""
echo -e "${GREEN}[9/13] Passe Verzeichnispfade in docker-compose.yml an...${NC}"

# Erstmal ein Backup - man weiß ja nie
cp docker-compose.yml docker-compose.yml.backup

# Jetzt ersetzen wir alle relativen Pfade mit unseren absoluten Pfaden
# sed = Stream Editor, ein mächtiges Tool für Textersetzungen
# -i = In-place editing (direkt in der Datei ändern)
# s|alt|neu|g = Suche "alt", ersetze mit "neu", global (alle Vorkommen)
sed -i "s|./consume:|$DATA_BASE/consume:|g" docker-compose.yml
sed -i "s|./data:|$DATA_BASE/data:|g" docker-compose.yml
sed -i "s|./media:|$DATA_BASE/media:|g" docker-compose.yml
sed -i "s|./export:|$DATA_BASE/export:|g" docker-compose.yml
sed -i "s|./pgdata:|$DATA_BASE/postgres:|g" docker-compose.yml
sed -i "s|./redisdata:|$DATA_BASE/redis:|g" docker-compose.yml

################################################################################
# Schritt 10: Sicherheits-Secrets generieren
################################################################################
# Der Standard-SECRET_KEY ist "change-me" - das ist natürlich Murks für Produktion
# Wir generieren einen zufälligen 32-Byte Schlüssel und setzen ihn ein
# Dieser Key wird für Session-Cookies und Verschlüsselung verwendet
echo ""
echo -e "${GREEN}[10/13] Generiere Secrets...${NC}"

# openssl rand -base64 32 = Generiere 32 zufällige Bytes, codiere sie als Base64
SECRET_KEY=$(openssl rand -base64 32)
sed -i "s|PAPERLESS_SECRET_KEY=change-me|PAPERLESS_SECRET_KEY=$SECRET_KEY|g" docker-compose.env

################################################################################
# Schritt 11: Portainer Agent starten
################################################################################
# Der Portainer Agent ist dein Freund - damit kannst du später bequem über
# eine Web-UI alle Container verwalten, Logs anschauen, etc.
# Er läuft auf Port 9001 und wartet darauf, dass ein Portainer Server sich verbindet
echo ""
echo -e "${GREEN}[11/13] Starte Portainer Agent...${NC}"

# sg docker -c = Führe den Befehl mit der docker-Gruppe aus (Workaround für die noch nicht aktive Gruppenzugehörigkeit)
# -d = Detached mode (läuft im Hintergrund)
# --restart=always = Startet automatisch nach Reboot oder wenn er abstürzt
# -v = Volume-Mounts, damit der Agent Docker-Infos sehen kann
sg docker -c "docker run -d \
  --name portainer_agent \
  --restart=always \
  -p 9001:9001 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /var/lib/docker/volumes:/var/lib/docker/volumes \
  portainer/agent:latest"

################################################################################
# Schritt 12: Paperless-ngx Container starten
################################################################################
# Jetzt wird Paperless endlich gestartet!
# compose pull = Lade die neuesten Images runter
# compose up -d = Starte alle Container im Hintergrund
echo ""
echo -e "${GREEN}[12/13] Starte Paperless-ngx Container...${NC}"
sg docker -c "docker compose pull"
sg docker -c "docker compose up -d"

################################################################################
# Schritt 13: Kurz warten bis alles hochgefahren ist
################################################################################
# Die Container brauchen ein paar Sekunden zum Starten
# Vor allem PostgreSQL muss erst initialisiert werden beim ersten Start
echo ""
echo -e "${GREEN}[13/13] Warte auf Containerstart...${NC}"
sleep 15

################################################################################
# Convenience-Features einrichten
################################################################################
# Machen wir das Leben noch ein bisschen einfacher...

# Symlink im Home-Verzeichnis, damit du nicht immer /opt/paperless-ngx tippen musst
ln -sf $INSTALL_BASE ~/paperless-ngx

echo ""
echo -e "${GREEN}Erstelle Helper-Skripte...${NC}"

################################################################################
# Status-Skript
################################################################################
# Zeigt dir auf einen Blick, ob alle Container laufen
cat > $INSTALL_BASE/status.sh << 'EOF'
#!/bin/bash
echo "=== Paperless-ngx Container ==="
cd /opt/paperless-ngx
docker compose ps
echo ""
echo "=== Portainer Agent ==="
docker ps -f name=portainer_agent --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
EOF
chmod +x $INSTALL_BASE/status.sh

################################################################################
# Logs-Skript
################################################################################
# Wenn was nicht funktioniert, schau dir die Logs an - hier siehst du alles in Echtzeit
cat > $INSTALL_BASE/logs.sh << 'EOF'
#!/bin/bash
cd /opt/paperless-ngx
docker compose logs -f
EOF
chmod +x $INSTALL_BASE/logs.sh

################################################################################
# Backup-Skript
################################################################################
# Erstellt ein Backup deiner Daten - besser safe als sorry!
# Nutzt den eingebauten document_exporter von Paperless
cat > $INSTALL_BASE/backup.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/var/backups/paperless-ngx"
BACKUP_FILE="$BACKUP_DIR/paperless-backup-$(date +%Y%m%d-%H%M%S).tar.gz"

echo "Erstelle Backup..."
cd /opt/paperless-ngx
docker compose exec -T webserver document_exporter /tmp/export

echo "Komprimiere Backup..."
sudo tar -czf "$BACKUP_FILE" /var/lib/paperless-ngx

echo "Backup erstellt: $BACKUP_FILE"
ls -lh "$BACKUP_FILE"
EOF
chmod +x $INSTALL_BASE/backup.sh

################################################################################
# Update-Skript
################################################################################
# Holt die neuesten Paperless-Updates und startet die Container neu
# Macht vorher automatisch ein Backup - doppelt hält besser!
cat > $INSTALL_BASE/update.sh << 'EOF'
#!/bin/bash
cd /opt/paperless-ngx
echo "Erstelle Backup vor Update..."
./backup.sh
echo ""
echo "Lade neue Images..."
docker compose pull
echo ""
echo "Starte Container neu..."
docker compose down
docker compose up -d
echo ""
echo "Update abgeschlossen!"
./status.sh
EOF
chmod +x $INSTALL_BASE/update.sh

################################################################################
# Abschluss-Info
################################################################################
# Zeig dem Benutzer, was passiert ist und wie es weitergeht
echo ""
echo "================================================"
echo -e "${GREEN}Installation abgeschlossen!${NC}"
echo "================================================"
echo ""
echo -e "${YELLOW}Verzeichnisstruktur:${NC}"
echo "  📁 Installation:  $INSTALL_BASE"
echo "  📁 Daten:         $DATA_BASE"
echo "  📁 Consume:       $DATA_BASE/consume  ← Hier Dokumente reinlegen"
echo "  📁 Export:        $DATA_BASE/export"
echo "  📁 Backups:       $BACKUP_BASE"
echo "  🔗 Symlink:       ~/paperless-ngx → $INSTALL_BASE"
echo ""
echo -e "${YELLOW}Dienste:${NC}"
echo "  📄 Paperless-ngx:   http://$(hostname -I | awk '{print $1}'):8000"
echo "  🐳 Portainer Agent: Port 9001 (für Portainer Server)"
echo ""
echo -e "${YELLOW}Helper-Skripte:${NC}"
echo "  $INSTALL_BASE/status.sh   # Zeigt dir ob alles läuft"
echo "  $INSTALL_BASE/logs.sh     # Live-Logs wenn was nicht klappt"
echo "  $INSTALL_BASE/backup.sh   # Macht ein Backup deiner Dokumente"
echo "  $INSTALL_BASE/update.sh   # Updated Paperless auf die neueste Version"
echo ""
echo -e "${YELLOW}Oder einfacher aus deinem Home:${NC}"
echo "  ~/paperless-ngx/status.sh"
echo "  ~/paperless-ngx/logs.sh"
echo ""
echo "Aktueller Container Status:"
sg docker -c "cd $INSTALL_BASE && docker compose ps"
echo ""
sg docker -c "docker ps -f name=portainer_agent --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'"
echo ""
echo -e "${YELLOW}WICHTIG:${NC} Bitte einmal aus- und wieder einloggen,"
echo "damit die Docker-Gruppenzugehörigkeit vollständig aktiv wird."
echo "Danach kannst du Docker-Befehle ohne sudo nutzen."
echo ""
echo -e "${BLUE}Portainer Agent verbinden:${NC}"
echo "Falls du einen Portainer Server hast, verbinde diesen Agent so:"
echo "  1. Öffne deinen Portainer Server im Browser"
echo "  2. Gehe zu 'Environments' → 'Add environment'"
echo "  3. Wähle 'Agent' aus"
echo "  4. Trage ein: $(hostname -I | awk '{print $1}'):9001"
echo "  5. Klick auf 'Connect' und fertig!"
echo ""
echo "Viel Spaß mit deinem neuen papierlosen Büro! 📄→💾"
echo ""