#!/usr/bin/env bash
set -euo pipefail

# Voltar para um commit (3 modos):
#
# 1) Só "ver" o estado do commit (detached HEAD, não altera seu branch)
#    ./git-back.sh <commit>
#
# 2) Criar um branch novo a partir do commit
#    ./git-back.sh <commit> branch <novo-branch>
#
# 3) RESETAR o branch atual para o commit (ALERTA: reescreve histórico local)
#    ./git-back.sh <commit> reset
#
# Opcional: forçar push do reset para o remoto (MUITO PERIGOSO)
#    ./git-back.sh <commit> reset --push origin main
#
# Dica: para "desfazer" um commit sem reescrever histórico, use:
#   git revert <commit>

COMMIT="${1:-}"
MODE="${2:-view}"

if [[ -z "$COMMIT" ]]; then
  echo "Uso:" >&2
  echo "  $0 <commit>                       # checkout (detached) para inspecionar" >&2
  echo "  $0 <commit> branch <novo-branch>  # cria branch a partir do commit" >&2
  echo "  $0 <commit> reset [--push <remote> <branch>]  # hard reset (perigoso)" >&2
  exit 1
fi

git rev-parse --is-inside-work-tree >/dev/null 2>&1 || {
  echo "Erro: não é um repositório git." >&2
  exit 1
}

# valida commit
git cat-file -e "${COMMIT}^{commit}" 2>/dev/null || {
  echo "Erro: commit inválido/não encontrado: $COMMIT" >&2
  exit 1
}

case "$MODE" in
  ""|"view")
    # Detached HEAD: bom para testar/inspecionar sem mexer no branch.
    git checkout --detach "$COMMIT"
    echo "OK: você está em detached HEAD no commit $COMMIT"
    echo "Para voltar ao branch: git checkout <seu-branch>"
    ;;

  "branch")
    NEW_BRANCH="${3:-}"
    if [[ -z "$NEW_BRANCH" ]]; then
      echo "Uso: $0 <commit> branch <novo-branch>" >&2
      exit 1
    fi
    git checkout -b "$NEW_BRANCH" "$COMMIT"
    echo "OK: branch '$NEW_BRANCH' criado no commit $COMMIT"
    ;;

  "reset")
    # hard reset: descarta mudanças locais e move o branch atual para o commit.
    # exigir working tree limpa pra evitar perda acidental.
    if [[ -n "$(git status --porcelain)" ]]; then
      echo "Erro: seu working tree não está limpo. Faça commit/stash antes de resetar." >&2
      exit 1
    fi

    git reset --hard "$COMMIT"
    echo "OK: branch atual foi resetado para $COMMIT (HARD RESET)"

    if [[ "${3:-}" == "--push" ]]; then
      REMOTE="${4:-}"
      BRANCH="${5:-}"
      if [[ -z "$REMOTE" || -z "$BRANCH" ]]; then
        echo "Uso: $0 <commit> reset --push <remote> <branch>" >&2
        exit 1
      fi
      echo "ATENÇÃO: isso vai reescrever o histórico no remoto ($REMOTE/$BRANCH)."
      git push --force-with-lease "$REMOTE" "HEAD:$BRANCH"
      echo "OK: force push com --force-with-lease em $REMOTE/$BRANCH"
    fi
    ;;

  *)
    echo "Modo inválido: $MODE" >&2
    exit 1
    ;;
esac

