#!/bin/bash
# ======================================================
#   HOKAGE LEGEND ZIVPN MANAGER (THEMED EDITION)
# ======================================================

# --- DEFINISI WARNA & VAR ---
y='\033[1;33m' # Yellow / Gold
z='\033[96m'   # Cyan
NC='\033[0m'   # No Color
GREEN='\033[0;32m'
RED='\033[0;31m'
PURPLE='\033[1;35m'
BLINK='\033[5m'

CONFIG_FILE="/etc/zivpn/config.json"
USER_DB="/etc/zivpn/user-db.json"
SERVICE_NAME="zivpn.service"
BACKUP_DIR="/root/backup/zivpn"

# --- DATA BOT TELEGRAM ---
if [ -f "/etc/bot/.bot.db" ]; then
    CHATID=$(grep -E "^#bot# " "/etc/bot/.bot.db" | cut -d ' ' -f 3)
    KEY=$(grep -E "^#bot# " "/etc/bot/.bot.db" | cut -d ' ' -f 2)
    URL="https://api.telegram.org/bot$KEY/sendMessage"
else
    CHATID=""; KEY=""; URL=""
fi

# ==================================================
# FUNGSI GRADASI (FAST RENDER)
# ==================================================
print_gradient() {
    local text="$1"
    awk -v text="$text" 'BEGIN {
        len = length(text);
        rs=255; gs=215; bs=0;
        rm=0;   gm=128; bm=255;
        re=138; ge=43;  be=226;
        for (i=0; i<len; i++) {
            ratio = i / (len-1);
            if (ratio <= 0.5) {
                f = ratio * 2;
                r = int(rs + (rm - rs) * f);
                g = int(gs + (gm - gs) * f);
                b = int(bs + (bm - bs) * f);
            } else {
                f = (ratio - 0.5) * 2;
                r = int(rm + (re - rm) * f);
                g = int(gm + (ge - gm) * f);
                b = int(bm + (be - bm) * f);
            }
            printf "\033[38;2;%d;%d;%dm%s", r, g, b, substr(text, i+1, 1);
        }
        printf "\033[0m\n";
    }'
}

# ==================================================
# FUNGSI CETAK BARIS RAPI
# ==================================================
print_row() {
    local label="$1"
    local val_text="$2"
    local val_clean=$(echo -e "$val_text" | sed "s/\x1b\[[0-9;]*m//g")
    local len_val=${#val_clean}
    local max_space=30
    local pad_len=$(( max_space - len_val ))
    if [[ $pad_len -lt 0 ]]; then pad_len=0; fi
    local padding=""
    for ((i=0; i<pad_len; i++)); do padding+=" "; done
    echo -e " ${z}│${NC} ${y}$(printf "%-12s" "$label")${NC} : ${val_text}${padding}${z}│${NC}"
}

function restart_service() { 
    systemctl restart "$SERVICE_NAME"
}

# --- FUNGSI HAPUS USER (CORE LOGIC) ---
function remove_user_data() {
    local user=$1
    # Hapus dari config.json
    jq --arg u "$user" '.auth.config -= [$u]' "$CONFIG_FILE" > "${CONFIG_FILE}.tmp" && mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"
    # Hapus dari user-db.json
    jq --arg u "$user" 'del(.[$u])' "$USER_DB" > "${USER_DB}.tmp" && mv "${USER_DB}.tmp" "$USER_DB"
    # Hapus system user & limit
    userdel -f "$user" &>/dev/null
    rm -f /etc/kyt/limit/ssh/ip/$user
}

# ==================================================
# 1. MONITOR / LIST USER (THEME STYLE)
# ==================================================
function list_users() {
    clear
    echo -e ""
    print_gradient "╭══════════════════════════════════════════════╮"
    print_gradient "│           MONITOR ZIVPN USER UTAMA           │"
    print_gradient "╰══════════════════════════════════════════════╯"
    echo -e ""

    users=($(jq -r '.auth.config[]' "$CONFIG_FILE"))
    today_sec=$(date +%s)
    total_active=0

    for user in "${users[@]}"; do
        if [[ "$user" == "zi" || -z "$user" ]]; then continue; fi
        
        ((total_active++))

        # Ambil Data dari DB
        exp=$(jq -r --arg u "$user" '.[$u].exp // "Unknown"' "$USER_DB")
        quota=$(jq -r --arg u "$user" '.[$u].quota // "Unlimited"' "$USER_DB")
        iplimit=$(jq -r --arg u "$user" '.[$u].ip // "Unlimited"' "$USER_DB")

        # Hitung Sisa Hari & Auto Delete
        if [[ "$exp" != "Unknown" ]]; then
            exp_sec=$(date -d "$exp" +%s 2>/dev/null)
            
            # Logic Auto Delete jika Expired
            if [[ $? -eq 0 && "$today_sec" -gt "$exp_sec" ]]; then
                remove_user_data "$user"
                continue # Skip display if deleted
            fi
            
            # Hitung hari
            d1=$(date -d "$exp" +%s)
            d2=$(date -d "$(date +%Y-%m-%d)" +%s)
            sisa_hari=$(( (d1 - d2) / 86400 ))
            
            if [[ "$sisa_hari" -lt 0 ]]; then
                validity="${RED}Expired${NC}"
            else
                validity="${GREEN}${BLINK}${sisa_hari} Hari${NC}"
            fi
        else
            validity="${GREEN}Unlimited${NC}"
        fi

        # Status Active (ZiVPN tidak punya log login real-time yg mudah, kita asumsi Active jika belum exp)
        status_akun="${GREEN}${BLINK}[Active]${NC}"

        # Tampilkan Card
        echo -e " ${z}╭══════════════════════════════════════════════╮${NC}"
        print_row "User" "$user"
        print_row "Expired" "$exp"
        print_row "Masa Aktif" "$validity"
        print_row "Status" "$status_akun"
        print_row "Kuota" "$quota"
        print_row "Limit IP" "$iplimit"
        echo -e " ${z}╰══════════════════════════════════════════════╯${NC}"
    done

    if [[ $total_active -eq 0 ]]; then
        echo -e " ${RED}       Tidak ada user ZiVPN yang terdaftar.${NC}"
    fi
    
    echo -e ""
    print_gradient "════════════════════════════════════════════════"
    read -n 1 -s -r -p "Press any key to back..."
}

# ==================================================
# 2. ADD USER
# ==================================================
function add_user() {
    clear
    print_gradient "╭══════════════════════════════════════════════╮"
    print_gradient "│             CREATE ZIVPN ACCOUNT             │"
    print_gradient "╰══════════════════════════════════════════════╯"
    echo -e ""

    read -p " Username    : " username
    # Cek exist
    if grep -q "\"$username\"" "$CONFIG_FILE"; then
        echo -e "${RED} Error: Username '$username' already exists!${NC}"
        sleep 2; return
    fi

    read -p " Password    : " password
    read -p " Expired (D) : " masa_aktif
    read -p " Limit IP    : " iplimit
    read -p " Limit Quota : " quota

    # Set Default
    [ -z "$password" ] && password="$username"
    [ -z "$masa_aktif" ] && masa_aktif="30"
    [ -z "$iplimit" ] && iplimit="Unlimited"
    [ -z "$quota" ] && quota="Unlimited"

    # Kalkulasi Tanggal
    exp_date=$(date -d "+$masa_aktif days" +%Y-%m-%d)
    tgl_exp=$(date -d "+$masa_aktif days" +"%d %b %Y")
    
    # Create System User
    useradd -e "$exp_date" -s /bin/false -M "$username"
    echo -e "$password\n$password" | passwd "$username" &>/dev/null
    
    # Save IP Limit (Untuk Script Limit Lain)
    if [[ "$iplimit" != "Unlimited" ]]; then
        echo "$iplimit" > /etc/kyt/limit/ssh/ip/$username
    fi

    # Update Config & DB
    jq --arg user "$username" '.auth.config += [$user]' "$CONFIG_FILE" > "${CONFIG_FILE}.tmp" && mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"
    jq --arg u "$username" --arg e "$exp_date" --arg q "$quota" --arg i "$iplimit" \
       '.[$u] = {exp: $e, quota: $q, ip: $i}' "$USER_DB" > "${USER_DB}.tmp" && mv "${USER_DB}.tmp" "$USER_DB"
    
    restart_service

    # Telegram Notify
    if [ -n "$CHATID" ]; then
        TEXT="<b>☘️ Success Create ZiVPN ☘️</b>%0A<code>User : $username</code>%0A<code>Pass : $password</code>%0A<code>Exp  : $tgl_exp</code>"
        curl -s "$URL?chat_id=$CHATID&text=$TEXT&parse_mode=html" >/dev/null
    fi

    echo -e ""
    echo -e " ${GREEN}✅ User $username Berhasil Dibuat!${NC}"
    sleep 2
}

# ==================================================
# 3. SYNC SSH (FIX 2099 & GHOST)
# ==================================================
function sync_ssh() {
    clear
    print_gradient "════════════════════════════════════════════════"
    echo -e " ${y}⚙️  SYNCING SYSTEM USERS & CLEANING GHOST...${NC}"
    print_gradient "════════════════════════════════════════════════"
    
    # Clean Ghost (User di ZiVPN tapi gak ada di System)
    users_zivpn=$(jq -r '.auth.config[]' "$CONFIG_FILE")
    for u in $users_zivpn; do
        if ! id "$u" &>/dev/null && [ "$u" != "zi" ]; then
            remove_user_data "$u"
            echo -e " ${RED}[DEL]${NC} Ghost User: $u"
        fi
    done

    # Sync System to ZiVPN
    while IFS=: read -r username _ uid _ _ _ _; do
        if [[ $uid -ge 1000 && "$username" != "nobody" ]]; then
            raw_exp=$(chage -l "$username" | grep "Account expires" | cut -d: -f2)
            exp_iso=$(date -d "$raw_exp" +"%Y-%m-%d" 2>/dev/null || echo "2026-12-31")
            
            # Jika user belum ada di config.json, tambahkan
            if ! jq -e ".auth.config | index(\"$username\")" "$CONFIG_FILE" > /dev/null; then
                jq --arg user "$username" '.auth.config += [$user]' "$CONFIG_FILE" > "${CONFIG_FILE}.tmp" && mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"
                echo -e " ${GREEN}[ADD]${NC} Sync User: $username"
            fi
            
            # Update/Create entry di user-db.json
            jq --arg u "$username" --arg e "$exp_iso" \
               '.[$u] = {exp: $e, quota: "Unlimited", ip: "Unlimited"}' "$USER_DB" > "${USER_DB}.tmp" && mv "${USER_DB}.tmp" "$USER_DB"
        fi
    done < /etc/passwd
    
    restart_service
    echo -e ""
    echo -e " ${GREEN}✅ Sync Selesai!${NC}"
    sleep 2
}

# ==================================================
# MAIN MENU
# ==================================================
while true; do
    clear
    # Cek Status Service
    if systemctl is-active --quiet zivpn; then
        status_srv="${GREEN}RUNNING${NC}"
    else
        status_srv="${RED}STOPPED${NC}"
    fi
    
    PORT=$(grep -o '"listen": *"[^"]*"' $CONFIG_FILE | cut -d'"' -f4 | sed 's/://g' | sed 's/0.0.0.0//g')
    [ -z "$PORT" ] && PORT="Unknown"

    echo -e ""
    print_gradient "╭══════════════════════════════════════════════╮"
    print_gradient "│     ZIVPN PREMIUM MANAGER (PRO VERSION)      │"
    print_gradient "╰══════════════════════════════════════════════╯"
    echo -e " ${z}╭══════════════════════════════════════════════╮${NC}"
    echo -e " ${z}│${NC} ${y}Service Status${NC} : $status_srv"
    echo -e " ${z}│${NC} ${y}UDP Port${NC}       : $PORT"
    echo -e " ${z}╰══════════════════════════════════════════════╯${NC}"
    echo -e " ${z}╭══════════════════════════════════════════════╮${NC}"
    echo -e " ${z}│${NC} [${GREEN}01${NC}] Create User ZiVPN"
    echo -e " ${z}│${NC} [${GREEN}02${NC}] Monitor User ${y}(Auto-Delete Expired)${NC}"
    echo -e " ${z}│${NC} [${GREEN}03${NC}] Delete User Manual"
    echo -e " ${z}│${NC} [${GREEN}04${NC}] Sync SSH ${PURPLE}(Fix Ghost & 2099)${NC}"
    echo -e " ${z}│${NC} [${GREEN}05${NC}] Fix UDP Custom (Exclude Port)"
    echo -e " ${z}│${NC} [${GREEN}06${NC}] Backup / Restore Data"
    echo -e " ${z}│${NC} [${GREEN}07${NC}] Restart Service"
    echo -e " ${z}│${NC} [${RED}00${NC}] Back to Main Menu"
    echo -e " ${z}╰══════════════════════════════════════════════╯${NC}"
    print_gradient "════════════════════════════════════════════════"
    read -p " Select Menu : " opt

    case $opt in
        1|01) add_user ;;
        2|02) list_users ;;
        3|03) 
            clear
            print_gradient "╭══════════════════════════════════════════════╮"
            print_gradient "│             DELETE ZIVPN ACCOUNT             │"
            print_gradient "╰══════════════════════════════════════════════╯"
            read -p " Username to delete: " target
            remove_user_data "$target"
            restart_service
            echo -e " ${GREEN}User $target deleted.${NC}"
            sleep 1
            ;;
        4|04) sync_ssh ;;
        5|05)
            # Fix UDP Exclude
            PORT=$(grep -o '"listen": *"[^"]*"' $CONFIG_FILE | cut -d'"' -f4 | sed 's/://g' | sed 's/0.0.0.0//g')
            sed -i "s|server -exclude .*|server -exclude 22,53,68,$PORT|g" /etc/systemd/system/udp-custom.service 2>/dev/null
            systemctl daemon-reload && systemctl restart udp-custom
            echo -e " ${GREEN}UDP Custom Fixed (Excluded Port $PORT).${NC}"
            sleep 2
            ;;
        6|06)
            echo -e " ${y}[1] Backup Data  [2] Restore Data${NC}"
            read -p " Select: " br
            if [[ $br == "1" ]]; then
                mkdir -p "$BACKUP_DIR"
                zip -r "$BACKUP_DIR/zivpn_$(date +%F).zip" "$CONFIG_FILE" "$USER_DB" >/dev/null
                echo -e " ${GREEN}Backup Saved in $BACKUP_DIR${NC}"
            elif [[ $br == "2" ]]; then
                latest=$(ls -t "$BACKUP_DIR"/*.zip | head -1)
                [ -n "$latest" ] && unzip -o "$latest" -d / && restart_service && echo -e " ${GREEN}Restore Success.${NC}"
            fi
            sleep 2
            ;;
        7|07) 
            restart_service
            echo -e " ${GREEN}Service Restarted.${NC}" 
            sleep 1
            ;;
        0|00) break ;;
        *) echo -e " ${RED}Invalid Option${NC}"; sleep 1 ;;
    esac
done