#!/bin/bash
# play-loop.sh — 오라클 서버에서 Claude Code가 게임을 플레이하는 루프
# 사용법: ./play-loop.sh [cycles]

set -e

ARCADE_DIR="/home/ubuntu/sites/arcade"
CONTROLLER="$ARCADE_DIR/pipeline/game-controller.js"
CYCLES=${1:-20}
BUG_LOG="/tmp/game-bugs.md"
SCREENSHOT_DIR="/tmp/game-play"

mkdir -p "$SCREENSHOT_DIR"
echo "# Abyssal Descent — 버그 및 UX 이슈 기록" > "$BUG_LOG"
echo "" >> "$BUG_LOG"
echo "테스트 시작: $(date)" >> "$BUG_LOG"
echo "" >> "$BUG_LOG"

# ── 1단계: 게임 코드 학습 ──
echo "=== PHASE 1: 게임 학습 ==="

GAME_INFO=$(cat <<'LEARN_EOF'
Read these game source files and learn how to play:

Controls (from index.html bottom bar):
- Click: Attack
- Space: Dash
- Q: Potion
- E: Switch weapon
- R: Forge
- T: Slots
- F: Finisher (and equip items)
- WASD: Move

Game states: title, playing, paused, dead, victory, soulforge
Screen size: 500x810
Character: blue figure, usually center
Enemies: red/orange figures
Items drop after kills: press F to equip, X to discard

Goal: Kill all enemies on each floor, find exit stairs, descend deeper.
LEARN_EOF
)

# ── 2단계: 게임 시작 ──
echo "=== PHASE 2: 게임 시작 ==="

cat > /tmp/actions_start.json << 'EOF'
{
  "actions": [
    { "type": "navigate", "url": "https://patchme.lol/games/abyssal-descent/" },
    { "type": "wait", "ms": 5000 },
    { "type": "screenshot", "name": "01_menu" },
    { "type": "click", "x": 250, "y": 441 },
    { "type": "wait", "ms": 3000 },
    { "type": "screenshot", "name": "02_after_click" },
    { "type": "key", "code": "Digit1", "kc": 49 },
    { "type": "wait", "ms": 3000 },
    { "type": "screenshot", "name": "03_game_start" }
  ]
}
EOF

cd "$ARCADE_DIR"
NODE_PATH=./node_modules node "$CONTROLLER" /tmp/actions_start.json
echo "게임 시작됨"

# ── 3단계: 플레이 루프 ──
echo "=== PHASE 3: 플레이 루프 ($CYCLES 사이클) ==="

for ((i=1; i<=CYCLES; i++)); do
  echo ""
  echo "--- Cycle $i/$CYCLES ---"

  # 스크린샷 찍기
  NODE_PATH=./node_modules node -e "
    const CDP=require('chrome-remote-interface');
    const fs=require('fs');
    (async()=>{
      const c=await CDP({port:9222});
      await c.Page.enable();
      const s=await c.Page.captureScreenshot({format:'png'});
      fs.writeFileSync('/tmp/game-play/cycle_${i}_before.png',Buffer.from(s.data,'base64'));
      await c.close();
    })().catch(e=>{console.error(e);process.exit(1)});
  "

  # Claude에게 스크린샷 분석 + 다음 액션 결정 요청
  DECISION=$(claude -p "You are playing the game Abyssal Descent. A roguelike dungeon crawler.

$GAME_INFO

This is cycle $i of $CYCLES.
Screenshot is at: /tmp/game-play/cycle_${i}_before.png (read it to see the game state)

TASKS:
1. Read the screenshot file to see current game state
2. Decide what actions to take for the next 2-3 seconds
3. Check for any bugs or UX issues (cursor missing, UI overlap, confusing elements, etc)

Respond with ONLY valid JSON (no markdown, no explanation):
{
  \"observation\": \"what you see on screen\",
  \"plan\": \"what you will do and why\",
  \"bugs\": [\"list any bugs or UX issues noticed, empty array if none\"],
  \"actions\": [
    {\"type\": \"moveAttack\", \"dir\": \"d\", \"attackX\": 350, \"attackY\": 400, \"ms\": 2000},
    {\"type\": \"key\", \"code\": \"KeyF\", \"kc\": 70}
  ]
}

Action types:
- moveAttack: hold WASD + click attack. dir=w/a/s/d, attackX/attackY=where to click, ms=duration
- click: click at x,y
- key: press key (code + kc). Common: F=70, X=88, Space=32, Escape=27, Digit1=49
- holdKey: hold key for ms. code + kc + ms
- wait: wait ms milliseconds
- screenshot: take screenshot with name

Key codes: W=87, A=65, S=83, D=68, Space=32, F=70, X=88, E=69, Escape=27, 1=49, 2=50

CRITICAL COORDINATE RULES:
- Screen is EXACTLY 500 wide x 810 tall pixels
- ALL x coordinates MUST be between 0-500
- ALL y coordinates MUST be between 0-810
- NEVER use coordinates outside this range
- Your character is always near the CENTER of the screen (~250, ~400)
- Enemies appear as red/orange figures RELATIVE TO THE SCREEN, not the game world
- To attack an enemy you SEE on the right side of screen: attackX=350-450, attackY=wherever you see it
- To attack an enemy on the left: attackX=50-150
- To attack an enemy above: attackY=150-300
- To attack an enemy below: attackY=500-700

STRATEGY:
- Look at the screenshot. Find red/orange enemy figures.
- Move TOWARD enemies using WASD direction
- Set attackX/attackY to WHERE THE ENEMY IS ON SCREEN (not world coords)
- If you see an item popup (green border box), press F to equip or X to discard
- If you see a perk/level-up screen (3 cards), press 1, 2, or 3 to pick
- If you see Floor Cleared text, move around to find stairs (bright square)
- If enemies are to your RIGHT on screen, move dir=d and attackX=400, attackY=(enemy screen Y)
- If enemies are BELOW you on screen, move dir=s and attackX=250, attackY=600" --allowedTools "Read" 2>/dev/null)

  echo "[CLAUDE] $DECISION" | head -5

  # JSON 추출
  ACTIONS_JSON=$(echo "$DECISION" | grep -o '{[^}]*"actions"[^]]*\].*}' | head -1)

  if [ -z "$ACTIONS_JSON" ]; then
    echo "[FALLBACK] Claude 응답 파싱 실패, 기본 액션 사용"
    ACTIONS_JSON='{"actions":[{"type":"moveAttack","dir":"d","attackX":350,"attackY":400,"ms":2000},{"type":"screenshot","name":"cycle_'$i'_after"}]}'
  fi

  # 버그 기록
  BUGS=$(echo "$DECISION" | grep -o '"bugs":\s*\[[^]]*\]' | head -1)
  if [ -n "$BUGS" ] && ! echo "$BUGS" | grep -q '\[\]'; then
    echo "### Cycle $i" >> "$BUG_LOG"
    echo "$BUGS" >> "$BUG_LOG"
    echo "" >> "$BUG_LOG"
    echo "[BUG] 이슈 발견됨, $BUG_LOG에 기록"
  fi

  # 액션 파일 저장 및 실행
  echo "$ACTIONS_JSON" > "/tmp/actions_cycle_${i}.json"

  # screenshot 액션 추가 (없으면)
  if ! echo "$ACTIONS_JSON" | grep -q '"screenshot"'; then
    # 수동으로 after screenshot 추가
    ACTIONS_JSON=$(echo "$ACTIONS_JSON" | sed 's/\]$/,{"type":"screenshot","name":"cycle_'$i'_after"}]/')
    echo "$ACTIONS_JSON" > "/tmp/actions_cycle_${i}.json"
  fi

  NODE_PATH=./node_modules node "$CONTROLLER" "/tmp/actions_cycle_${i}.json" 2>&1 | tail -5

  echo "[DONE] Cycle $i"
done

echo ""
echo "=== 플레이 완료 ==="
echo "버그 로그: $BUG_LOG"
cat "$BUG_LOG"
