#!/bin/bash

API_URL="http://localhost:5000"
TOKEN_FILE="$HOME/.pastebin_token"

load_token() {
  [[ -f "$TOKEN_FILE" ]] && TOKEN=$(cat "$TOKEN_FILE") || TOKEN=""
}

save_token() {
  echo "$TOKEN" > "$TOKEN_FILE"
}

authenticate() {
  local username="$1" password="$2"
  response=$(curl -s -X POST "$API_URL/api/token" \
    -H "Content-Type: application/json" \
    -d '{"username": "'$username'", "password": "'$password'"}')
  if echo "$response" | grep -q 'token'; then
    TOKEN=$(echo "$response" | jq -r '.token')
    save_token
    echo "Authentication successful. Token saved."
  else
    echo "Authentication failed: $(echo "$response" | jq -r '.error')"
    exit 1
  fi
}

list_users() {
  load_token
  if [[ -z "$TOKEN" ]]; then
    echo "Error: No token found. Please authenticate first."
    return 1
  fi

  response=$(curl -s -H "Authorization: Bearer $TOKEN" "$API_URL/api/users")
  
  error_msg=$(echo "$response" | jq -r '.error // empty')
  if [[ -n "$error_msg" ]]; then
    echo "Error: $error_msg"
    return 1
  fi

  usernames=$(echo "$response" | jq -r '.users[]')
  echo "$usernames"
}

remove_gps_metadata() {
  local paste_id="$1"
  load_token

  if [[ -z "$TOKEN" ]]; then
    echo "Error: No token found. Please authenticate first."
    return 1
  fi

  if [[ -z "$paste_id" ]]; then
    echo "Usage: $0 remove_gps <paste_id>"
    return 1
  fi

  response=$(curl -s -X POST "$API_URL/api/removegps" \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d "{\"paste_id\": $paste_id}")

  success=$(echo "$response" | jq -r '.success // empty')

  if [[ "$success" == "true" ]]; then
    echo "✅ GPS metadata successfully removed from paste ID $paste_id"
  else
    error_msg=$(echo "$response" | jq -r '.error // empty')
    echo "❌ Error: $error_msg"
  fi
}

edit_paste() {
  local paste_id="$1"
  load_token

  # Chequear token
  if [[ -z "$TOKEN" ]]; then
    echo "Error: No token found. Please authenticate first."
    return 1
  fi

  if [[ -z "$paste_id" ]]; then
    echo "Usage: $0 edit <paste_id>"
    return 1
  fi

  # 1. Descargar contenido JSON del paste
  echo "Fetching current content of paste $paste_id..."
  response=$(curl -s -H "Authorization: Bearer $TOKEN" \
                   "$API_URL/paste/$paste_id/json")

  # Checar error
  error_msg=$(echo "$response" | jq -r '.error // empty')
  if [[ -n "$error_msg" ]]; then
    echo "Error: $error_msg"
    return 1
  fi

  # 2. Extraer el contenido, filename, etc.
  current_content=$(echo "$response" | jq -r '.content // empty')
  paste_filename=$(echo "$response" | jq -r '.filename // empty')
  paste_language=$(echo "$response" | jq -r '.language // empty')

  # 3. Decidir la extensión local:
  #    a) tratar de inferirla de paste_filename
  #    b) si no hay, usar language
  #    c) fallback a "txt"

  # Extraer extensión del filename, si existe
  extension="txt"
  if [[ -n "$paste_filename" ]]; then
    # e.g. "myscript.py" -> ".py"
    ext_from_name="${paste_filename##*.}"  # todo lo que viene después de la última.
    if [[ "$ext_from_name" != "$paste_filename" ]]; then
      extension="$ext_from_name"
    fi
  elif [[ -n "$paste_language" ]]; then
    # Una pequeña tabla de mapeo básico
    case "$paste_language" in
      python) extension="py" ;;
      javascript|js) extension="js" ;;
      typescript|ts) extension="ts" ;;
      java) extension="java" ;;
      c) extension="c" ;;
      cpp|c++) extension="cpp" ;;
      bash|shell) extension="sh" ;;
      html) extension="html" ;;
      css) extension="css" ;;
      json) extension="json" ;;
      sql) extension="sql" ;;
      *) extension="txt" ;;
    esac
  fi

  # 4. Crear archivo temporal con esa extensión
  temp_file=$(mktemp "/tmp/paste_${paste_id}_XXXXXX.${extension}")

  # 5. Guardar el contenido en el archivo y abrir editor
  echo "$current_content" > "$temp_file"
  "${EDITOR:-nano}" "$temp_file"

  # 6. Leer el contenido editado
  new_content=$(cat "$temp_file")
  if [[ -z "$new_content" ]]; then
    echo "No content provided. Aborting."
    rm -f "$temp_file"
    return 1
  fi

  # 7. Convertir a JSON con jq -Rs '.'
  new_content_json=$(echo "$new_content" | jq -Rs '.')

  # 8. Enviar PUT /api/paste/<paste_id> con el nuevo contenido
  update_response=$(curl -s -X PUT "$API_URL/api/paste/$paste_id" \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"content":'"$new_content_json"'}')

  # 9. Mostrar resultado
  msg=$(echo "$update_response" | jq -r '.message // .error // empty')
  if [[ -n "$msg" ]]; then
    echo "$msg"
  else
    echo "$update_response"
  fi

  # 10. Limpieza
  rm -f "$temp_file"
}


unshare_paste() {
  local paste_id="$1" username="$2"
  load_token
  if [[ -z "$TOKEN" ]]; then
    echo "Error: No token found. Please authenticate first."
    return 1
  fi

  if [[ -z "$paste_id" || -z "$username" ]]; then
    echo "Error: Paste ID and username are required."
    return 1
  fi

  response=$(curl -s -X POST "$API_URL/api/paste/$paste_id/unshare" \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"username": "'$username'"}')

  if echo "$response" | grep -q '"message"'; then
    echo "$response" | jq -r '.message'
  else
    echo "Error: $(echo "$response" | jq -r '.error')"
  fi
}

share_paste() {
  local paste_id="$1"
  local username="$2"
  local can_edit_input="${3:-false}" # Por defecto, no se permite editar

  load_token
  if [[ -z "$TOKEN" ]]; then
    echo "Error: No token found. Please authenticate first."
    return 1
  fi

  # Validación de argumentos
  if [[ -z "$paste_id" || -z "$username" ]]; then
    echo "Usage: share_paste <paste_id> <username> [can_edit (true|false)]"
    return 1
  fi

  # Validar que can_edit sea 'true' o 'false'
  if [[ "$can_edit_input" != "true" && "$can_edit_input" != "false" ]]; then
    echo "Error: can_edit must be 'true' or 'false'."
    return 1
  fi

  # Convertir la entrada can_edit a booleano JSON
  if [[ "$can_edit_input" == "true" ]]; then
    can_edit_json=true
  else
    can_edit_json=false
  fi

  # Construir el JSON de manera segura usando jq
  json_data=$(jq -n --arg username "$username" --argjson can_edit "$can_edit_json" \
    '{username: $username, can_edit: $can_edit}')

  # Verificar que json_data es válido
  if [[ -z "$json_data" ]]; then
    echo "Error: Failed to construct JSON data."
    return 1
  fi

  # Realizar la solicitud POST al endpoint y capturar la respuesta y el código HTTP
  response=$(curl -s -w "\n%{http_code}" -X POST "$API_URL/api/paste/$paste_id/share" \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d "$json_data")

  # Separar el cuerpo de la respuesta y el código de estado
  http_body=$(echo "$response" | sed '$d')
  http_code=$(echo "$response" | tail -n1)

  # Manejar la respuesta según el código de estado
  if [[ "$http_code" == "200" ]]; then
    echo "$http_body" | jq
  elif [[ "$http_code" == "400" || "$http_code" == "403" || "$http_code" == "404" || "$http_code" == "500" ]]; then
    echo "$http_body" | jq -r '.error // .message'
  else
    echo "Unexpected HTTP code: $http_code"
    echo "$http_body"
  fi
}

list_shared_with_others() {
  load_token
  if [[ -z "$TOKEN" ]]; then
    echo "Error: No token found. Please authenticate first."
    return 1
  fi

  response=$(curl -s -H "Authorization: Bearer $TOKEN" "$API_URL/api/shared_with_others")
  echo "$response" | jq
}

list_shared_with_me() {
  load_token
  if [[ -z "$TOKEN" ]]; then
    echo "Error: No token found. Please authenticate first."
    return 1
  fi

  response=$(curl -s -H "Authorization: Bearer $TOKEN" "$API_URL/api/shared_with_me")
  echo "$response" | jq
}


list_favorites() {
  load_token
  if [[ -z "$TOKEN" ]]; then
    echo "Error: No token found. Please authenticate first."
    return 1
  fi

  response=$(curl -s -H "Authorization: Bearer $TOKEN" "$API_URL/api/favorites")
  echo "$response" | jq
}


download() {
  local paste_id="$1"
  load_token
  if [[ -z "$TOKEN" ]]; then
    echo "Error: No token found. Please authenticate first."
    return 1
  fi

  # Solicitar el archivo y guardar las cabeceras en un archivo temporal
  response=$(curl -s -w "%{http_code}" -D headers.tmp -o "paste_${paste_id}.tmp" \
    -H "Authorization: Bearer $TOKEN" "$API_URL/api/paste/$paste_id/download")

  # Extraer el código HTTP del final de la respuesta
  http_code=$(echo "$response" | tail -n1)

  if [[ "$http_code" -eq 200 ]]; then
    # Extraer el nombre del archivo del encabezado "Content-Disposition"
    filename=$(grep -i "Content-Disposition" headers.tmp | grep -o 'filename="[^"]*"' | sed 's/filename=//' | tr -d '"')
    if [[ -z "$filename" ]]; then
      # Si no se encuentra el encabezado, usar un nombre genérico
      file_extension=$(file --mime-type -b "paste_${paste_id}.tmp" | awk -F'/' '{print $2}')
      filename="paste_${paste_id}.${file_extension}"
    fi
    mv "paste_${paste_id}.tmp" "$filename"
    echo "Paste $paste_id downloaded to $filename"
  elif [[ "$http_code" -eq 403 ]]; then
    echo "Error: You do not have permission to download paste $paste_id."
    rm -f "paste_${paste_id}.tmp"
  elif [[ "$http_code" -eq 404 ]]; then
    echo "Error: Paste $paste_id not found."
    rm -f "paste_${paste_id}.tmp"
  else
    echo "Failed to download paste $paste_id (HTTP code: $http_code)"
    rm -f "paste_${paste_id}.tmp"
  fi

  # Limpieza
  rm -f headers.tmp
}


download_favorites() {
  load_token
  if [[ -z "$TOKEN" ]]; then
    echo "Error: No token found. Please authenticate first."
    return 1
  fi
  response=$(curl -s -H "Authorization: Bearer $TOKEN" "$API_URL/api/favorites")
  echo "$response" | jq -r '.[] | @base64' | while read paste; do
    paste_id=$(echo "$paste" | base64 --decode | jq -r '.id')
    download "$paste_id"
  done
}

create_paste() {
#  local lang="$1"
  local expire="${1:-yes}"
  local private="${2:-no}"  # ✅ Nuevo parámetro opcional, por defecto "no"

  echo "Enter the content for the paste (Ctrl+D to finish):"
  content=$(cat)

  [[ -z "$content" ]] && { echo "Error: Paste content cannot be empty."; exit 1; }

  response=$(echo "$content" | curl -s -X POST "$API_URL/paste" \
    -H "Authorization: Bearer $TOKEN" \
    -F "c=@-" \
    -F "expire=$expire" \
    $( [[ "$private" == "yes" ]] && echo "-F private=true" ) )  # ✅ Se envía "private=true" solo si es necesario

  echo "$response" | jq -r '.url // .error'
}

upload_file() {
  local file="$1"
  local expire="${2:-yes}"
  local private="${3:-no}"

  [[ ! -f "$file" ]] && { echo "Error: File not found."; exit 1; }


  response=$(curl -s -X POST "$API_URL/paste" \
    -H "Authorization: Bearer $TOKEN" \
    -F "c=@$file" \
    -F "expire=$expire" \
    $( [[ "$private" == "yes" ]] && echo "-F private=true" ) )  # ✅ Se envía "private=true" solo si es necesario

  echo "$response" | jq -r '.url // .error'
}


view_paste() {
  local paste_id="$1"
  response=$(curl -s "$API_URL/paste/$paste_id/json" \
    -H "Authorization: Bearer $TOKEN")
  echo "$response" | jq -r '.content // .error'
}

list_pastes() {
  response=$(curl -s "$API_URL/pastes" -H "Authorization: Bearer $TOKEN")
  echo "$response" | jq
}

delete_paste() {
  local paste_id="$1"
  response=$(curl -s -X DELETE "$API_URL/paste/$paste_id" \
    -H "Authorization: Bearer $TOKEN")
  echo "$response"
}

view_raw() {
  local paste_id="$1"
  response=$(curl -s "$API_URL/paste/$paste_id/raw" \
    -H "Authorization: Bearer $TOKEN")
  echo "$response"
}

register_user() {
  local username="$1" password="$2"
  response=$(curl -s -X POST "$API_URL/register" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $TOKEN" \
    -d '{"username": "'$username'", "password": "'$password'"}')
  echo "$response"
}

details() {
  response=$(curl -s -X GET "$API_URL/user/details" \
    -H "Authorization: Bearer $TOKEN")
  echo "$response" | jq
}

search_pastes() {
  local query="$1"
  response=$(curl -s -X GET "$API_URL/pastes/search?q=$query" \
    -H "Authorization: Bearer $TOKEN")
  echo "$response" | jq
}

add_to_favorites() {
  local paste_id="$1"
  load_token
  if [[ -z "$TOKEN" ]]; then
    echo "Error: No token found. Please authenticate first."
    return 1
  fi
  response=$(curl -s -X POST "$API_URL/api/paste/$paste_id/favorite" \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json")
  echo "$response"
}

remove_from_favorites() {
  local paste_id="$1"
  load_token
  if [[ -z "$TOKEN" ]]; then
    echo "Error: No token found. Please authenticate first."
    return 1
  fi
  response=$(curl -s -X POST "$API_URL/api/paste/$paste_id/unfavorite" \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json")
  echo "$response"
}


load_token

case "$1" in
  login) authenticate "$2" "$3" ;;
  edit) edit_paste "$2" ;;
  shared_with_others) list_shared_with_others ;;
  shared_with_me) list_shared_with_me ;;
download) download "$2" ;;
 list_favorites) list_favorites ;;
 remove_gps) remove_gps_metadata "$2" ;;
  favorite) add_to_favorites "$2" ;;
  unfavorite) remove_from_favorites "$2" ;;
  create) create_paste "$2" "$3" ;;
  upload) upload_file "$2" "$3" "$4" ;;
  view) view_paste "$2" ;;
  share) share_paste "$2" "$3" "$4" ;;
  unshare) unshare_paste "$2" "$3" ;;
  list) list_pastes ;;
  delete) delete_paste "$2" ;;
  view_raw) view_raw "$2" ;;
  register) register_user "$2" "$3" ;;
  details) details ;;
  search) search_pastes "$2" ;;
  *) echo "Usage: $0 {login|create|upload|view|list|delete|view_raw|register|details|search|favorite|unfavorite|shared_with_others|shared_with_me|share|unshare|remove_gps}" ;;
esac

