#!/bin/bash
clear

domain=$(cat /root/domain)
api_host="127.0.0.1"
api_port=$(netstat -tunlp | grep 'python' | awk '{split($4, a, ":"); print a[2]}')

# Variabel API
API_URL="http://${api_host}:${api_port}/api/users"
TOKEN=$(cat /root/token.json | jq -r .access_token)

# Function to convert bytes to human-readable format
format_data() {
  awk '{split("B KB MB GB TB PB", v); s = 1; while ($1 >= 1024) {$1 /= 1024; s++} printf "%.2f %s", $1, v[s]}'
}

# Function to convert expiration timestamp to human-readable format
convert_expiration() {
  timestamp="${1}"
  if [ "${timestamp}" == "null" ]; then
    echo "Always ON"
  else
    date -d "@${timestamp}" '+%Y-%m-%d %H:%M:%S'
  fi
}

# Function to display detailed account information based on protocol
display_protocol_details() {
  user="$1"
  protocol="$2"
  used_traffic="$3"
  data_limit="$4"
  reset_strategy="$5"
  pass_or_id="$6"
  subs="$7"
  expires_at_human="$8"

  echo -e "=======-XRAY/${protocol}======="
  echo -e ""
  echo -e "Remarks: ${user}"
  echo -e "Domain: ${domain}"
  echo -e "Quota: ${used_traffic_human}/${data_limit_human}"
  echo -e "Reset Quota Strategy: ${reset_strategy}"
  echo -e "================================="
  echo -e "🔑 Port TLS: 443, 8443, 8880"
  echo -e "🔑 Port nonTLS: 80, 2082, 2083, 3128, 8080"
  echo -e "================================="
  if [[ "$protocol" == "trojan" || "$protocol" == "shadowsocks" ]]; then
    echo -e "Password: ${pass_or_id}"
  elif [[ "$protocol" == "vless" || "$protocol" == "vmess" ]]; then
    echo -e "ID: ${pass_or_id}"
  fi
  echo -e "================================="
  echo -e "Link Subscription : https://${domain}${subs}"
  echo -e "================================="
  echo -e "Expired at : ${expires_at_human}"
}

# Fetch user data from the API
response=$(curl -s -X 'GET' \
  "${API_URL}" \
  -H 'accept: application/json' \
  -H "Authorization: Bearer ${TOKEN}")

# Check if the API request was successful
if [ $? -ne 0 ]; then
  echo "Error fetching data from the API"
  exit 1
fi

# Check if the response is valid JSON
if ! jq '.' <<< "${response}" > /dev/null 2>&1; then
  echo "Invalid JSON response from the API"
  exit 1
fi

# Extract relevant information and format the output as a table
echo "No.   Username                Protocol  Status   Used Traffic    Data Limit    Reset Strategy     Expires At"
echo "----- ------------------------ --------- -------- -------------- ------------- ------------------- ---------------------"

# Loop through the users and print the information
count=1
while IFS= read -r row; do
  username=$(jq -r '.username' <<< "${row}")
  status=$(jq -r '.status' <<< "${row}")
  used_traffic=$(jq -r '.used_traffic' <<< "${row}")
  data_limit=$(jq -r '.data_limit' <<< "${row}")
  reset_strategy=$(jq -r '.data_limit_reset_strategy' <<< "${row}")
  expires_at=$(jq -r '.expire' <<< "${row}")
  protocol=$(jq -r '.proxies | keys_unsorted[0]' <<< "${row}" | sed 's/shadowsocks/ss/')

  # Convert bytes to human-readable format
  used_traffic_human=$(echo "${used_traffic}" | format_data)

  # Check if data limit is 0.00 KB and replace with Unlimited
  if [ "${data_limit}" == "null" ]; then
    data_limit_human="Unlimited"
  else
    data_limit_human=$(echo "${data_limit}" | format_data)
  fi

  # Replace null values and specific reset strategies
  case "${reset_strategy}" in
    "no_reset") reset_strategy="loss_doll";;
    "day") reset_strategy="harian";;
    "week") reset_strategy="mingguan";;
    "month") reset_strategy="bulanan";;
    "year") reset_strategy="tahunan";;
  esac

  expires_at_human=$(convert_expiration "${expires_at}")

  printf "%-5s %-24s %-9s %-8s %-14s %-13s %-19s %s\n" "${count}" "${username}" "${protocol}" "${status}" "${used_traffic_human}" "${data_limit_human}" "${reset_strategy}" "${expires_at_human}"
  ((count++))
done <<< "$(jq -c '.users[]' <<< "${response}")"

# User input for menu selection
echo "Pilih menu yang ingin dijalankan:"
echo "1. Delete User"
echo "2. Renew / Perpanjang Masa Aktif User"
echo "3. Reset Usage Data User"
echo "4. Display Detailed Account Information"
read -p "Silahkan masukkan pilihan: " menu_choice

case $menu_choice in
  1)
    # Delete User
    read -p "Pilih pengguna yang akan dihapus (Masukkan nomor yang sesuai): " user_number
    
    # Validate user input
    if [[ ! $user_number =~ ^[0-9]+$ ]]; then
    echo "Masukan tidak valid. Silakan masukkan nomor pilihan yang benar."
    exit 1
    fi

    # Check if the selected user number is valid
    if [ "$user_number" -lt 1 ] || [ "$user_number" -gt "$count" ]; then
    echo "Nomor pengguna tidak valid. Silakan masukkan nomor yang sesuai dengan daftar."
    exit 1
    fi
    # Get the selected user information
    selected_user=$(jq -c --argjson user_number "$user_number" '.users[$user_number - 1]' <<< "${response}")

    # Confirm deletion
    read -p "Anda yakin ingin menghapus pengguna ${username}? (y/n): " confirmation
    if [ "$confirmation" == "y" ] || [ "$confirmation" == "Y" ]; then
      # Perform user deletion
      username_to_delete=$(jq -r '.username' <<< "${selected_user}")
      curl -s -X 'DELETE' \
        "http://${api_host}:${api_port}/api/user/${username_to_delete}" \
        -H 'accept: application/json' \
        -H "Authorization: Bearer ${TOKEN}"

      echo "User ${username_to_delete} telah berhasil dihapus."
    else
      echo "Operasi hapus user telah dibatalkan."
    fi
    ;;
  2)
    # Renew / Perpanjang Masa Aktif User
    read -p "Pilih pengguna yang akan diperpanjang masa aktifnya (Masukkan nomor yang sesuai): " user_number
    # Validate user input
    if [[ ! $user_number =~ ^[0-9]+$ ]]; then
    echo "Masukan tidak valid. Silakan masukkan nomor pilihan yang benar."
    exit 1
    fi

    # Check if the selected user number is valid
    if [ "$user_number" -lt 1 ] || [ "$user_number" -gt "$count" ]; then
    echo "Nomor pengguna tidak valid. Silakan masukkan nomor yang sesuai dengan daftar."
    exit 1
    fi
    # Get the selected user information
    selected_user=$(jq -c --argjson user_number "$user_number" '.users[$user_number - 1]' <<< "${response}")

    # Ask for the renewal duration in days
    read -p "Masukkan durasi perpanjangan masa aktif dalam hari: " renewal_days

    # Calculate the new expiration timestamp by adding the renewal duration to the existing expiration
    current_expiration_epoch=$(jq -r '.expire' <<< "${selected_user}")
    new_expiration_epoch=$((current_expiration_epoch + (renewal_days * 86400)))

    # API call to renew user
    username_to_renew=$(jq -r '.username' <<< "${selected_user}")
    curl -s -X 'PUT' \
      "http://${api_host}:${api_port}/api/user/${username_to_renew}" \
      -H 'accept: application/json' \
      -H "Authorization: Bearer ${TOKEN}" \
      -H 'Content-Type: application/json' \
      -d '{
        "proxies": {},
        "inbounds": {},
        "expire": '"${new_expiration_epoch}"'
      }'

    echo "Masa aktif untuk ${username_to_renew} telah diperpanjang selama ${renewal_days} hari."
    ;;
  3)
    # Reset Usage Data User
    read -p "Pilih pengguna yang akan di-reset data penggunaannya (Masukkan nomor yang sesuai): " user_number
    # Validate user input
    if [[ ! $user_number =~ ^[0-9]+$ ]]; then
    echo "Masukan tidak valid. Silakan masukkan nomor pilihan yang benar."
    exit 1
    fi

    # Check if the selected user number is valid
    if [ "$user_number" -lt 1 ] || [ "$user_number" -gt "$count" ]; then
    echo "Nomor pengguna tidak valid. Silakan masukkan nomor yang sesuai dengan daftar."
    exit 1
    fi
    # Get the selected user information
    selected_user=$(jq -c --argjson user_number "$user_number" '.users[$user_number - 1]' <<< "${response}")
    # API call to reset usage data
    username_to_reset=$(jq -r '.username' <<< "${selected_user}")
    curl -s -X 'POST' \
      "http://${api_host}:${api_port}/api/user/${username_to_reset}/reset" \
      -H 'accept: application/json' \
      -H "Authorization: Bearer ${TOKEN}" \
      -d ' '
    echo "Data penggunaan untuk ${username_to_reset} telah di-reset."
    ;;
  4)
    # Display Detailed Account Information
    read -p "Pilih pengguna untuk menampilkan informasi detail (Masukkan nomor yang sesuai): " user_number
    # Validate user input
    if [[ ! $user_number =~ ^[0-9]+$ ]]; then
    echo "Masukan tidak valid. Silakan masukkan nomor pilihan yang benar."
    exit 1
    fi

    # Check if the selected user number is valid
    if [ "$user_number" -lt 1 ] || [ "$user_number" -gt "$count" ]; then
    echo "Nomor pengguna tidak valid. Silakan masukkan nomor yang sesuai dengan daftar."
    exit 1
    fi
    selected_user=$(jq -c --argjson user_number "$user_number" '.users[$user_number - 1]' <<< "${response}")

    # Extract relevant information for detailed display
    user=$(jq -r '.username' <<< "${selected_user}")
    protocol=$(jq -r '.proxies | keys_unsorted[0]' <<< "${selected_user}" | sed 's/shadowsocks/ss/')
    used_traffic=$(jq -r '.used_traffic' <<< "${selected_user}")
    data_limit=$(jq -r '.data_limit' <<< "${selected_user}")
    reset_strategy=$(jq -r '.data_limit_reset_strategy' <<< "${selected_user}")
    if [[ "$protocol" == "trojan" || "$protocol" == "shadowsocks" ]]; then
      pass_or_id=$(jq -r '.proxies."'$protocol'".password' <<< "${selected_user}")
    elif [[ "$protocol" == "vless" || "$protocol" == "vmess" ]]; then
      pass_or_id=$(jq -r '.proxies."'$protocol'".id' <<< "${selected_user}")
    fi
    subs=$(jq -r '.subscription_url' <<< "${selected_user}")
    expires_at=$(jq -r '.expire' <<< "${row}")

    # Call the function to display detailed information based on protocol
    display_protocol_details "$user" "$protocol" "$used_traffic" "$data_limit" "$reset_strategy" "$pass_or_id" "$subs" "$expires_at_human"
    ;;
  *)
    echo "Pilihan tidak valid. Keluar."
    exit 1
    ;;
esac
