#!/usr/bin/env bash
# gstack-analytics — personal usage dashboard from local JSONL
#
# Usage:
#   gstack-analytics          # default: last 7 days
#   gstack-analytics 7d       # last 7 days
#   gstack-analytics 30d      # last 30 days
#   gstack-analytics all      # all time
#
# Env overrides (for testing):
#   GSTACK_STATE_DIR  — override ~/.gstack state directory
set -uo pipefail

STATE_DIR="${GSTACK_STATE_DIR:-$HOME/.gstack}"
JSONL_FILE="$STATE_DIR/analytics/skill-usage.jsonl"

# ─── Parse time window ───────────────────────────────────────
WINDOW="${1:-7d}"
case "$WINDOW" in
  7d)  DAYS=7;  LABEL="last 7 days" ;;
  30d) DAYS=30; LABEL="last 30 days" ;;
  all) DAYS=0;  LABEL="all time" ;;
  *)   DAYS=7;  LABEL="last 7 days" ;;
esac

# ─── Check for data ──────────────────────────────────────────
if [ ! -f "$JSONL_FILE" ]; then
  echo "gstack usage — no data yet"
  echo ""
  echo "Usage data will appear here after you use gstack skills"
  echo "with telemetry enabled (gstack-config set telemetry anonymous)."
  exit 0
fi

TOTAL_LINES="$(wc -l < "$JSONL_FILE" | tr -d ' ')"
if [ "$TOTAL_LINES" = "0" ]; then
  echo "gstack usage — no data yet"
  exit 0
fi

# ─── Filter by time window ───────────────────────────────────
if [ "$DAYS" -gt 0 ] 2>/dev/null; then
  # Calculate cutoff date
  if date -v-1d +%Y-%m-%d >/dev/null 2>&1; then
    # macOS date
    CUTOFF="$(date -v-${DAYS}d -u +%Y-%m-%dT%H:%M:%SZ)"
  else
    # GNU date
    CUTOFF="$(date -u -d "$DAYS days ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || echo "2000-01-01T00:00:00Z")"
  fi
  # Filter: skill_run events (new format) OR basic skill events (old format, no event_type)
  # Old format: {"skill":"X","ts":"Y","repo":"Z"} (no event_type field)
  # New format: {"event_type":"skill_run","skill":"X","ts":"Y",...}
  FILTERED="$(awk -F'"' -v cutoff="$CUTOFF" '
    /"ts":"/ {
      # Skip hook_fire events
      if (/"event":"hook_fire"/) next
      # Skip non-skill_run new-format events
      if (/"event_type":"/ && !/"event_type":"skill_run"/) next
      for (i=1; i<=NF; i++) {
        if ($i == "ts" && $(i+1) ~ /^:/) {
          ts = $(i+2)
          if (ts >= cutoff) { print; break }
        }
      }
    }
  ' "$JSONL_FILE")"
else
  # All time: include skill_run events + old-format basic events, exclude hook_fire
  FILTERED="$(awk '/"ts":"/ && !/"event":"hook_fire"/' "$JSONL_FILE" | grep -v '"event_type":"upgrade_' 2>/dev/null || true)"
fi

if [ -z "$FILTERED" ]; then
  echo "gstack usage ($LABEL) — no skill runs found"
  exit 0
fi

# ─── Aggregate by skill ──────────────────────────────────────
# Extract skill names and count
SKILL_COUNTS="$(echo "$FILTERED" | awk -F'"' '
  /"skill":"/ {
    for (i=1; i<=NF; i++) {
      if ($i == "skill" && $(i+1) ~ /^:/) {
        skill = $(i+2)
        counts[skill]++
        break
      }
    }
  }
  END {
    for (s in counts) print counts[s], s
  }
' | sort -rn)"

# Count outcomes
TOTAL="$(echo "$FILTERED" | wc -l | tr -d ' ')"
SUCCESS="$(echo "$FILTERED" | grep -c '"outcome":"success"' || true)"
SUCCESS="${SUCCESS:-0}"; SUCCESS="$(echo "$SUCCESS" | tr -d ' \n\r\t')"
ERRORS="$(echo "$FILTERED" | grep -c '"outcome":"error"' || true)"
ERRORS="${ERRORS:-0}"; ERRORS="$(echo "$ERRORS" | tr -d ' \n\r\t')"
# Old format events have no outcome field — count them as successful
NO_OUTCOME="$(echo "$FILTERED" | grep -vc '"outcome":' || true)"
NO_OUTCOME="${NO_OUTCOME:-0}"; NO_OUTCOME="$(echo "$NO_OUTCOME" | tr -d ' \n\r\t')"
SUCCESS=$(( SUCCESS + NO_OUTCOME ))

# Calculate success rate
if [ "$TOTAL" -gt 0 ] 2>/dev/null; then
  SUCCESS_RATE=$(( SUCCESS * 100 / TOTAL ))
else
  SUCCESS_RATE=100
fi

# ─── Calculate total duration ────────────────────────────────
TOTAL_DURATION="$(echo "$FILTERED" | awk -F'[:,]' '
  /"duration_s"/ {
    for (i=1; i<=NF; i++) {
      if ($i ~ /"duration_s"/) {
        val = $(i+1)
        gsub(/[^0-9.]/, "", val)
        if (val+0 > 0) total += val
      }
    }
  }
  END { printf "%.0f", total }
')"

# Format duration
TOTAL_DURATION="${TOTAL_DURATION:-0}"
if [ "$TOTAL_DURATION" -ge 3600 ] 2>/dev/null; then
  HOURS=$(( TOTAL_DURATION / 3600 ))
  MINS=$(( (TOTAL_DURATION % 3600) / 60 ))
  DUR_DISPLAY="${HOURS}h ${MINS}m"
elif [ "$TOTAL_DURATION" -ge 60 ] 2>/dev/null; then
  MINS=$(( TOTAL_DURATION / 60 ))
  DUR_DISPLAY="${MINS}m"
else
  DUR_DISPLAY="${TOTAL_DURATION}s"
fi

# ─── Render output ───────────────────────────────────────────
echo "gstack usage ($LABEL)"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

# Find max count for bar scaling
MAX_COUNT="$(echo "$SKILL_COUNTS" | head -1 | awk '{print $1}')"
BAR_WIDTH=20

echo "$SKILL_COUNTS" | while read -r COUNT SKILL; do
  # Scale bar
  if [ "$MAX_COUNT" -gt 0 ] 2>/dev/null; then
    BAR_LEN=$(( COUNT * BAR_WIDTH / MAX_COUNT ))
  else
    BAR_LEN=1
  fi
  [ "$BAR_LEN" -lt 1 ] && BAR_LEN=1

  # Build bar
  BAR=""
  i=0
  while [ "$i" -lt "$BAR_LEN" ]; do
    BAR="${BAR}█"
    i=$(( i + 1 ))
  done

  # Calculate avg duration for this skill
  AVG_DUR="$(echo "$FILTERED" | awk -v skill="$SKILL" '
    index($0, "\"skill\":\"" skill "\"") > 0 {
      # Extract duration_s value using split on "duration_s":
      n = split($0, parts, "\"duration_s\":")
      if (n >= 2) {
        # parts[2] starts with the value, e.g. "142,"
        gsub(/[^0-9.].*/, "", parts[2])
        if (parts[2]+0 > 0) { total += parts[2]; count++ }
      }
    }
    END { if (count > 0) printf "%.0f", total/count; else print "0" }
  ')"

  # Format avg duration
  if [ "$AVG_DUR" -ge 60 ] 2>/dev/null; then
    AVG_DISPLAY="$(( AVG_DUR / 60 ))m"
  else
    AVG_DISPLAY="${AVG_DUR}s"
  fi

  printf "  /%-20s %s  %d runs  (avg %s)\n" "$SKILL" "$BAR" "$COUNT" "$AVG_DISPLAY"
done

echo ""
echo "Success rate: ${SUCCESS_RATE}% | Errors: ${ERRORS} | Total time: ${DUR_DISPLAY}"
echo "Events: ${TOTAL} skill runs"
