#!/bin/bash

# shellcheck shell=bash

# Get enhanced git status
bridge_enhanced_git_status() {
  # Optional directory parameter - if provided, cd to that directory first
  target_dir="${1:-}"
  if [[ -n "$target_dir" ]]; then
    if [[ ! -d "$target_dir" ]]; then
      json_error "Directory does not exist: $target_dir"
      return 1
    fi
    cd "$target_dir" || {
      json_error "Cannot change to directory: $target_dir"
      return 1
    }
  fi
  
  if git_require_repo_root >/dev/null 2>&1; then
    # Get porcelain status
    status_lines="$(git status --porcelain=v1 2>/dev/null)"
    
    # Get branch info
    branch="$(git_current_branch)"
    
    # Get ahead/behind info (handle cases where upstream doesn't exist)
    ahead_behind="$(git rev-list --left-right --count HEAD...@{upstream} 2>/dev/null || echo "0	0")"
    ahead="$(echo "$ahead_behind" | cut -f1)"
    behind="$(echo "$ahead_behind" | cut -f2)"
    
    # Get all diff stats in bulk for performance
    staged_stats="$(git diff --cached --numstat 2>/dev/null)"
    unstaged_stats="$(git diff --numstat 2>/dev/null)"
    
    # Process each file and get diff stats
    files_payload=""
    while IFS= read -r line; do
      if [[ -n "$line" ]]; then
        index_status="${line:0:1}"
        workdir_status="${line:1:1}"
        filepath="${line:3}"
        
        # Get diff stats for the file
        added=0
        deleted=0
        
        # Check for staged changes first
        if [[ "$index_status" != " " && "$index_status" != "?" ]]; then
          # Look up stats in bulk staged diff
          stats="$(echo "$staged_stats" | grep -F "	$filepath" | head -1)"
          if [[ -n "$stats" && "$stats" != "-	-"* ]]; then
            added="$(echo "$stats" | cut -f1)"
            deleted="$(echo "$stats" | cut -f2)"
            # Handle binary files (shows -)
            [[ "$added" == "-" ]] && added=0
            [[ "$deleted" == "-" ]] && deleted=0
          fi
        fi
        
        # Check for working directory changes if no staged stats or if workdir is also modified
        if [[ "$workdir_status" != " " && "$workdir_status" != "?" ]] && [[ $added -eq 0 && $deleted -eq 0 ]]; then
          # Look up stats in bulk unstaged diff
          stats="$(echo "$unstaged_stats" | grep -F "	$filepath" | head -1)"
          if [[ -n "$stats" && "$stats" != "-	-"* ]]; then
            added="$(echo "$stats" | cut -f1)"
            deleted="$(echo "$stats" | cut -f2)"
            # Handle binary files (shows -)
            [[ "$added" == "-" ]] && added=0
            [[ "$deleted" == "-" ]] && deleted=0
          fi
        fi
        
        # For untracked files, try to count lines
        if [[ "$index_status" == "?" && "$workdir_status" == "?" ]]; then
          if [[ -f "$filepath" ]]; then
            # Count lines in new file
            line_count="$(wc -l < "$filepath" 2>/dev/null || echo "0")"
            added="$line_count"
            deleted=0
          fi
        fi
        
        # Output JSON for this file
        file_json="$(json_object \
          "path:s=$filepath" \
          "index_status:s=$index_status" \
          "workdir_status:s=$workdir_status" \
          "lines_added:n=$added" \
          "lines_deleted:n=$deleted")"
        files_payload+="$file_json"$'\n'
      fi
    done <<< "$status_lines"

    if [[ -n "$files_payload" ]]; then
      files_json="$(json_array_from_json_lines "$files_payload")"
    else
      files_json="[]"
    fi
    
    # Combine into final JSON
    json_object \
      "branch:s=$branch" \
      "ahead:n=${ahead:-0}" \
      "behind:n=${behind:-0}" \
      "files:j=$files_json"
  else
    json_error "Not a git repository"
  fi
}
