#!/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"
neutral="\e[0m"
orange="\e[38;5;130m"
blue="\e[38;5;39m"
yellow="\e[38;5;226m"
purple="\e[38;5;141m"
bold_white="\e[1;37m"
reset="\e[0m"
pink="\e[38;5;205m"
white="\e[38;5;255m"
cyan="\e[38;5;51m"

DB_FILE="/etc/ssh/.ssh.db"

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" "$text" "$reset"
        printf "%*s" "$right" ""
        printf " %b│%b\n" "$orange" "$reset"

        offset=$((offset + available))
        text="${text:$available}"
        offset=0

        if [ -z "$text" ]; then
            break
        fi
    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
}

show_header() {
    clear

    box_top
    box_center "$BRAND" "$green"
    box_center "SSH / OVPN MANAGER" "$bold_white"
    box_bottom
}

pause_menu() {
    echo ""
    read -n 1 -s -r -p "Tekan tombol apa saja untuk kembali..."
    echo ""
}

ensure_database() {
    mkdir -p /etc/ssh

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

get_account_count() {
    ensure_database
    grep -c '^### ' "$DB_FILE" 2>/dev/null || echo "0"
}

get_days_left() {
    local exp="$1"
    local exp_timestamp
    local current_timestamp
    local days_left

    exp_timestamp=$(date -d "$exp" +%s 2>/dev/null)
    current_timestamp=$(date +%s)

    if [ -z "$exp_timestamp" ]; then
        echo "0"
        return
    fi

    days_left=$(((exp_timestamp - current_timestamp) / 86400))

    if [ "$days_left" -lt 0 ]; then
        days_left=0
    fi

    echo "$days_left"
}

show_account_table() {
    local index=1
    local user
    local exp
    local days_left

    printf " ┌────┬────────────────────┬─────────────┐\n"
    printf " │ No │ Username           │ Sisa Aktif  │\n"
    printf " ├────┼────────────────────┼─────────────┤\n"

    while read -r marker user exp; do
        [ "$marker" != "###" ] && continue
        [ -z "$user" ] && continue

        days_left=$(get_days_left "$exp")

        printf " │ %-2s │ %-18s │ %-9s   │\n" \
            "$index" \
            "$user" \
            "${days_left} hari"

        index=$((index + 1))
    done <"$DB_FILE"

    printf " └────┴────────────────────┴─────────────┘\n"
}

select_account() {
    local account_count
    local account_number

    account_count=$(get_account_count)

    if [ "$account_count" -eq 0 ]; then
        return 1
    fi

    echo ""
    show_account_table
    echo ""

    while true; do
        read -rp "Pilih nomor akun [1-${account_count}] : " account_number

        if [[ "$account_number" =~ ^[0-9]+$ ]] &&
           [ "$account_number" -ge 1 ] &&
           [ "$account_number" -le "$account_count" ]; then
            break
        fi

        echo -e "${red}Nomor akun tidak valid.${reset}"
    done

    SELECTED_USER=$(
        grep '^### ' "$DB_FILE" |
            awk '{print $2}' |
            sed -n "${account_number}p"
    )

    SELECTED_EXP=$(
        grep '^### ' "$DB_FILE" |
            awk '{print $3}' |
            sed -n "${account_number}p"
    )

    [ -n "$SELECTED_USER" ]
}

autokill_ssh() {
    local sts
    local pilihan

    while true; do
        if [ -f "/etc/cron.d/autokill" ] &&
           grep -q "/usr/bin/autokill" /etc/cron.d/autokill 2>/dev/null; then
            sts="AKTIF"
        else
            sts="NONAKTIF"
        fi

        clear

        box_top
        box_center "$BRAND" "$green"
        box_center "SSH / OVPN AUTO KILL" "$bold_white"
        box_middle
        box_left "Status AutoKill : $sts" "$yellow"
        box_middle
        box_left "1. Jalankan setiap 5 menit" "$green"
        box_left "2. Jalankan setiap 10 menit" "$green"
        box_left "3. Jalankan setiap 15 menit" "$green"
        box_left "4. Nonaktifkan AutoKill" "$red"
        box_left "X. Kembali" "$white"
        box_bottom

        echo ""

        read -rp "Pilih menu [1-4/X] : " pilihan

        case "$pilihan" in
            1)
                cat >/etc/cron.d/autokill <<'EOF'
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
*/5 * * * * root /usr/bin/autokill
EOF

                chmod 644 /etc/cron.d/autokill
                systemctl restart cron >/dev/null 2>&1 || true

                echo -e "${green}AutoKill diatur setiap 5 menit.${reset}"
                pause_menu
                ;;
            2)
                cat >/etc/cron.d/autokill <<'EOF'
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
*/10 * * * * root /usr/bin/autokill
EOF

                chmod 644 /etc/cron.d/autokill
                systemctl restart cron >/dev/null 2>&1 || true

                echo -e "${green}AutoKill diatur setiap 10 menit.${reset}"
                pause_menu
                ;;
            3)
                cat >/etc/cron.d/autokill <<'EOF'
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
*/15 * * * * root /usr/bin/autokill
EOF

                chmod 644 /etc/cron.d/autokill
                systemctl restart cron >/dev/null 2>&1 || true

                echo -e "${green}AutoKill diatur setiap 15 menit.${reset}"
                pause_menu
                ;;
            4)
                rm -f /etc/cron.d/autokill
                systemctl restart cron >/dev/null 2>&1 || true

                echo -e "${green}AutoKill berhasil dinonaktifkan.${reset}"
                pause_menu
                ;;
            x|X)
                return
                ;;
            *)
                echo -e "${red}Pilihan tidak valid.${reset}"
                sleep 1
                ;;
        esac
    done
}

lock_ssh() {
    local account_count
    local username

    clear

    box_top
    box_center "$BRAND" "$green"
    box_center "LOCK AKUN SSH / OVPN" "$bold_white"
    box_bottom

    account_count=$(get_account_count)

    if [ "$account_count" -eq 0 ]; then
        echo ""

        box_top
        box_center "TIDAK ADA AKUN" "$yellow"
        box_middle
        box_center "Belum ada akun SSH / OVPN terdaftar." "$white"
        box_bottom

        pause_menu
        return
    fi

    if ! select_account; then
        pause_menu
        return
    fi

    username="$SELECTED_USER"

    if ! id "$username" >/dev/null 2>&1; then
        echo -e "${red}Username $username tidak ditemukan pada sistem.${reset}"
        pause_menu
        return
    fi

    if [ "$username" = "root" ] ||
       [ "$username" = "admin" ]; then
        echo -e "${red}Akun sistem $username tidak dapat dikunci.${reset}"
        pause_menu
        return
    fi

    if passwd -S "$username" 2>/dev/null |
        awk '{print $2}' |
        grep -q '^L'; then

        echo -e "${yellow}Akun $username sudah dalam keadaan terkunci.${reset}"
        pause_menu
        return
    fi

    if passwd -l "$username" >/dev/null 2>&1; then
        pkill -u "$username" >/dev/null 2>&1 || true

        mkdir -p /var/log

        echo "$(date '+%Y-%m-%d %H:%M:%S') | LOCK | ${username}" \
            >>/var/log/ssh_account_actions.log

        clear

        box_top
        box_center "$BRAND" "$green"
        box_center "AKUN BERHASIL DIKUNCI" "$bold_white"
        box_middle
        box_left "Username   : $username" "$white"
        box_left "Kadaluarsa : $SELECTED_EXP" "$white"
        box_left "Status     : LOCKED" "$red"
        box_bottom
    else
        echo -e "${red}Gagal mengunci akun $username.${reset}"
    fi

    pause_menu
}

unlock_ssh() {
    local account_count
    local username
    local status

    clear

    box_top
    box_center "$BRAND" "$green"
    box_center "UNLOCK AKUN SSH / OVPN" "$bold_white"
    box_bottom

    account_count=$(get_account_count)

    if [ "$account_count" -eq 0 ]; then
        echo ""

        box_top
        box_center "TIDAK ADA AKUN" "$yellow"
        box_middle
        box_center "Belum ada akun SSH / OVPN terdaftar." "$white"
        box_bottom

        pause_menu
        return
    fi

    if ! select_account; then
        pause_menu
        return
    fi

    username="$SELECTED_USER"

    if ! id "$username" >/dev/null 2>&1; then
        echo -e "${red}Username $username tidak ditemukan pada sistem.${reset}"
        pause_menu
        return
    fi

    status=$(
        passwd -S "$username" 2>/dev/null |
            awk '{print $2}'
    )

    if [ "$status" != "L" ]; then
        echo -e "${yellow}Akun $username sudah dalam keadaan aktif.${reset}"
        pause_menu
        return
    fi

    if passwd -u "$username" >/dev/null 2>&1; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') | UNLOCK | ${username}" \
            >>/var/log/ssh_account_actions.log

        clear

        box_top
        box_center "$BRAND" "$green"
        box_center "AKUN BERHASIL DIBUKA" "$bold_white"
        box_middle
        box_left "Username   : $username" "$white"
        box_left "Kadaluarsa : $SELECTED_EXP" "$white"
        box_left "Status     : AKTIF" "$green"
        box_bottom
    else
        echo -e "${red}Gagal membuka akun $username.${reset}"
    fi

    pause_menu
}

detail_ssh() {
    local account_count
    local username
    local exp
    local ip_limit
    local status
    local status_text
    local log_file

    clear

    box_top
    box_center "$BRAND" "$green"
    box_center "DETAIL AKUN SSH / OVPN" "$bold_white"
    box_bottom

    account_count=$(get_account_count)

    if [ "$account_count" -eq 0 ]; then
        echo ""

        box_top
        box_center "TIDAK ADA AKUN" "$yellow"
        box_bottom

        pause_menu
        return
    fi

    if ! select_account; then
        pause_menu
        return
    fi

    username="$SELECTED_USER"
    exp="$SELECTED_EXP"

    ip_limit=$(cat "/etc/ssh/${username}" 2>/dev/null)
    ip_limit=${ip_limit:-0}

    if [ "$ip_limit" = "0" ]; then
        ip_limit="Unlimited"
    fi

    if id "$username" >/dev/null 2>&1; then
        status=$(
            passwd -S "$username" 2>/dev/null |
                awk '{print $2}'
        )

        if [ "$status" = "L" ]; then
            status_text="LOCKED"
            status_color="$red"
        else
            status_text="AKTIF"
            status_color="$green"
        fi
    else
        status_text="TIDAK DITEMUKAN"
        status_color="$red"
    fi

    clear

    box_top
    box_center "$BRAND" "$green"
    box_center "DETAIL AKUN SSH / OVPN" "$bold_white"
    box_middle
    box_left "Username    : $username" "$white"
    box_left "Kadaluarsa  : $exp" "$white"
    box_left "Sisa Aktif  : $(get_days_left "$exp") Hari" "$white"
    box_left "Batas IP    : $ip_limit" "$white"
    box_left "Status      : $status_text" "$status_color"
    box_bottom

    log_file="/etc/xray/log-createssh-${username}.log"

    if [ -f "$log_file" ]; then
        echo ""
        cat "$log_file"
    else
        echo ""
        echo -e "${yellow}Log pembuatan akun tidak ditemukan.${reset}"
    fi

    pause_menu
}

changelimit() {
    local account_count
    local user
    local iplim
    local ip_display

    clear

    box_top
    box_center "$BRAND" "$green"
    box_center "UBAH LIMIT SSH / OVPN" "$bold_white"
    box_bottom

    account_count=$(get_account_count)

    if [ "$account_count" -eq 0 ]; then
        echo ""

        box_top
        box_center "TIDAK ADA AKUN" "$yellow"
        box_bottom

        pause_menu
        return
    fi

    if ! select_account; then
        pause_menu
        return
    fi

    user="$SELECTED_USER"

    echo ""

    box_top
    box_center "AKUN TERPILIH" "$yellow"
    box_middle
    box_left "Username   : $user" "$white"
    box_left "Kadaluarsa : $SELECTED_EXP" "$white"
    box_bottom

    echo ""

    while true; do
        read -rp "Batas IP baru [0 = Unlimited, X = batal] : " iplim

        case "$iplim" in
            x|X)
                return
                ;;
        esac

        if [[ "$iplim" =~ ^[0-9]+$ ]]; then
            break
        fi

        echo -e "${red}Batas IP harus berupa angka 0 atau lebih.${reset}"
    done

    printf '%s\n' "$iplim" >"/etc/ssh/${user}"

    if [ "$iplim" -eq 0 ]; then
        ip_display="Unlimited"
    else
        ip_display="${iplim} Perangkat"
    fi

    clear

    box_top
    box_center "$BRAND" "$green"
    box_center "LIMIT BERHASIL DIPERBARUI" "$bold_white"
    box_middle
    box_left "Username : $user" "$white"
    box_left "Batas IP : $ip_display" "$green"
    box_bottom

    pause_menu
}

member_ssh() {
    local data
    local user
    local exp
    local dayleft
    local status
    local status_text
    local iplimit
    local total=0

    clear

    box_top
    box_center "$BRAND" "$green"
    box_center "DAFTAR MEMBER SSH / OVPN" "$bold_white"
    box_bottom

    ensure_database

    data=$(
        grep '^### ' "$DB_FILE" 2>/dev/null |
            awk '{print $2, $3}'
    )

    if [ -z "$data" ]; then
        echo ""

        box_top
        box_center "TIDAK ADA AKUN" "$yellow"
        box_middle
        box_center "Belum ada akun SSH / OVPN terdaftar." "$white"
        box_bottom

        pause_menu
        return
    fi

    echo ""

    while read -r user exp; do
        [ -z "$user" ] && continue

        dayleft=$(get_days_left "$exp")

        if id "$user" >/dev/null 2>&1; then
            status=$(
                passwd -S "$user" 2>/dev/null |
                    awk '{print $2}'
            )

            if [ "$status" = "L" ]; then
                status_text="LOCKED"
                status_color="$red"
            else
                status_text="AKTIF"
                status_color="$green"
            fi
        else
            status_text="TIDAK DITEMUKAN"
            status_color="$red"
        fi

        iplimit=$(cat "/etc/ssh/${user}" 2>/dev/null)
        iplimit=${iplimit:-0}

        if [ "$iplimit" = "0" ]; then
            iplimit="Unlimited"
        fi

        box_top
        box_left "Username    : $user" "$white"
        box_left "Status      : $status_text" "$status_color"
        box_left "Batas IP    : $iplimit" "$white"
        box_left "Sisa Aktif  : $dayleft Hari" "$white"
        box_left "Kadaluarsa  : $exp" "$white"
        box_bottom

        echo ""

        total=$((total + 1))
    done <<<"$data"

    box_top
    box_center "TOTAL AKUN : $total" "$green"
    box_bottom

    pause_menu
}

run_command() {
    local command_name="$1"
    local label="$2"

    if command -v "$command_name" >/dev/null 2>&1; then
        "$command_name"
        return
    fi

    clear

    box_top
    box_center "$BRAND" "$green"
    box_center "$label" "$bold_white"
    box_middle
    box_center "PERINTAH TIDAK DITEMUKAN" "$red"
    box_middle
    box_left "Command : $command_name" "$yellow"
    box_bottom

    pause_menu
}

display_ssh_menu() {
    local ssh_choice

    while true; do
        clear

        box_top
        box_center "$BRAND" "$green"
        box_center "SSH / OVPN MANAGER" "$bold_white"
        box_middle
        box_left "1. Buat Akun SSH / OVPN" "$green"
        box_left "2. Hapus Akun SSH / OVPN" "$green"
        box_left "3. Renew Akun SSH / OVPN" "$green"
        box_left "4. Cek Login SSH / OVPN" "$green"
        box_left "5. Daftar Member SSH / OVPN" "$green"
        box_left "6. Ubah Limit Akun SSH / OVPN" "$green"
        box_left "7. Lock Akun SSH / OVPN" "$green"
        box_left "8. Unlock Akun SSH / OVPN" "$green"
        box_left "9. Detail Akun SSH / OVPN" "$green"
        box_left "10. AutoKill SSH / OVPN" "$green"
        box_left "11. Buat Trial SSH / OVPN" "$green"
        box_left "X. Keluar" "$red"
        box_bottom

        echo ""

        read -rp "Pilih menu [1-11/X] : " ssh_choice

        case "$ssh_choice" in
            1)
                run_command "addssh" "BUAT AKUN SSH / OVPN"
                ;;
            2)
                run_command "dellssh" "HAPUS AKUN SSH / OVPN"
                ;;
            3)
                run_command "renewssh" "RENEW AKUN SSH / OVPN"
                ;;
            4)
                run_command "checkssh" "CEK LOGIN SSH / OVPN"
                ;;
            5)
                member_ssh
                ;;
            6)
                changelimit
                ;;
            7)
                lock_ssh
                ;;
            8)
                unlock_ssh
                ;;
            9)
                detail_ssh
                ;;
            10)
                autokill_ssh
                ;;
            11)
                run_command "trialssh" "TRIAL SSH / OVPN"
                ;;
            x|X)
                clear

                box_top
                box_center "$BRAND" "$green"
                box_center "KELUAR DARI SSH / OVPN MANAGER" "$bold_white"
                box_middle
                box_center "Terima kasih telah menggunakan layanan kami." "$white"
                box_middle
                box_left "WhatsApp ~ $WHATSAPP" "$green"
                box_left "Telegram ~ $TELEGRAM" "$cyan"
                box_bottom

                exit 0
                ;;
            *)
                echo ""
                echo -e "${red}Pilihan tidak valid. Silakan coba kembali.${reset}"
                sleep 1
                ;;
        esac
    done
}

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))

ensure_database
display_ssh_menu