#!/usr/bin/env bash
# git_clean_branches
# ------------------
# Elimina ramas locales ya mergeadas en la rama base (main/master por defecto).
# Opcionalmente también elimina las ramas en remotes.
#
# USO:
#   source git_clean_branches.sh
#   git_clean_branches [base_branch] [--remote] [--force]
#
# ARGUMENTOS:
#   base_branch  Rama base (opcional; autodetecta main/master si se omite)
#   --remote     Elimina también las ramas en todos los remotes
#   --force      Omite confirmación interactiva

git_clean_branches() {
    local base_branch=""
    local delete_remote=false
    local force=false

    # Parsear argumentos
    for arg in "$@"; do
        case "$arg" in
            --remote) delete_remote=true ;;
            --force)  force=true ;;
            *)        [[ -z "$base_branch" ]] && base_branch="$arg" ;;
        esac
    done

    # Validar repo
    if ! git rev-parse --is-inside-work-tree &>/dev/null; then
        echo "git_clean_branches: el directorio actual no es un repositorio Git" >&2
        return 1
    fi

    # Detectar rama base
    if [[ -z "$base_branch" ]]; then
        if git show-ref --verify --quiet refs/heads/main; then
            base_branch="main"
        elif git show-ref --verify --quiet refs/heads/master; then
            base_branch="master"
        else
            echo "git_clean_branches: no se detectó main/master; pasa la rama base como argumento" >&2
            return 1
        fi
    fi

    echo "git_clean_branches: rama base = ${base_branch}"

    # Hacer prune de referencias remotas obsoletas
    echo "Haciendo prune de referencias remotas..."
    git remote | while IFS= read -r remote; do
        git remote prune "$remote" 2>/dev/null && echo "  Pruned: ${remote}"
    done
    echo ""

    # Buscar ramas locales mergeadas
    local candidates
    candidates="$(git branch --merged "$base_branch" \
        | grep -v -E "^\*|^\s*(main|master|develop|dev|staging|release)$" \
        | sed 's/^[[:space:]]*//' \
        | grep -v "^$" || true)"

    if [[ -z "$candidates" ]]; then
        echo "No hay ramas locales mergeadas para eliminar."
        return 0
    fi

    echo "Ramas candidatas a eliminar:"
    echo "$candidates" | while IFS= read -r b; do
        echo "  - ${b}"
    done
    echo ""

    # Confirmación (omitir si --force)
    if [[ "$force" != true ]]; then
        echo -n "¿Eliminar estas ramas locales? [y/N] "
        read -r answer
        [[ "$answer" != "y" && "$answer" != "Y" ]] && { echo "Operación cancelada."; return 0; }
    fi

    # Eliminar ramas locales
    local deleted=0
    local failed=0
    while IFS= read -r branch; do
        if git branch -d "$branch"; then
            echo "  Eliminada local: ${branch}"
            deleted=$((deleted + 1))
        else
            echo "  No se pudo eliminar: ${branch}" >&2
            failed=$((failed + 1))
        fi
    done <<< "$candidates"

    echo ""
    echo "Resumen: ${deleted} eliminada(s), ${failed} fallida(s)"

    # Eliminar en remotes si se solicitó
    if [[ "$delete_remote" == true ]]; then
        local remotes
        remotes="$(git remote 2>/dev/null || true)"
        if [[ -n "$remotes" ]]; then
            echo ""
            echo "Eliminando ramas en remotes..."
            while IFS= read -r branch; do
                while IFS= read -r remote; do
                    if git ls-remote --heads "$remote" "$branch" 2>/dev/null | grep -q "$branch"; then
                        if git push "$remote" --delete "$branch"; then
                            echo "  Eliminada remota: ${remote}/${branch}"
                        else
                            echo "  No se pudo eliminar remota: ${remote}/${branch}" >&2
                        fi
                    fi
                done <<< "$remotes"
            done <<< "$candidates"
        fi
    fi

    echo ""
    echo "Limpieza completada."
}

# Ejecutar si se invoca directamente
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    git_clean_branches "$@"
fi
