#!/bin/bash
clear

domain=$(cat /root/domain)
api_host="127.0.0.1"
get_marzban_api_port() {
  local env_file="/opt/marzban/.env"
  [[ -r "$env_file" ]] || { echo "7879"; return; }   # fallback opsional

  local port
  port="$(grep -E '^[[:space:]]*UVICORN_PORT[[:space:]]*=' "$env_file" \
           | tail -n1 \
           | sed -E 's/.*=[[:space:]]*["'\'']?([0-9]+).*/\1/')"

  # Validasi angka
  if [[ "$port" =~ ^[0-9]+$ ]]; then
    echo "$port"
  else
    echo "7879"   # fallback opsional lain
  fi
}

api_port="$(get_marzban_api_port)"

# 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_human="$3"
  data_limit_human="$4"
  reset_strategy="$5"
  pass_or_id="$6"
  subs="$7"
  expires_at_human="$8"

# Convert protocol to uppercase
protocol_uppercase=$(echo "${protocol}" | awk '{print toupper($0)}')

  echo -e "=======-XRAY/${protocol_uppercase}======="
  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   Penggunaan Data     Total Penggunaan Data  Data Limit    Reset Strategy      Expires At"
printf "%-5s %-24s %-9s %-8s %-19s %-22s %-13s %-19s %s\n" "-----" "------------------------" "---------" "--------" "---------------" "-----------------------" "-------------" "-------------------" "---------------------"

# Check if there are no users
if [ "$(jq -c '.users | length' <<< "${response}")" -eq 0 ]; then
  echo "Belum ada user yang dibuat disini"
  echo""
else
  # 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}")
    lifetime_used_traffic=$(jq -r '.lifetime_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)
    lifetime_used_traffic_human=$(echo "${lifetime_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}")

    # Use a single printf statement for the separator line and data
    printf "%-5s %-24s %-9s %-8s %-19s %-22s %-13s %-19s %s\n" "${count}" "${username}" "${protocol}" "${status}" "${used_traffic_human}" "${lifetime_used_traffic_human}" "${data_limit_human}" "${reset_strategy}" "${expires_at_human}"

    ((count++))
  done <<< "$(jq -c '.users[]' <<< "${response}")"
fi

# 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"
echo "5. Exit"
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}")
    username_to_delete=$(jq -r '.username' <<< "${selected_user}")

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

    echo "User ${username_to_delete} telah berhasil dihapus."
    rm -r /var/www/html/oc-${username_to_delete}.conf
    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_epoch=$(jq -r '.expire' <<< "${selected_user}")

    # Convert epoch timestamp to human-readable date
    expires_at_human=$(date -d "@$expires_at_epoch" +"%Y-%m-%d %H:%M:%S")

    # 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

# Call the function to display detailed information based on protocol
display_protocol_details "$user" "$protocol" "$used_traffic_human" "$data_limit_human" "$reset_strategy" "$pass_or_id" "$subs" "$expires_at_human"
    ;;
  5)
    echo "Keluar dari skrip."
    exit 0
    ;;
  *)
    echo "Pilihan tidak valid. Keluar."
    exit 1
    ;;
esac
