#!/bin/bash

###############################################################################
# gw-bridge.sh – API bridge between the Rust TUI and the shell context
# ---------------------------------------------------------------------------
# The UI lives in Rust, but all operational logic (git, worktrees, tmux, env
# copying, etc.) lives in bash.  The TUI calls into this script (through
# `BridgeApi`), and we fan out to the shell utilities (`api/git.sh`, `commands.sh`,
# `api/tmux.sh`, …).  Responses are normalised (usually JSON) so the Rust side can
# remain strongly-typed while we stay anchored in the shell environment.
###############################################################################

set -euo pipefail

# Source the API modules
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/api/git.sh"
source "$SCRIPT_DIR/api/tmux.sh"
source "$SCRIPT_DIR/shell/gw_env_copy.sh"

# Source bridge modules
source "$SCRIPT_DIR/shell/bridge/utils.sh"
source "$SCRIPT_DIR/shell/bridge/tmux.sh"
source "$SCRIPT_DIR/shell/bridge/ai.sh"

# Source git bridge modules (now modular)
source "$SCRIPT_DIR/shell/git/bridge_worktree.sh"
source "$SCRIPT_DIR/shell/git/bridge_repo.sh"
source "$SCRIPT_DIR/shell/git/bridge_merge.sh"
source "$SCRIPT_DIR/shell/git/bridge_enhanced_git_status.sh"
source "$SCRIPT_DIR/shell/git/bridge_git_status.sh"

# Define utilities we need
err() { printf '❌ %s\n' "$*" >&2; }
info() { printf '%s\n' "$*"; }
have_cmd() { command -v "$1" >/dev/null 2>&1; }

bridge_copy_env_files() {
  if [[ -z "${1:-}" ]] || [[ -z "${2:-}" ]]; then
    json_error "Source and target paths required"
    return 1
  fi
  local source_path="$1"
  local target_path="$2"
  local raw_locations="${3-}"

  local repo_root
  repo_root="$(cd "$source_path" 2>/dev/null && git rev-parse --show-toplevel 2>/dev/null || printf '%s' "$source_path")"
  local shared_root
  shared_root="$(cd "$source_path" 2>/dev/null && git rev-parse --git-common-dir 2>/dev/null || echo "")"
  if [[ -n "$shared_root" ]]; then
    if [[ "$shared_root" != /* ]]; then
      shared_root="$(cd "$source_path" 2>/dev/null && pwd -P)/$shared_root"
    fi
    shared_root="$(dirname "$shared_root")"
  else
    shared_root="$repo_root"
  fi

  local bin
  if ! bin="$(gw_env_copy_bin)"; then
    json_error "gw-env-copy binary not found"
    return 1
  fi

  local args=(
    --source "$source_path"
    --target "$target_path"
    --repo "$shared_root"
    --format boolean
    --quiet
  )
  if [[ -n "$raw_locations" ]]; then
    args+=(--locations-json "$raw_locations")
  fi

  "$bin" "${args[@]}"
}

# Ensure JSON backend is available (jq preferred, python/node fallback)
bridge_init_json_backend

# Main command dispatcher
case "${1:-}" in
  "list-worktrees")
    bridge_list_worktrees
    ;;
    
  "list-sessions")
    bridge_list_sessions "${2:-}" "${3:-}"
    ;;
    
  "create-session")
    bridge_create_session "${2:-}" "${3:-}" "${4:-}"
    ;;

  "create-session-exact")
    bridge_create_session_exact "${2:-}" "${3:-}"
    ;;
    
  "kill-session")
    bridge_kill_session "${2:-}"
    ;;
    
  "attach-session")
    bridge_attach_session "${2:-}"
    ;;
  
  "tmux-send-keys")
    bridge_tmux_send_keys "${2:-}" "${@:3}"
    ;;

  "cycle-workspace-session")
    bridge_cycle_workspace_session "${2:-}" "${3:-}" "${4:-}"
    ;;

  "tmux-help-popup")
    bridge_tmux_help_popup "${2:-}"
    ;;
    
  "session-metadata")
    bridge_session_metadata "${2:-}"
    ;;
    
  "session-preview")
    bridge_session_preview "${2:-}"
    ;;
    
    "ai-generate-name-from-base64")
    bridge_ai_generate_name_from_base64 "${2:-}"
    ;;
    
  "rename-session")
    bridge_rename_session "${2:-}"
    ;;
    
  "manual-rename-session")
    bridge_manual_rename_session "${2:-}" "${@:3}"
    ;;
    
  "check-branch")
    bridge_check_branch "${2:-}"
    ;;

  "create-worktree")
    bridge_create_worktree "${2:-}"
    ;;

  "create-worktree-from-existing")
    bridge_create_worktree_from_existing "${2:-}"
    ;;

  "create-worktree-from-remote")
    bridge_create_worktree_from_remote "${2:-}" "${3:-}"
    ;;

  "delete-worktree")
    bridge_delete_worktree "${2:-}"
    ;;
    
  "delete-worktree-only")
    bridge_delete_worktree_only "${2:-}"
    ;;
    
  "delete-branch-only")
    bridge_delete_branch_only "${2:-}"
    ;;
    
  "switch-worktree")
    bridge_switch_worktree "${2:-}"
    ;;
    
  "repo-info")
    bridge_repo_info
    ;;
    
  "git-status")
    bridge_git_status
    ;;
    
  "enhanced-git-status")
    bridge_enhanced_git_status "${2:-}"
    ;;
    
  "primary-branch")
    bridge_primary_branch
    ;;

  "merge-from-primary")
    bridge_merge_from_primary "$@"
    ;;

  "rebase-from-primary")
    bridge_rebase_from_primary "$@"
    ;;

  "merge-into-primary")
    bridge_merge_into_primary "$@"
    ;;

  "squash-into-primary")
    bridge_squash_into_primary "$@"
    ;;

  "tmux-available")
    bridge_tmux_available
    ;;
    
  "copy-env-files")
    bridge_copy_env_files "${2:-}" "${3:-}" "${4:-}"
    ;;
    
  "help"|"-h"|"--help")
    cat << 'EOF'
Usage: gw-bridge.sh <command> [args]

API bridge for gw-tui Rust application.

Commands:
  list-worktrees                    List all worktrees as JSON
  list-sessions <slug>              List tmux sessions for worktree slug
  create-session <slug> [name] [path]  Create new tmux session
  kill-session <session>            Kill tmux session
  attach-session <session>          Attach to tmux session
  session-metadata <session>        Get session metadata (window, pane, command)
  session-preview <session>         Get session preview text
  tmux-send-keys <session> <cmd>    Send command to session and press Enter

  ai-generate-name-from-base64 <content>  Generate AI session name from base64 content
  rename-session <session>          Rename session with AI
  manual-rename-session <old> <new>  Manually rename session

  check-branch <branch>             Check local/remote branch existence
  create-worktree <branch>          Create new worktree and branch
  create-worktree-from-existing <branch>
                                    Create worktree from existing local branch
  create-worktree-from-remote <branch> [remote]
                                    Create worktree from remote branch
  delete-worktree <branch>          Delete worktree and branch
  delete-worktree-only <branch>     Delete worktree only (keep branch)
  delete-branch-only <branch>       Delete branch only (keep worktree)
  switch-worktree <path>            Generate cd command for path
  copy-env-files <source> <target>  Copy .env files between directories
  cycle-workspace-session <session> <next|previous> [client]
                                    Switch within registered Orchestra sessions for this repo
  tmux-help-popup [client]          Show Orchestra tmux shortcut popup
  repo-info                         Get repository information
  git-status                        Get git status --porcelain
  enhanced-git-status [dir]         Get enhanced git status with file stats and line counts
  primary-branch                    Detect primary branch name
  merge-from-primary --worktree <path> --branch <name>
                                    Merge primary into selected branch
  rebase-from-primary --worktree <path> --branch <name>
                                    Rebase selected branch onto primary
  merge-into-primary --worktree <path> --branch <name> [--message <msg>]
                                    Merge selected branch into primary (merge commit)
  squash-into-primary --worktree <path> --branch <name> [--message <msg>]
                                    Squash selected branch into primary (single commit)
  tmux-available                    Check if tmux is available
  help                              Show this help

All commands return JSON output or JSON errors.
EOF
    ;;
    
  *)
    json_error "Unknown command: ${1:-}. Use 'help' for usage."
    exit 1
    ;;
esac
