#!/usr/bin/env bash
set -euo pipefail

readonly ALLOWED_MAIN_BRANCHES=("main" "master" "develop")
readonly BRANCH_TYPES=(
  "feat      For new features"
  "hotfix    For urgent fixes"
  "fix       For fixes"
  "release   For preparing releases"
  "chore     For non-code tasks"
)

error() {
  echo "Error: $1" >&2
  exit 1
}

warn() {
  echo "Warning: $1" >&2
}

check_dependencies() {
  local missing=()
  for cmd in git fzf; do
    if ! command -v "$cmd" &> /dev/null; then
      missing+=("$cmd")
    fi
  done

  if [[ ${#missing[@]} -gt 0 ]]; then
    error "Missing required commands: ${missing[*]}"
  fi
}

check_git_repo() {
  if ! git rev-parse --git-dir &> /dev/null; then
    error "Not in a git repository"
  fi
}

check_current_branch() {
  local current_branch
  current_branch=$(git branch --show-current)

  local is_main_branch=false
  for branch in "${ALLOWED_MAIN_BRANCHES[@]}"; do
    if [[ "$current_branch" == "$branch" ]]; then
      is_main_branch=true
      break
    fi
  done

  if [[ "$is_main_branch" == false ]]; then
    warn "Not branching from a main branch (current: $current_branch)"
    read -rp "Continue anyway? [y/N] " response
    if [[ ! "$response" =~ ^[Yy]$ ]]; then
      exit 0
    fi
  fi
}

get_user_email() {
  local email
  email=$(git config --get user.email 2>/dev/null)

  if [[ -z "$email" ]]; then
    error "Git user email not configured. Run: git config user.email 'your@email.com'"
  fi

  echo "$email"
}

select_branch_type() {
  local selected
  selected=$(printf '%s\n' "${BRANCH_TYPES[@]}" | \
    fzf --prompt="Select branch type: " \
        --height=40% \
        --border \
        --info=inline) || error "Branch type selection cancelled"

  echo "${selected%% *}"
}

select_jira_ticket() {
  local email=$1

  if ! command -v jira &> /dev/null; then
    warn "Jira CLI not found. Proceeding without ticket ID."
    return 0
  fi

  echo "Fetching Jira tickets for $email..." >&2
  local jira_data
  jira_data=$(jira issue list --assignee="$email" --order-by=priority --plain --no-headers 2>/dev/null) || {
    warn "Could not fetch Jira tickets. Proceeding without ticket ID."
    return 0
  }

  if [[ -z "$jira_data" ]]; then
    warn "No Jira tickets found. Proceeding without ticket ID."
    return 0
  fi

  echo "$jira_data" >&2
  echo "" >&2

  local formatted_tickets
  formatted_tickets=$(echo "$jira_data" | awk '{
    ticket_id = $2
    $1 = $2 = ""
    description = $0
    gsub(/^[ \t]+/, "", description)
    if (length(description) > 60) {
      description = substr(description, 1, 57) "..."
    }
    print ticket_id " - " description
  }')

  if [[ -z "$formatted_tickets" ]]; then
    warn "No tickets to display. Proceeding without ticket ID."
    return 0
  fi

  local selected_ticket
  selected_ticket=$(echo -e "SKIP - Create branch without ticket ID\n$formatted_tickets" | \
    fzf --prompt="Select Jira ticket (or skip): " \
        --height=40% \
        --border \
        --info=inline) || error "Ticket selection cancelled"

  if [[ "$selected_ticket" != "SKIP"* ]]; then
    echo "${selected_ticket%% -*}"
  fi
}

get_branch_description() {
  local ticket_id=$1
  local editor="${EDITOR:-vi}"
  local tmpfile
  tmpfile=$(mktemp)

  trap "rm -f '$tmpfile'" EXIT

  if [[ -n "$ticket_id" ]]; then
    cat > "$tmpfile" << EOF
# Selected ticket: $ticket_id
# Enter your branch description below in kebab-case (e.g., my-description):
# The ticket ID will be automatically included in the branch name.
# Lines starting with # will be ignored.

EOF
  else
    cat > "$tmpfile" << 'EOF'
# Enter your branch description below in kebab-case (e.g., my-description):
# Lines starting with # will be ignored.

EOF
  fi
  
  "$editor" "$tmpfile" < /dev/tty > /dev/tty

  local desc
  desc=$(grep -v '^#' "$tmpfile" | tr -d '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')

  echo "$desc"
}

validate_description() {
  local desc=$1

  if [[ -z "$desc" ]]; then
    error "No description provided"
  fi

  if [[ ! "$desc" =~ ^[a-z0-9]+(-[a-z0-9]+)*$ ]]; then
    error "Invalid branch description format.\nUse lowercase letters, numbers, and hyphens only.\nNo trailing or consecutive hyphens allowed.\nExample: my-feature-description"
  fi
}

create_branch() {
  local type=$1
  local ticket_id=$2
  local desc=$3

  local branch
  if [[ -n "$ticket_id" ]]; then
    branch="$type/$ticket_id-$desc"
  else
    branch="$type/$desc"
  fi

  if git show-ref --verify --quiet "refs/heads/$branch"; then
    error "Branch '$branch' already exists"
  fi

  echo ""
  echo "Creating branch: $branch"
  git checkout -b "$branch"
}

main() {
  check_dependencies
  check_git_repo
  check_current_branch

  local email
  email=$(get_user_email)

  local type
  type=$(select_branch_type)

  echo "About to call select_jira_ticket" >&2
  local ticket_id=""
  ticket_id=$(select_jira_ticket "$email")
  local desc
  desc=$(get_branch_description "$ticket_id")
  validate_description "$desc"
  create_branch "$type" "$ticket_id" "$desc"
}

main "$@"
