#!/bin/bash
# Ralph - Autonomous Loop for PRD Implementation
# Usage: ./ralph.sh [max_iterations]

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
PRD_FILE="$SCRIPT_DIR/prd.json"
PROGRESS_FILE="$SCRIPT_DIR/progress.txt"
PROMPT_FILE="$SCRIPT_DIR/prompt.md"
LOG_DIR="$SCRIPT_DIR/logs"

MAX_ITERATIONS=${1:-50}
ITERATION=0

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

log() {
    echo -e "${BLUE}[Ralph]${NC} $1"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$PROGRESS_FILE"
}

error() {
    echo -e "${RED}[Ralph ERROR]${NC} $1"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1" >> "$PROGRESS_FILE"
}

success() {
    echo -e "${GREEN}[Ralph]${NC} $1"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] SUCCESS: $1" >> "$PROGRESS_FILE"
}

# Check prerequisites
if [ ! -f "$PRD_FILE" ]; then
    error "prd.json not found at $PRD_FILE"
    exit 1
fi

if ! command -v claude &> /dev/null; then
    error "claude CLI not found. Install with: npm install -g @anthropic-ai/claude-code"
    exit 1
fi

if ! command -v jq &> /dev/null; then
    error "jq not found. Install with: apt install jq"
    exit 1
fi

# Create log directory
mkdir -p "$LOG_DIR"

# Get project info
PROJECT_NAME=$(jq -r '.projectName' "$PRD_FILE")
BRANCH_NAME=$(jq -r '.branchName' "$PRD_FILE")

log "Starting Ralph for project: $PROJECT_NAME"
log "Max iterations: $MAX_ITERATIONS"

# Create branch if not exists
cd "$PROJECT_ROOT"
CURRENT_BRANCH=$(git branch --show-current)
if [ "$CURRENT_BRANCH" != "$BRANCH_NAME" ]; then
    if git show-ref --verify --quiet "refs/heads/$BRANCH_NAME"; then
        log "Switching to existing branch: $BRANCH_NAME"
        git checkout "$BRANCH_NAME"
    else
        log "Creating new branch: $BRANCH_NAME"
        git checkout -b "$BRANCH_NAME"
    fi
fi

# Function to get next pending story
get_next_story() {
    jq -r '.userStories | map(select(.passes == false)) | sort_by(.priority) | .[0] | .id // empty' "$PRD_FILE"
}

# Function to get story details
get_story_details() {
    local story_id=$1
    jq -r --arg id "$story_id" '.userStories[] | select(.id == $id)' "$PRD_FILE"
}

# Function to mark story as passed
mark_story_passed() {
    local story_id=$1
    local notes=$2
    local tmp_file=$(mktemp)
    jq --arg id "$story_id" --arg notes "$notes" \
        '(.userStories[] | select(.id == $id)) |= (.passes = true | .notes = $notes)' \
        "$PRD_FILE" > "$tmp_file" && mv "$tmp_file" "$PRD_FILE"
}

# Function to count stories
count_stories() {
    local total=$(jq '.userStories | length' "$PRD_FILE")
    local passed=$(jq '[.userStories[] | select(.passes == true)] | length' "$PRD_FILE")
    echo "$passed/$total"
}

# Main loop
while [ $ITERATION -lt $MAX_ITERATIONS ]; do
    ITERATION=$((ITERATION + 1))

    log "=== Iteration $ITERATION/$MAX_ITERATIONS ==="

    # Get next story
    NEXT_STORY=$(get_next_story)

    if [ -z "$NEXT_STORY" ]; then
        success "All stories completed! 🎉"
        break
    fi

    log "Working on story: $NEXT_STORY"

    # Get story details for prompt
    STORY_JSON=$(get_story_details "$NEXT_STORY")
    STORY_TITLE=$(echo "$STORY_JSON" | jq -r '.title')

    # Create iteration prompt
    ITERATION_PROMPT="You are implementing user story $NEXT_STORY: $STORY_TITLE

Read the full PRD at scripts/ralph/prd.json for context and CSS rules.

Story details:
$STORY_JSON

IMPORTANT CSS RULES (from PRD):
- NEVER use hardcoded values - always use design tokens
- Check docs/DESIGN_TOKENS.md and docs/CSS_PATTERNS.md before writing CSS
- Test in BOTH light and dark mode
- NEVER use :deep() in components

Your task:
1. Implement this story following all acceptance criteria
2. Run tests/typecheck to verify
3. If ALL criteria pass, respond with: STORY_PASSED
4. If blocked or need clarification, respond with: STORY_BLOCKED: <reason>

Do NOT move to other stories. Focus only on $NEXT_STORY."

    # Run Claude
    LOG_FILE="$LOG_DIR/iteration_${ITERATION}_${NEXT_STORY}.log"
    log "Running Claude... (log: $LOG_FILE)"

    # Run claude with the prompt (--output-format json avoids streaming mode issues)
    CLAUDE_OUTPUT=$(cd "$PROJECT_ROOT" && claude -p "$ITERATION_PROMPT" --output-format json 2>&1 | tee "$LOG_FILE")

    # Check result
    if echo "$CLAUDE_OUTPUT" | grep -q "STORY_PASSED"; then
        success "Story $NEXT_STORY passed!"
        mark_story_passed "$NEXT_STORY" "Completed in iteration $ITERATION"

        # Commit changes
        cd "$PROJECT_ROOT"
        if [ -n "$(git status --porcelain)" ]; then
            git add -A
            git commit -m "feat($PROJECT_NAME): Complete $NEXT_STORY - $STORY_TITLE

Implemented by Ralph autonomous loop.
Iteration: $ITERATION

Co-Authored-By: Claude <noreply@anthropic.com>"
            log "Changes committed"
        fi

    elif echo "$CLAUDE_OUTPUT" | grep -q "STORY_BLOCKED"; then
        BLOCK_REASON=$(echo "$CLAUDE_OUTPUT" | grep "STORY_BLOCKED" | sed 's/STORY_BLOCKED://')
        error "Story $NEXT_STORY blocked: $BLOCK_REASON"
        log "Stopping loop due to blocked story"
        break
    else
        log "Story $NEXT_STORY not yet complete, continuing..."
    fi

    # Progress update
    PROGRESS=$(count_stories)
    log "Progress: $PROGRESS stories completed"

    # Small delay between iterations
    sleep 2
done

# Final summary
echo ""
log "=== Ralph Session Complete ==="
PROGRESS=$(count_stories)
log "Final progress: $PROGRESS stories completed"
log "Branch: $BRANCH_NAME"
log "Logs: $LOG_DIR"

# Show remaining stories
REMAINING=$(jq -r '[.userStories[] | select(.passes == false)] | length' "$PRD_FILE")
if [ "$REMAINING" -gt 0 ]; then
    echo -e "\n${YELLOW}Remaining stories:${NC}"
    jq -r '.userStories[] | select(.passes == false) | "  - \(.id): \(.title)"' "$PRD_FILE"
fi
