#!/bin/bash
#
# Git-Helper für Ubuntu Touch Entwicklung
# Version: 1.7
# Autor: darklithium <dev@darklithium.de>
#
# Zweck: Narrensicheres Git für Entwickler
# - Einfache Befehle für häufige Git-Operationen
# - Automatische Branch-Naming
# - Konsistente Workflows
#
# Verwendung:
#   ./git-helper.sh <befehl> [argumente]
#
# Beispiele:
#   ./git-helper.sh status
#   ./git-helper.sh new-feature login-system
#   ./git-helper.sh merge-stable

# --- KONFIGURATION ---
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
if [[ -z "$REPO_ROOT" ]]; then
    echo "❌ Nicht in einem Git-Repository!"
    echo "   → cd /pfad/zu/deinem/git/repo"
    exit 1
fi

CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | sed 's/refs\/heads\///')
MAINTAINER="darklithium <dev@darklithium.de>"

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

# --- FUNKTIONEN ---

# Hilfstext anzeigen
show_help() {
    cat << EOF
📖 Git-Helper v1.7 - Hilfstext

Verfügbare Befehle:

  📊 STATUS & INFO
    status                  Zeigt Git-Status an
    branches                Liste alle Branches
    log                     Zeigt Commit-Historie
    diff                    Zeigt unstaged Änderungen
    diff-staged             Zeigt staged Änderungen

  🌿 BRANCHES
    new-feature <name>     Erstellt Feature-Branch (Basis: testing)
    new-bugfix <name>      Erstellt Bugfix-Branch (Basis: testing)
    new-hotfix <name>      Erstellt Hotfix-Branch (Basis: stable)
    switch <branch>        Wechselt zu Branch
    delete <branch>        Löscht Branch (lokal)

  🔄 MERGE & REBASE
    merge-stable           Merged testing → stable
    merge-testing          Merged feature/* → testing
    rebase-testing        Rebase aktuellen Branch auf testing

  📤 PUSH & PULL
    push                    Pushed aktuellen Branch
    pull                    Pullt Änderungen
    push-all               Pushed alle Branches
    fetch                   Fetched alle Remote-Branches

  🏷️ TAGS
    tag <version>          Erstellt Tag (z. B. v1.0.0)
    tag-push <version>    Pushed Tag zum Remote
    tags                   Liste alle Tags

  📝 COMMITS
    commit <msg>           Erstellt Commit mit Message
    amend                 Ändert letzten Commit
    revert <commit>       Revertet einen Commit

  🧹 AUFRÄUMEN
    cleanup                Löscht gemergte Branches
    cleanup-all            Löscht alle lokalen Branches außer stable/testing

  📋 REVIEW
    review                 Zeigt Commits zur Review
    review-last            Zeigt letzten Commit detailliert

  ❓ HILFE
    help                   Zeigt diesen Hilfstext
    version                Zeigt Version

Beispiele:
  ./git-helper.sh new-feature login-system
  ./git-helper.sh switch testing
  ./git-helper.sh merge-stable
  ./git-helper.sh push

EOF
}

# Zeigt aktuellen Status
cmd_status() {
    echo ""
    echo -e "${BLUE}=== Git-Status ===${NC}"
    echo ""
    echo -e "${YELLOW}Repository:${NC} $REPO_ROOT"
    echo -e "${YELLOW}Aktueller Branch:${NC} $CURRENT_BRANCH"
    echo ""

    # Branch-Status
    if [[ "$CURRENT_BRANCH" == "stable" || "$CURRENT_BRANCH" == "testing" ]]; then
        echo -e "${GREEN}✅ Haupt-Branch${NC}"
    elif [[ "$CURRENT_BRANCH" =~ ^feature/ ]]; then
        echo -e "${BLUE}📌 Feature-Branch${NC}"
    elif [[ "$CURRENT_BRANCH" =~ ^bugfix/ ]]; then
        echo -e "${RED}🐛 Bugfix-Branch${NC}"
    elif [[ "$CURRENT_BRANCH" =~ ^hotfix/ ]]; then
        echo -e "${RED}🚨 Hotfix-Branch${NC}"
    else
        echo -e "${YELLOW}⚠️  Unbekannter Branch-Typ${NC}"
    fi

    echo ""
    echo -e "${YELLOW}Änderungen:${NC}"
    git status --short
    echo ""

    echo -e "${YELLOW}Remote-Status:${NC}"
    git remote -v
    echo ""
}

# Liste alle Branches
cmd_branches() {
    echo ""
    echo -e "${BLUE}=== Alle Branches ===${NC}"
    echo ""
    echo -e "${GREEN}🟢 Haupt-Branches:${NC}"
    git branch | grep -E '^\*?\s*(stable|testing|main|master)$' | sed 's/^[ *]//'
    echo ""
    echo -e "${BLUE}📌 Feature-Branches:${NC}"
    git branch | grep -E '^\*?\s*feature/' | sed 's/^[ *]//'
    echo ""
    echo -e "${RED}🐛 Bugfix-Branches:${NC}"
    git branch | grep -E '^\*?\s*bugfix/' | sed 's/^[ *]//'
    echo ""
    echo -e "${RED}🚨 Hotfix-Branches:${NC}"
    git branch | grep -E '^\*?\s*hotfix/' | sed 's/^[ *]//'
}

# Zeigt Commit-Historie
cmd_log() {
    echo ""
    echo -e "${BLUE}=== Commit-Historie ===${NC}"
    echo ""
    git log --oneline --graph --all -20
    echo ""
}

# Zeigt unstaged Änderungen
cmd_diff() {
    echo ""
    echo -e "${BLUE}=== Unstaged Änderungen ===${NC}"
    echo ""
    git diff
}

# Zeigt staged Änderungen
cmd_diff_staged() {
    echo ""
    echo -e "${BLUE}=== Staged Änderungen ===${NC}"
    echo ""
    git diff --cached
}

# Erstellt Feature-Branch
cmd_new_feature() {
    local branch_name="feature/$1"
    if [[ -z "$1" ]]; then
        echo -e "${RED}❌ Fehlender Branch-Name!${NC}"
        echo "   → ./git-helper.sh new-feature <name>"
        exit 1
    fi

    # Prüfe ob Branch schon existiert
    if git show-ref --verify --quiet refs/heads/"$branch_name"; then
        echo -e "${RED}❌ Branch '$branch_name' existiert bereits!${NC}"
        exit 1
    fi

    # Basis-Branch prüfen (sollte testing sein)
    if git show-ref --verify --quiet refs/heads/testing; then
        BASE_BRANCH="testing"
    elif git show-ref --verify --quiet refs/heads/stable; then
        BASE_BRANCH="stable"
        echo -e "${YELLOW}⚠️  testing-Branch nicht gefunden, verwende stable${NC}"
    else
        echo -e "${RED}❌ Basis-Branch (testing oder stable) nicht gefunden!${NC}"
        exit 1
    fi

    # Branch erstellen und wechseln
    git checkout -b "$branch_name" "$BASE_BRANCH"
    echo -e "${GREEN}✅ Feature-Branch '$branch_name' erstellt (Basis: $BASE_BRANCH)${NC}"
    echo "   → git push --set-upstream origin $branch_name"
}

# Erstellt Bugfix-Branch
cmd_new_bugfix() {
    local branch_name="bugfix/$1"
    if [[ -z "$1" ]]; then
        echo -e "${RED}❌ Fehlender Branch-Name!${NC}"
        echo "   → ./git-helper.sh new-bugfix <name>"
        exit 1
    fi

    # Prüfe ob Branch schon existiert
    if git show-ref --verify --quiet refs/heads/"$branch_name"; then
        echo -e "${RED}❌ Branch '$branch_name' existiert bereits!${NC}"
        exit 1
    fi

    # Basis-Branch prüfen
    if git show-ref --verify --quiet refs/heads/testing; then
        BASE_BRANCH="testing"
    elif git show-ref --verify --quiet refs/heads/stable; then
        BASE_BRANCH="stable"
        echo -e "${YELLOW}⚠️  testing-Branch nicht gefunden, verwende stable${NC}"
    else
        echo -e "${RED}❌ Basis-Branch (testing oder stable) nicht gefunden!${NC}"
        exit 1
    fi

    git checkout -b "$branch_name" "$BASE_BRANCH"
    echo -e "${GREEN}✅ Bugfix-Branch '$branch_name' erstellt (Basis: $BASE_BRANCH)${NC}"
    echo "   → git push --set-upstream origin $branch_name"
}

# Erstellt Hotfix-Branch
cmd_new_hotfix() {
    local branch_name="hotfix/$1"
    if [[ -z "$1" ]]; then
        echo -e "${RED}❌ Fehlender Branch-Name!${NC}"
        echo "   → ./git-helper.sh new-hotfix <name>"
        exit 1
    fi

    # Prüfe ob Branch schon existiert
    if git show-ref --verify --quiet refs/heads/"$branch_name"; then
        echo -e "${RED}❌ Branch '$branch_name' existiert bereits!${NC}"
        exit 1
    fi

    # Hotfix muss von stable kommen
    if ! git show-ref --verify --quiet refs/heads/stable; then
        echo -e "${RED}❌ stable-Branch nicht gefunden!${NC}"
        echo "   → Hotfix-Branches müssen von stable ausgehen"
        exit 1
    fi

    git checkout -b "$branch_name" stable
    echo -e "${GREEN}✅ Hotfix-Branch '$branch_name' erstellt (Basis: stable)${NC}"
    echo "   → git push --set-upstream origin $branch_name"
}

# Wechselt Branch
cmd_switch() {
    if [[ -z "$1" ]]; then
        echo -e "${RED}❌ Fehlender Branch-Name!${NC}"
        echo "   → ./git-helper.sh switch <branch>"
        exit 1
    fi

    # Branch-Namen validieren
    case "$1" in
        stable|testing|feature/*|bugfix/*|hotfix/*|release/*)
            git checkout "$1"
            echo -e "${GREEN}✅ Zu Branch '$1' gewechselt${NC}"
            ;;
        *)
            echo -e "${RED}❌ Ungültiger Branch-Name: '$1'${NC}"
            echo "   → Erlaubt: stable, testing, feature/*, bugfix/*, hotfix/*"
            exit 1
            ;;
    esac
}

# Löscht Branch
cmd_delete() {
    if [[ -z "$1" ]]; then
        echo -e "${RED}❌ Fehlender Branch-Name!${NC}"
        echo "   → ./git-helper.sh delete <branch>"
        exit 1
    fi

    # Nicht stable oder testing löschen
    if [[ "$1" == "stable" || "$1" == "testing" ]]; then
        echo -e "${RED}❌ Cannot delete main branches (stable/testing)!${NC}"
        exit 1
    fi

    # Prüfe ob Branch existiert
    if ! git show-ref --verify --quiet refs/heads/"$1"; then
        echo -e "${RED}❌ Branch '$1' existiert nicht!${NC}"
        exit 1
    fi

    # Prüfe ob Branch aktuell aktiv ist
    if [[ "$1" == "$CURRENT_BRANCH" ]]; then
        echo -e "${RED}❌ Kann aktiven Branch nicht löschen!${NC}"
        echo "   → Wechsle zuerst zu einem anderen Branch"
        exit 1
    fi

    git branch -D "$1"
    echo -e "${GREEN}✅ Branch '$1' gelöscht (lokal)${NC}"
}

# Merged testing → stable
cmd_merge_stable() {
    # Prüfe ob auf stable Branch
    if [[ "$CURRENT_BRANCH" != "stable" ]]; then
        echo -e "${RED}❌ Nicht auf stable-Branch!${NC}"
        echo "   → git checkout stable"
        exit 1
    fi

    # Prüfe ob testing existiert
    if ! git show-ref --verify --quiet refs/heads/testing; then
        echo -e "${RED}❌ testing-Branch existiert nicht!${NC}"
        exit 1
    fi

    echo -e "${YELLOW}🔍 Prüfe ob testing in stable gemerged ist...${NC}"
    if git merge --no-commit --no-ff testing 2>/dev/null; then
        echo -e "${GREEN}✅ testing kann in stable gemerged werden${NC}"
        git merge --no-ff testing -m "merge: testing → stable"
        echo ""
        echo -e "${GREEN}✅ testing erfolgreich in stable gemerged!${NC}"
        echo "   → git push origin stable"
        echo "   → git push origin testing"
    else
        echo -e "${RED}❌ Merge-Konflikte!${NC}"
        echo "   → Konflikte manuell lösen und dann:"
        echo "   → git commit"
        echo "   → git merge --continue"
        exit 1
    fi
}

# Merged feature/* → testing
cmd_merge_testing() {
    # Prüfe ob auf testing Branch
    if [[ "$CURRENT_BRANCH" != "testing" ]]; then
        echo -e "${RED}❌ Nicht auf testing-Branch!${NC}"
        echo "   → git checkout testing"
        exit 1
    fi

    # Zeige alle Feature-Branches
    echo -e "${YELLOW}Verfügbare Feature-Branches:${NC}"
    git branch | grep -E '^\s*feature/' | sed 's/^[ *]//' | sed 's/feature\///'
    echo ""

    # Branch-Namen abfragen
    read -p "Welchen Feature-Branch möchtest du mergen? (Name ohne 'feature/')? " branch_name
    FULL_BRANCH="feature/$branch_name"

    # Prüfe ob Branch existiert
    if ! git show-ref --verify --quiet refs/heads/"$FULL_BRANCH"; then
        echo -e "${RED}❌ Branch '$FULL_BRANCH' existiert nicht!${NC}"
        exit 1
    fi

    echo -e "${YELLOW}🔍 Prüfe ob $FULL_BRANCH in testing gemerged ist...${NC}"
    if git merge --no-commit --no-ff "$FULL_BRANCH" 2>/dev/null; then
        echo -e "${GREEN}✅ $FULL_BRANCH kann in testing gemerged werden${NC}"
        git merge --no-ff "$FULL_BRANCH" -m "merge: $FULL_BRANCH → testing"
        echo ""
        echo -e "${GREEN}✅ $FULL_BRANCH erfolgreich in testing gemerged!${NC}"
        echo "   → git push origin testing"
    else
        echo -e "${RED}❌ Merge-Konflikte!${NC}"
        echo "   → Konflikte manuell lösen und dann:"
        echo "   → git commit"
        echo "   → git merge --continue"
        exit 1
    fi
}

# Rebase auf testing
cmd_rebase_testing() {
    if ! git show-ref --verify --quiet refs/heads/testing; then
        echo -e "${RED}❌ testing-Branch existiert nicht!${NC}"
        exit 1
    fi

    echo -e "${YELLOW}🔍 Rebase $CURRENT_BRANCH auf testing...${NC}"
    if git rebase testing; then
        echo -e "${GREEN}✅ $CURRENT_BRANCH auf testing gerebased!${NC}"
        echo "   → git push --force-with-lease"
    else
        echo -e "${RED}❌ Rebase-Konflikte!${NC}"
        echo "   → Konflikte lösen mit:"
        echo "   → git rebase --continue (wenn gelöst)"
        echo "   → git rebase --abort (zum Abbrechen)"
        exit 1
    fi
}

# Push
cmd_push() {
    if [[ -z "$1" ]]; then
        # Push aktuellen Branch
        git push
        echo -e "${GREEN}✅ $CURRENT_BRANCH gepusht${NC}"
    else
        git push origin "$1"
        echo -e "${GREEN}✅ Branch '$1' gepusht${NC}"
    fi
}

# Pull
cmd_pull() {
    git pull
    echo -e "${GREEN}✅ Änderungen gepullt${NC}"
}

# Push alle Branches
cmd_push_all() {
    git push --all
    echo -e "${GREEN}✅ Alle Branches gepusht${NC}"
}

# Fetch
cmd_fetch() {
    git fetch --all
    echo -e "${GREEN}✅ Alle Remote-Branches gefetched${NC}"
}

# Erstellt Tag
cmd_tag() {
    if [[ -z "$1" ]]; then
        echo -e "${RED}❌ Fehlende Versionsnummer!${NC}"
        echo "   → ./git-helper.sh tag v1.0.0"
        exit 1
    fi

    # Prüfe Format (sollte wie v1.0.0 aussehen)
    if ! [[ "$1" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
        echo -e "${YELLOW}⚠️  Tag-Format sollte vMAJOR.MINOR.PATCH sein (z. B. v1.0.0)${NC}"
        read -p "Fortfahren mit '$1'? (j/n): " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[JjYy]$ ]]; then
            exit 1
        fi
    fi

    git tag -a "$1" -m "Release $1"
    echo -e "${GREEN}✅ Tag '$1' erstellt${NC}"
    echo "   → git-helper.sh tag-push $1"
}

# Pushed Tag
cmd_tag_push() {
    if [[ -z "$1" ]]; then
        echo -e "${RED}❌ Fehlender Tag-Name!${NC}"
        echo "   → ./git-helper.sh tag-push v1.0.0"
        exit 1
    fi

    git push origin "$1"
    echo -e "${GREEN}✅ Tag '$1' gepusht${NC}"
}

# Liste alle Tags
cmd_tags() {
    echo ""
    echo -e "${BLUE}=== Alle Tags ===${NC}"
    echo ""
    git tag -l
}

# Erstellt Commit
cmd_commit() {
    if [[ -z "$1" ]]; then
        echo -e "${RED}❌ Fehlende Commit-Message!${NC}"
        echo "   → ./git-helper.sh commit 'feat: neue Funktion'"
        exit 1
    fi

    # Prüfe Format (sollte Typ: Beschreibung sein)
    if ! [[ "$1" =~ ^[a-z]+:\ .+ ]]; then
        echo -e "${YELLOW}⚠️  Commit-Message sollte Format <Typ>: <Beschreibung> haben${NC}"
        echo "   Beispiel: feat: neue Funktion"
        echo ""
        read -p "Fortfahren mit '$1'? (j/n): " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[JjYy]$ ]]; then
            exit 1
        fi
    fi

    git commit -m "$1"
    echo -e "${GREEN}✅ Commit erstellt: $1${NC}"
}

# Ändert letzten Commit
cmd_amend() {
    if [[ -z "$1" ]]; then
        git commit --amend --no-edit
        echo -e "${GREEN}✅ Letzter Commit geändert (gleiche Message)${NC}"
    else
        git commit --amend -m "$1"
        echo -e "${GREEN}✅ Letzter Commit geändert: $1${NC}"
    fi
}

# Revertet Commit
cmd_revert() {
    if [[ -z "$1" ]]; then
        echo -e "${RED}❌ Fehlende Commit-ID!${NC}"
        echo "   → ./git-helper.sh revert <commit-hash>"
        exit 1
    fi

    git revert "$1"
    echo -e "${GREEN}✅ Commit $1 revertet${NC}"
}

# Löscht gemergte Branches
cmd_cleanup() {
    echo -e "${YELLOW}🔍 Suche gemergte Branches...${NC}"

    # Alle Branches außer stable und testing
    MERGED_BRANCHES=$(git branch --merged stable | grep -v -E '^\*?\s*(stable|testing|main|master)$' | sed 's/^[ *]//' | sed 's/^[[:space:]]*//')

    if [[ -z "$MERGED_BRANCHES" ]]; then
        echo -e "${GREEN}✅ Keine gemergten Branches zum Löschen gefunden${NC}"
        exit 0
    fi

    echo -e "${YELLOW}Gemergte Branches:${NC}"
    echo "$MERGED_BRANCHES"
    echo ""

    read -p "Alle gemergten Branches löschen? (j/n): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[JjYy]$ ]]; then
        for branch in $MERGED_BRANCHES; do
            git branch -D "$branch"
            echo -e "${GREEN}✅ Gelöscht: $branch${NC}"
        done
        echo -e "${GREEN}✅ Alle gemergten Branches gelöscht${NC}"
    else
        echo -e "${YELLOW}❌ Abgebrochen${NC}"
    fi
}

# Löscht alle lokalen Branches außer stable/testing
cmd_cleanup_all() {
    echo -e "${RED}⚠️  WARNING: Dies löscht ALLE lokalen Branches außer stable und testing!${NC}"
    echo ""

    read -p "Fortfahren? (j/n): " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[JjYy]$ ]]; then
        echo -e "${YELLOW}❌ Abgebrochen${NC}"
        exit 0
    fi

    # Alle Branches außer stable und testing
    ALL_BRANCHES=$(git branch | grep -v -E '^\*?\s*(stable|testing|main|master)$' | sed 's/^[ *]//' | sed 's/^[[:space:]]*//')

    if [[ -z "$ALL_BRANCHES" ]]; then
        echo -e "${GREEN}✅ Keine zusätzlichen Branches gefunden${NC}"
        exit 0
    fi

    for branch in $ALL_BRANCHES; do
        git branch -D "$branch"
        echo -e "${GREEN}✅ Gelöscht: $branch${NC}"
    done

    echo -e "${GREEN}✅ Alle lokalen Branches (außer stable/testing) gelöscht${NC}"
}

# Zeigt Commits zur Review
cmd_review() {
    echo ""
    echo -e "${BLUE}=== Commits zur Review (nicht gepusht) ===${NC}"
    echo ""
    git log --oneline origin/$CURRENT_BRANCH..$CURRENT_BRANCH
    echo ""

    if [[ $? -eq 0 && -n "$(git log --oneline origin/$CURRENT_BRANCH..$CURRENT_BRANCH 2>/dev/null)" ]]; then
        echo -e "${YELLOW}📝 Tipp: Nutze diese Commits für Code-Review${NC}"
    fi
}

# Zeigt letzten Commit detailliert
cmd_review_last() {
    echo ""
    echo -e "${BLUE}=== Letzter Commit ===${NC}"
    echo ""
    git show HEAD --stat
    echo ""
}

# Zeigt Version
cmd_version() {
    echo "Git-Helper v1.7"
    echo "Framework: START-UT-DEV 1.7"
    echo "Maintainer: darklithium <dev@darklithium.de>"
    echo "Stand: 30.05.2026"
}

# --- HAUPTPROGRAMM ---

# Keine Argumente → Hilfe anzeigen
if [[ $# -eq 0 ]]; then
    show_help
    exit 0
fi

# Command Dispatch
COMMAND="$1"
shift

case "$COMMAND" in
    status)          cmd_status ;;
    branches)        cmd_branches ;;
    log)             cmd_log ;;
    diff)            cmd_diff ;;
    diff-staged)     cmd_diff_staged ;;

    new-feature)     cmd_new_feature "$1" ;;
    new-bugfix)      cmd_new_bugfix "$1" ;;
    new-hotfix)      cmd_new_hotfix "$1" ;;

    switch)          cmd_switch "$1" ;;
    delete)          cmd_delete "$1" ;;

    merge-stable)    cmd_merge_stable ;;
    merge-testing)   cmd_merge_testing ;;
    rebase-testing)  cmd_rebase_testing ;;

    push)            cmd_push "$1" ;;
    pull)            cmd_pull ;;
    push-all)        cmd_push_all ;;
    fetch)           cmd_fetch ;;

    tag)             cmd_tag "$1" ;;
    tag-push)        cmd_tag_push "$1" ;;
    tags)            cmd_tags ;;

    commit)          cmd_commit "$*" ;;
    amend)           cmd_amend "$*" ;;
    revert)          cmd_revert "$1" ;;

    cleanup)         cmd_cleanup ;;
    cleanup-all)     cmd_cleanup_all ;;

    review)          cmd_review ;;
    review-last)     cmd_review_last ;;

    help)            show_help ;;
    version)         cmd_version ;;

    *)
        echo -e "${RED}❌ Unbekannter Befehl: $COMMAND${NC}"
        echo ""
        show_help
        exit 1
        ;;
esac
