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

# Script Name: jj
# Description: JSON formatting and querying tool (upgrade from alias)
# Usage: jj                     # Format clipboard JSON
#        jj '.users[0].name'    # jq query on clipboard
#        jj -v                  # Validate JSON
#        jj -f file.json        # Format file in place
#        jj -c                  # Compact JSON (remove whitespace)
#        cat file.json | jj     # Format from stdin

VERSION="1.0.0"

show_help() {
  echo -e "\033[1mjj\033[0m - JSON Formatting & Querying Tool v${VERSION}"
  echo
  echo -e "\033[1mUSAGE:\033[0m"
  echo "  jj [OPTIONS] [JQ_QUERY]"
  echo
  echo -e "\033[1mOPTIONS:\033[0m"
  echo -e "  \033[0;36m-v, --validate\033[0m    Validate JSON only (no output)"
  echo -e "  \033[0;36m-f, --file\033[0m        Format file in place"
  echo -e "  \033[0;36m-c, --compact\033[0m     Compact JSON (remove whitespace)"
  echo -e "  \033[0;36m-i, --stdin\033[0m       Read from stdin instead of clipboard"
  echo -e "  \033[0;36m-o, --output\033[0m      Write to clipboard (default: stdout)"
  echo -e "  \033[0;36m-h, --help\033[0m        Show this help message"
  echo
  echo -e "\033[1mEXAMPLES:\033[0m"
  echo "  jj                        # Format clipboard JSON"
  echo "  jj '.users[0].name'       # Query clipboard with jq"
  echo "  jj -v                     # Validate clipboard JSON"
  echo "  jj -f data.json           # Format file in place"
  echo "  jj -c                     # Compact clipboard JSON"
  echo "  cat file.json | jj        # Format from stdin"
  echo "  curl api.com | jj '.data' # Query API response"
  echo
  echo -e "\033[1mNOTE:\033[0m"
  echo "  Requires jq to be installed for querying"
}

# Clipboard functions
clip_get() {
  if command -v xsel &>/dev/null; then
    xsel --output --clipboard
  elif command -v xclip &>/dev/null; then
    xclip -selection clipboard -o
  else
    echo "Error: No clipboard tool found" >&2
    return 1
  fi
}

clip_set() {
  if command -v xsel &>/dev/null; then
    xsel --input --clipboard
  elif command -v xclip &>/dev/null; then
    xclip -selection clipboard
  else
    echo "Error: No clipboard tool found" >&2
    return 1
  fi
}

# Get input (clipboard or stdin)
get_input() {
  if [[ "${use_stdin}" == "true" ]] || [[ ! -t 0 ]]; then
    # Use stdin if explicitly requested OR if stdin is not a terminal (piped)
    cat
  else
    clip_get
  fi
}

# Validate JSON
validate_json() {
  local input=$1
  if echo "$input" | jq empty 2>/dev/null; then
    echo -e "\033[0;32m✓\033[0m Valid JSON"
    return 0
  else
    echo -e "\033[0;31m✗\033[0m Invalid JSON:" >&2
    echo "$input" | jq empty 2>&1 | sed 's/^/  /' >&2
    return 1
  fi
}

# Format JSON (pretty print)
format_json() {
  local input=$1
  echo "$input" | jq .
}

# Compact JSON
compact_json() {
  local input=$1
  echo "$input" | jq -c .
}

# Query JSON with jq
query_json() {
  local input=$1
  local query=$2
  echo "$input" | jq "$query"
}

# Parse arguments
mode="format"
use_stdin=false
to_clipboard=false
file_path=""
jq_query=""

while [[ $# -gt 0 ]]; do
  case $1 in
    -v|--validate)
      mode="validate"
      shift
      ;;
    -f|--file)
      mode="file"
      file_path="$2"
      shift 2
      ;;
    -c|--compact)
      mode="compact"
      shift
      ;;
    -i|--stdin)
      use_stdin=true
      shift
      ;;
    -o|--output)
      to_clipboard=true
      shift
      ;;
    -h|--help)
      show_help
      exit 0
      ;;
    *)
      # Assume it's a jq query
      jq_query="$1"
      mode="query"
      shift
      ;;
  esac
done

# Check if jq is installed
if ! command -v jq &>/dev/null; then
  echo -e "\033[0;31mError:\033[0m jq is not installed" >&2
  echo "Install it with: sudo apt install jq" >&2
  exit 1
fi

# Main logic
case "$mode" in
  validate)
    input=$(get_input)
    validate_json "$input"
    ;;

  file)
    if [[ ! -f "$file_path" ]]; then
      echo -e "\033[0;31mError:\033[0m File not found: $file_path" >&2
      exit 1
    fi

    # Validate first
    if ! jq empty "$file_path" 2>/dev/null; then
      echo -e "\033[0;31mError:\033[0m Invalid JSON in file" >&2
      jq empty "$file_path" 2>&1 | sed 's/^/  /' >&2
      exit 1
    fi

    # Format in place
    temp_file=$(mktemp)
    jq . "$file_path" > "$temp_file"
    mv "$temp_file" "$file_path"
    echo -e "\033[0;32m✓\033[0m Formatted: $file_path"
    ;;

  compact)
    input=$(get_input)
    output=$(compact_json "$input")

    if [[ "$to_clipboard" == "true" ]]; then
      echo -n "$output" | clip_set
      echo -e "\033[0;32m✓\033[0m Copied compacted JSON to clipboard"
    else
      echo "$output"
    fi
    ;;

  query)
    input=$(get_input)
    output=$(query_json "$input" "$jq_query")

    if [[ "$to_clipboard" == "true" ]]; then
      echo -n "$output" | clip_set
      echo -e "\033[0;32m✓\033[0m Copied query result to clipboard"
    else
      echo "$output"
    fi
    ;;

  format)
    input=$(get_input)
    output=$(format_json "$input")

    if [[ "$to_clipboard" == "true" ]]; then
      echo -n "$output" | clip_set
      echo -e "\033[0;32m✓\033[0m Copied formatted JSON to clipboard"
    else
      echo "$output"
    fi
    ;;
esac
