#!/bin/bash

BASE_URL="https://autoscript.interflazz.my.id/v2"
BRAND="INTERFLAZZ.MY.ID"
WHATSAPP="https://wa.me/6285956131443"
TELEGRAM="https://t.me/interflazz"

green="\e[38;5;82m"
red="\e[38;5;196m"
yellow="\e[38;5;226m"
cyan="\e[38;5;51m"
white="\e[97m"
orange="\e[38;5;130m"
bold_white="\e[1;37m"
reset="\e[0m"

INTERVAL_SECONDS=30

update_box_width() {
    local cols

    cols=$(tput cols 2>/dev/null || echo 80)

    if [ "$cols" -gt 72 ]; then
        BOX_WIDTH=72
    elif [ "$cols" -lt 30 ]; then
        BOX_WIDTH=30
    else
        BOX_WIDTH=$((cols - 2))
    fi

    BOX_INNER=$((BOX_WIDTH - 4))
}

repeat_char() {
    local count="$1"
    local char="$2"
    local line

    printf -v line '%*s' "$count" ""
    printf '%s' "${line// /$char}"
}

box_top() {
    update_box_width

    printf "%b┌" "$orange"
    repeat_char $((BOX_WIDTH - 2)) "─"
    printf "┐%b\n" "$reset"
}

box_middle() {
    update_box_width

    printf "%b├" "$orange"
    repeat_char $((BOX_WIDTH - 2)) "─"
    printf "┤%b\n" "$reset"
}

box_bottom() {
    update_box_width

    printf "%b└" "$orange"
    repeat_char $((BOX_WIDTH - 2)) "─"
    printf "┘%b\n" "$reset"
}

box_empty() {
    update_box_width

    printf "%b│%b" "$orange" "$reset"
    printf "%*s" $((BOX_WIDTH - 2)) ""
    printf "%b│%b\n" "$orange" "$reset"
}

box_center() {
    update_box_width

    local text="$1"
    local color="${2:-$white}"
    local length=${#text}
    local available="$BOX_INNER"

    if [ "$length" -gt "$available" ]; then
        box_left "$text" "$color"
        return
    fi

    local left=$(((available - length) / 2))
    local right=$((available - length - left))

    printf "%b│%b " "$orange" "$reset"
    printf "%*s" "$left" ""
    printf "%b%s%b" "$color" "$text" "$reset"
    printf "%*s" "$right" ""
    printf " %b│%b\n" "$orange" "$reset"
}

box_left() {
    update_box_width

    local text="$1"
    local color="${2:-$white}"
    local available="$BOX_INNER"
    local length=${#text}
    local offset=0
    local part
    local part_length
    local right

    if [ "$length" -eq 0 ]; then
        box_empty
        return
    fi

    while [ "$offset" -lt "$length" ]; do
        part="${text:$offset:$available}"
        part_length=${#part}
        right=$((available - part_length))

        printf "%b│%b " "$orange" "$reset"
        printf "%b%s%b" "$color" "$part" "$reset"
        printf "%*s" "$right" ""
        printf " %b│%b\n" "$orange" "$reset"

        offset=$((offset + available))
    done
}

show_access_denied() {
    local reason="$1"

    clear

    box_top
    box_center "$BRAND" "$green"
    box_center "AUTOSCRIPT PREMIUM" "$bold_white"
    box_middle
    box_center "AKSES DITOLAK!" "$red"
    box_middle
    box_left "IP VPS : $vps_ip" "$yellow"
    box_left "$reason" "$yellow"
    box_middle
    box_center "HUBUNGI ADMIN" "$bold_white"
    box_left "WhatsApp ~ $WHATSAPP" "$green"
    box_left "Telegram ~ $TELEGRAM" "$cyan"
    box_bottom

    exit 1
}

convert_size() {
    local bytes="${1:-0}"

    if ! [[ "$bytes" =~ ^[0-9]+$ ]]; then
        bytes=0
    fi

    if [ "$bytes" -lt 1024 ]; then
        echo "${bytes} B"
    elif [ "$bytes" -lt 1048576 ]; then
        echo "$(((bytes + 1023) / 1024)) KB"
    elif [ "$bytes" -lt 1073741824 ]; then
        echo "$(((bytes + 1048575) / 1048576)) MB"
    elif [ "$bytes" -lt 1099511627776 ]; then
        echo "$(((bytes + 1073741823) / 1073741824)) GB"
    else
        echo "$(((bytes + 1099511627775) / 1099511627776)) TB"
    fi
}

send_telegram() {
    local protocol="$1"
    local user="$2"
    local readable_usage="$3"
    local readable_limit="$4"
    local message

    if [ ! -f "/root/.vars" ]; then
        return
    fi

    source /root/.vars

    if [ -z "${bot_token:-}" ] || [ -z "${telegram_id:-}" ]; then
        return
    fi

    message="<b>━━━━━━━━━━━━━━━━━━</b>
<b>INTERFLAZZ.MY.ID</b>
<b>🔔 NOTIFIKASI ${protocol^^}</b>
<b>🚫 KUOTA TELAH HABIS</b>
<b>━━━━━━━━━━━━━━━━━━</b>
<b>👤 Username :</b> <code>${user}</code>
<b>📊 Penggunaan :</b> <code>${readable_usage}</code>
<b>🔒 Batas Kuota :</b> <code>${readable_limit}</code>
<b>⚠️ Status :</b> <code>Akun Dihapus</code>
<b>━━━━━━━━━━━━━━━━━━</b>"

    curl -s \
        --connect-timeout 10 \
        --max-time 20 \
        -X POST \
        "https://api.telegram.org/bot${bot_token}/sendMessage" \
        --data-urlencode "chat_id=${telegram_id}" \
        --data-urlencode "parse_mode=HTML" \
        --data-urlencode "text=${message}" \
        >/dev/null 2>&1
}

get_stat_value() {
    local api_port="$1"
    local user="$2"
    local stat_name="$3"
    local output
    local value

    output=$(
        xray api stats \
            --server="127.0.0.1:${api_port}" \
            -name "user>>>${user}>>>traffic>>>${stat_name}" \
            2>/dev/null
    )

    value=$(
        printf '%s\n' "$output" |
            awk '
                /value:/ {
                    gsub(/"/, "", $2)
                    print $2
                    exit
                }
            '
    )

    if ! [[ "$value" =~ ^[0-9]+$ ]]; then
        value=0
    fi

    printf '%s' "$value"
}

reset_stat() {
    local api_port="$1"
    local user="$2"
    local stat_name="$3"

    xray api stats \
        --server="127.0.0.1:${api_port}" \
        -name "user>>>${user}>>>traffic>>>${stat_name}" \
        -reset \
        >/dev/null 2>&1
}

delete_account_files() {
    local protocol="$1"
    local user="$2"

    rm -f \
        "/etc/xray/${protocol}/${user}" \
        "/etc/xray/${protocol}/${user}IP" \
        "/etc/xray/${protocol}/usage/${user}" \
        "/etc/xray/${protocol}/log-create-${user}.log" \
        "/etc/xray/${protocol}/${user}-non.json" \
        "/etc/xray/${protocol}/${user}-tls.json" \
        "/etc/xray/${protocol}/${user}-grpc.json" \
        "/var/www/html/${protocol}-${user}.txt"
}

delete_account() {
    local protocol="$1"
    local user="$2"
    local exp="$3"
    local config_file="$4"
    local db_file="$5"

    if [ -f "$config_file" ]; then
        sed -i "/^### ${user} ${exp}$/,+1d" "$config_file"
    fi

    if [ -f "$db_file" ]; then
        sed -i "/^### ${user} /d" "$db_file"
    fi

    delete_account_files "$protocol" "$user"

    if ! systemctl restart "${protocol}@config" >/dev/null 2>&1; then
        printf '%s | %s | Gagal restart service %s@config\n' \
            "$(date '+%Y-%m-%d %H:%M:%S')" \
            "$user" \
            "$protocol" \
            >>/var/log/xray/quota.log
    fi
}

process_users() {
    local protocol="$1"
    local api_port="$2"
    local base_dir="/etc/xray/${protocol}"
    local config_file="${base_dir}/config.json"
    local usage_dir="${base_dir}/usage"
    local db_file="${base_dir}/.${protocol}.db"
    local user
    local exp
    local downlink_value
    local uplink_value
    local traffic_value
    local current_usage
    local new_usage
    local limit
    local readable_usage
    local readable_limit

    mkdir -p "$usage_dir"

    if [ ! -f "$db_file" ]; then
        touch "$db_file"
    fi

    if [ ! -f "$config_file" ]; then
        return
    fi

    mapfile -t users < <(
        grep '^### ' "$db_file" 2>/dev/null |
            awk '{print $2}' |
            sort -u
    )

    for user in "${users[@]}"; do
        [ -z "$user" ] && continue

        downlink_value=$(get_stat_value "$api_port" "$user" "downlink")
        uplink_value=$(get_stat_value "$api_port" "$user" "uplink")

        if ! [[ "$downlink_value" =~ ^[0-9]+$ ]]; then
            downlink_value=0
        fi

        if ! [[ "$uplink_value" =~ ^[0-9]+$ ]]; then
            uplink_value=0
        fi

        traffic_value=$((downlink_value + uplink_value))

        current_usage=$(cat "${usage_dir}/${user}" 2>/dev/null)
        current_usage=${current_usage:-0}

        if ! [[ "$current_usage" =~ ^[0-9]+$ ]]; then
            current_usage=0
        fi

        if [ "$traffic_value" -gt 0 ]; then
            new_usage=$((current_usage + traffic_value))

            printf '%s\n' "$new_usage" \
                >"${usage_dir}/${user}"

            reset_stat "$api_port" "$user" "downlink"
            reset_stat "$api_port" "$user" "uplink"
        elif [ ! -f "${usage_dir}/${user}" ]; then
            printf '0\n' >"${usage_dir}/${user}"
        fi
    done

    for user in "${users[@]}"; do
        [ -z "$user" ] && continue

        limit=$(cat "${base_dir}/${user}" 2>/dev/null)
        limit=${limit:-0}

        if ! [[ "$limit" =~ ^[0-9]+$ ]]; then
            limit=0
        fi

        if [ "$limit" -eq 0 ]; then
            continue
        fi

        current_usage=$(cat "${usage_dir}/${user}" 2>/dev/null)
        current_usage=${current_usage:-0}

        if ! [[ "$current_usage" =~ ^[0-9]+$ ]]; then
            current_usage=0
        fi

        if [ "$current_usage" -lt "$limit" ]; then
            continue
        fi

        exp=$(
            grep "^### ${user} " "$db_file" 2>/dev/null |
                head -1 |
                awk '{print $3}'
        )

        if [ -z "$exp" ]; then
            continue
        fi

        readable_usage=$(convert_size "$current_usage")
        readable_limit=$(convert_size "$limit")

        printf '%s | %s | %s | Penggunaan %s | Batas %s | Akun dihapus\n' \
            "$(date '+%Y-%m-%d %H:%M:%S')" \
            "${protocol^^}" \
            "$user" \
            "$readable_usage" \
            "$readable_limit" \
            >>/var/log/xray/quota.log

        send_telegram \
            "$protocol" \
            "$user" \
            "$readable_usage" \
            "$readable_limit"

        delete_account \
            "$protocol" \
            "$user" \
            "$exp" \
            "$config_file" \
            "$db_file"
    done
}

mkdir -p \
    /etc/xray/vmess/usage \
    /etc/xray/vless/usage \
    /etc/xray/trojan/usage \
    /etc/xray/shadowsocks/usage \
    /var/log/xray

touch /var/log/xray/quota.log

vps_ip=$(wget -qO- ipv4.icanhazip.com)

if [ -z "$vps_ip" ]; then
    vps_ip=$(curl -4 -s ipv4.icanhazip.com)
fi

if [ -z "$vps_ip" ]; then
    vps_ip="Tidak diketahui"
fi

data_acc=$(
    curl -s "${BASE_URL}/access" |
        grep "### $vps_ip " |
        awk '{print $3}'
)

if [ -z "$data_acc" ]; then
    show_access_denied "VPS belum memiliki izin akses script."
fi

expiry_date=$(date -d "$data_acc" +%s 2>/dev/null)
current_date=$(date +%s)

if [ -z "$expiry_date" ]; then
    show_access_denied "Data masa aktif script tidak valid."
fi

if [ "$expiry_date" -le "$current_date" ]; then
    show_access_denied "Masa aktif akses script telah berakhir."
fi

remaining_days=$(((expiry_date - current_date) / 86400))

while true; do
    process_users "vmess" 20001
    process_users "vless" 20002
    process_users "trojan" 20003
    process_users "shadowsocks" 20004

    sleep "$INTERVAL_SECONDS"
done