#!/bin/bash
set -euo pipefail

# ============================================================================
# Suggest Work - Priority Backlog Recommendations
# ============================================================================
# Suggests highest priority unblocked issues from the backlog.
# Reads project configuration from config.yaml (no runtime lookups).
# Auto-detects current repo to prioritize relevant issues.
#
# Data Sources:
#   - Configuration: config.yaml for project IDs and blocked labels
#   - Query Target: Linear MCP for backlog issues
#   - Context: Current working directory for repo detection
#   - Cache: lib/cache_manager.py for TTL-based caching
# ============================================================================

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_FILE="$SCRIPT_DIR/config.yaml"
LIB_DIR="$SCRIPT_DIR/lib"
CACHE_DIR="$SCRIPT_DIR/.cache"

# Cache settings
CACHE_TTL=300  # 5 minutes (matches config.yaml cache.ttl.issues)
CACHE_SCHEMA_VERSION=1

# ============================================================================
# Repo Detection
# ============================================================================

# Detect current repo from working directory
# Looks for common OmniNode repo patterns
detect_current_repo() {
    local cwd="${PWD}"
    local repo_name=""

    # Check if we're in a git repo and get its name
    if git rev-parse --is-inside-work-tree &>/dev/null 2>&1; then
        repo_name=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "")
    fi

    # If no git repo, try to extract from path
    if [[ -z "$repo_name" ]]; then
        # Look for common repo patterns in path
        if [[ "$cwd" == *"/omnibase_core"* ]]; then
            repo_name="omnibase_core"
        elif [[ "$cwd" == *"/omnibase_spi"* ]]; then
            repo_name="omnibase_spi"
        elif [[ "$cwd" == *"/omnibase_infra"* ]]; then
            repo_name="omnibase_infra"
        elif [[ "$cwd" == *"/omniclaude"* ]]; then
            repo_name="omniclaude"
        fi
    fi

    echo "$repo_name"
}

usage() {
    cat << EOF
Usage: $(basename "$0") [OPTIONS]

Suggest highest priority unblocked issues from the project backlog.
Auto-detects current repo to prioritize relevant issues first.

Options:
  --count N          Number of suggestions (default: 5)
  --project PROJECT  Project name (MVP, Beta, Production, etc.)
  --repo REPO        Override auto-detected repo context (e.g., omnibase_core)
  --no-repo          Disable repo-based prioritization
  --label LABEL      Filter to issues with this label
  --json             Output as JSON instead of markdown
  --execute          Output ONLY the execution prompt (pipeable, no formatting)
  --no-cache         Bypass cache (force fresh query generation)
  -h, --help         Show this help

Projects Available:
  MVP              - MVP - OmniNode Platform Foundation
  Beta             - Beta - OmniNode Platform Hardening
  Production       - Production - OmniNode Platform Scale
  NodeReducer      - NodeReducer v1.0 - Contract-Driven FSM
  EventBusAlignment - Event Bus Alignment - OmniNode Platform
  PipelineOptimization - Synchronous Pipeline Optimization

Repo Context:
  The script auto-detects your current repository and prioritizes issues
  with matching labels. For example, if you're in omnibase_core, issues
  labeled 'omnibase_core' appear first, then remaining issues by priority.

Examples:
  # Get 5 suggestions, auto-detect repo context
  $(basename "$0")

  # Override repo context
  $(basename "$0") --repo omnibase_spi

  # Disable repo prioritization (pure priority sort)
  $(basename "$0") --no-repo

  # Get 10 suggestions for Beta project
  $(basename "$0") --project Beta --count 10

  # Output as JSON
  $(basename "$0") --json

  # Get execution prompt only (pipeable)
  $(basename "$0") --execute
  $(basename "$0") --execute | pbcopy

Priority Sorting:
  1. Issues matching current repo label (if detected)
  2. By priority: Urgent > High > Normal > Low
  3. By age: oldest first within same priority

Blocked Labels (excluded from suggestions):
  - blocked, waiting, on-hold, needs-clarification, dependent
EOF
    exit 0
}

# ============================================================================
# Configuration Parsing
# ============================================================================

# Parse YAML value (simple single-line values only)
# Usage: parse_yaml_value "key" < config.yaml
parse_yaml_value() {
    local key="$1"
    grep -E "^[[:space:]]*$key:" "$CONFIG_FILE" 2>/dev/null | head -1 | sed 's/.*:[[:space:]]*//' | sed 's/^"//' | sed 's/"$//' | sed "s/^'//" | sed "s/'$//"
}

# Parse project ID from config
# Usage: get_project_id "MVP"
get_project_id() {
    local project="$1"
    # Look for the project section and extract its id
    awk -v proj="$project" '
        /^[[:space:]]+'"$project"':/ { in_project=1; next }
        in_project && /^[[:space:]]+id:/ {
            gsub(/.*id:[[:space:]]*/, "")
            gsub(/^"/, "")
            gsub(/"$/, "")
            print
            exit
        }
        in_project && /^[[:space:]][[:space:]][A-Za-z]+:/ && !/^[[:space:]]+id:/ && !/^[[:space:]]+name:/ && !/^[[:space:]]+shortcuts:/ && !/^[[:space:]]+status:/ && !/^[[:space:]]+lead:/ { exit }
    ' "$CONFIG_FILE"
}

# Parse project name from config
# Usage: get_project_name "MVP"
get_project_name() {
    local project="$1"
    awk -v proj="$project" '
        /^[[:space:]]+'"$project"':/ { in_project=1; next }
        in_project && /^[[:space:]]+name:/ {
            gsub(/.*name:[[:space:]]*/, "")
            gsub(/^"/, "")
            gsub(/"$/, "")
            print
            exit
        }
        in_project && /^[[:space:]][[:space:]][A-Za-z]+:/ && !/^[[:space:]]+id:/ && !/^[[:space:]]+name:/ && !/^[[:space:]]+shortcuts:/ && !/^[[:space:]]+status:/ && !/^[[:space:]]+lead:/ { exit }
    ' "$CONFIG_FILE"
}

# Parse blocked labels from config
# Returns newline-separated list
get_blocked_labels() {
    awk '
        /^[[:space:]]+blocked_labels:/ { in_blocked=1; next }
        in_blocked && /^[[:space:]]+-/ {
            gsub(/^[[:space:]]+-[[:space:]]*/, "")
            gsub(/^"/, "")
            gsub(/"$/, "")
            print
        }
        in_blocked && /^[[:space:]][[:space:]][a-z_]+:/ && !/^[[:space:]]+-/ { exit }
    ' "$CONFIG_FILE"
}

# Get default project from config
get_default_project() {
    awk '
        /^defaults:/ { in_defaults=1; next }
        in_defaults && /^[[:space:]]+project:/ {
            gsub(/.*project:[[:space:]]*/, "")
            gsub(/[[:space:]]*#.*$/, "")  # Remove YAML comments
            gsub(/^"/, "")
            gsub(/"$/, "")
            print
            exit
        }
        in_defaults && /^[a-z]+:/ { exit }
    ' "$CONFIG_FILE"
}

# Get default count from config
get_default_count() {
    awk '
        /^backlog:/ { in_backlog=1; next }
        in_backlog && /^[[:space:]]+default_count:/ {
            gsub(/.*default_count:[[:space:]]*/, "")
            print
            exit
        }
        in_backlog && /^[a-z]+:/ { exit }
    ' "$CONFIG_FILE"
}

# ============================================================================
# Default Values
# ============================================================================

# Check config file exists
if [[ ! -f "$CONFIG_FILE" ]]; then
    echo "Error: Configuration file not found: $CONFIG_FILE"
    echo "Run 'configure' skill first to generate configuration."
    exit 1
fi

DEFAULT_PROJECT=$(get_default_project)
DEFAULT_COUNT=$(get_default_count)
DEFAULT_COUNT=${DEFAULT_COUNT:-5}

COUNT="$DEFAULT_COUNT"
PROJECT=""
LABEL=""
REPO_CONTEXT=""
NO_REPO=false
JSON_OUTPUT=false
EXECUTE_ONLY=false
NO_CACHE=false
CACHE_HIT=false

# ============================================================================
# Parse Arguments
# ============================================================================

while [[ $# -gt 0 ]]; do
    case $1 in
        --count)
            COUNT="$2"
            shift 2
            ;;
        --project)
            PROJECT="$2"
            shift 2
            ;;
        --repo)
            REPO_CONTEXT="$2"
            shift 2
            ;;
        --no-repo)
            NO_REPO=true
            shift
            ;;
        --label)
            LABEL="$2"
            shift 2
            ;;
        --json)
            JSON_OUTPUT=true
            shift
            ;;
        --execute)
            EXECUTE_ONLY=true
            shift
            ;;
        --no-cache)
            NO_CACHE=true
            shift
            ;;
        -h|--help)
            usage
            ;;
        *)
            echo "Error: Unknown argument: $1"
            usage
            ;;
    esac
done

# Auto-detect repo if not disabled and not explicitly set
if [[ "$NO_REPO" == "false" && -z "$REPO_CONTEXT" ]]; then
    REPO_CONTEXT=$(detect_current_repo)
fi

# Use default project if not specified
if [[ -z "$PROJECT" ]]; then
    PROJECT="$DEFAULT_PROJECT"
fi

# Validate project exists in config
PROJECT_ID=$(get_project_id "$PROJECT")
if [[ -z "$PROJECT_ID" ]]; then
    echo "Error: Project '$PROJECT' not found in configuration."
    echo ""
    echo "Available projects:"
    grep -E "^  [A-Z][a-zA-Z]+:" "$CONFIG_FILE" | sed 's/://' | sed 's/^  /  - /'
    exit 1
fi

PROJECT_NAME=$(get_project_name "$PROJECT")
PROJECT_NAME=${PROJECT_NAME:-$PROJECT}

# Get blocked labels
BLOCKED_LABELS=$(get_blocked_labels)

# Calculate query limit (get extra to filter blocked)
QUERY_LIMIT=$((COUNT * 3))

# ============================================================================
# Cache Integration (using lib/cache_manager.py)
# ============================================================================

# Build cache key for this query
build_cache_key() {
    local project_id="$1"
    local label_filter="$2"
    local repo_ctx="$3"
    local count="$4"

    # Create deterministic cache key
    # Format: v{schema}:suggest-work:{project_id}:{filters}:{count}
    local filters="label=${label_filter:-none},repo=${repo_ctx:-none}"
    echo "v${CACHE_SCHEMA_VERSION}:suggest-work:${project_id}:${filters}:${count}"
}

# Check cache using Python cache_manager
check_cache() {
    local cache_key="$1"

    python3 << PYTHON_EOF
import sys
sys.path.insert(0, "$LIB_DIR")
from cache_manager import CacheManager

try:
    cache = CacheManager("$CACHE_DIR", schema_version=$CACHE_SCHEMA_VERSION, default_ttl=$CACHE_TTL)
    result = cache.get("$cache_key")
    if result is not None:
        import json
        print(json.dumps(result))
        sys.exit(0)
    else:
        sys.exit(1)
except Exception as e:
    sys.exit(1)
PYTHON_EOF
}

# Set cache using Python cache_manager
set_cache() {
    local cache_key="$1"
    local value="$2"

    python3 << PYTHON_EOF
import sys
sys.path.insert(0, "$LIB_DIR")
from cache_manager import CacheManager
import json

try:
    cache = CacheManager("$CACHE_DIR", schema_version=$CACHE_SCHEMA_VERSION, default_ttl=$CACHE_TTL)
    value = json.loads('''$value''')
    cache.set("$cache_key", value, ttl=$CACHE_TTL)
except Exception as e:
    # Cache write failure is non-fatal
    pass
PYTHON_EOF
}

# Generate cache key for this query
CACHE_KEY=$(build_cache_key "$PROJECT_ID" "$LABEL" "$REPO_CONTEXT" "$COUNT")

# Check cache unless --no-cache specified
CACHED_RESULT=""
if [[ "$NO_CACHE" == "false" ]]; then
    if CACHED_RESULT=$(check_cache "$CACHE_KEY"); then
        CACHE_HIT=true
    fi
fi

# ============================================================================
# Execution Prompt Generation
# ============================================================================

# Generate the execution prompt for Claude
# This is used by --execute flag and included in markdown/JSON output
generate_execution_prompt() {
    local blocked_list
    blocked_list=$(echo "$BLOCKED_LABELS" | tr '\n' ',' | sed 's/,$//' | sed 's/,/, /g')

    local label_param=""
    if [[ -n "$LABEL" ]]; then
        label_param=", label=\"$LABEL\""
    fi

    local repo_sort=""
    local repo_column=""
    if [[ -n "$REPO_CONTEXT" ]]; then
        repo_sort="Sort by: 1) Issues with '$REPO_CONTEXT' label first, 2) Priority (Urgent > High > Normal > Low), 3) Created date (oldest first)"
        repo_column=", Repo Match"
    else
        repo_sort="Sort by: 1) Priority (Urgent > High > Normal > Low), 2) Created date (oldest first)"
        repo_column=""
    fi

    cat << PROMPT_EOF
Query Linear for the top $COUNT unblocked backlog issues in project $PROJECT (ID: $PROJECT_ID).

Use: mcp__linear-server__list_issues(project="$PROJECT_ID", state="Backlog", limit=$QUERY_LIMIT$label_param)

Then filter out issues with labels: $blocked_list

$repo_sort

Return the top $COUNT results in a table with columns: #, ID, Title, Priority$repo_column, Created
PROMPT_EOF
}

# ============================================================================
# Output Generation
# ============================================================================

# Helper function: output markdown only when not in JSON mode
md_echo() {
    if [[ "$JSON_OUTPUT" != "true" ]]; then
        echo "$@"
    fi
}

# Store execution prompt for reuse
EXECUTION_PROMPT=$(generate_execution_prompt)

# ============================================================================
# Execute-Only Mode
# ============================================================================

if [[ "$EXECUTE_ONLY" == "true" ]]; then
    # Output ONLY the execution prompt - no formatting, pipeable
    echo "$EXECUTION_PROMPT"
    exit 0
fi

# ============================================================================
# JSON / Markdown Output
# ============================================================================

if [[ "$JSON_OUTPUT" == "true" ]]; then
    # JSON output
    # Escape the execution prompt for JSON embedding
    ESCAPED_PROMPT=$(echo "$EXECUTION_PROMPT" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))')

    # Convert bash boolean to Python boolean string
    CACHE_HIT_PYTHON="True"
    if [[ "$CACHE_HIT" == "false" ]]; then
        CACHE_HIT_PYTHON="False"
    fi

    python3 << PYTHON_EOF
import json
from datetime import datetime, timezone

result = {
    "generated_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
    "cache_hit": $CACHE_HIT_PYTHON,
    "cache": {
        "key": "$CACHE_KEY",
        "ttl_seconds": $CACHE_TTL,
        "schema_version": $CACHE_SCHEMA_VERSION
    },
    "execution_prompt": $ESCAPED_PROMPT,
    "project": {
        "shortcut": "$PROJECT",
        "name": "$PROJECT_NAME",
        "id": "$PROJECT_ID"
    },
    "repo_context": "$REPO_CONTEXT" if "$REPO_CONTEXT" else None,
    "query": {
        "state": "Backlog",
        "limit": $QUERY_LIMIT,
        "label_filter": "$LABEL" if "$LABEL" else None
    },
    "filters": {
        "blocked_labels": [
$(echo "$BLOCKED_LABELS" | while read -r label; do
    if [[ -n "$label" ]]; then
        echo "            \"$label\","
    fi
done)
        ],
        "return_count": $COUNT
    },
    "sorting": {
        "primary": "repo_label_match" if "$REPO_CONTEXT" else "priority",
        "secondary": "priority",
        "tertiary": "created_at",
        "repo_label": "$REPO_CONTEXT" if "$REPO_CONTEXT" else None,
        "priority_order": "1=Urgent > 2=High > 3=Normal > 4=Low",
        "description": "Issues with '$REPO_CONTEXT' label first, then by priority" if "$REPO_CONTEXT" else "By priority, then by age"
    },
    "mcp_query": {
        "tool": "mcp__linear-server__list_issues",
        "parameters": {
            "project": "$PROJECT_ID",
            "state": "Backlog",
            "limit": $QUERY_LIMIT
$(if [[ -n "$LABEL" ]]; then echo "            ,\"label\": \"$LABEL\""; fi)
        }
    }
}

# Clean up None values and trailing commas
print(json.dumps(result, indent=2, default=str))
PYTHON_EOF

    # Cache the result for future use (only if not a cache hit)
    if [[ "$CACHE_HIT" == "false" && "$NO_CACHE" == "false" ]]; then
        # Build the cacheable payload
        CACHE_PAYLOAD=$(python3 << CACHE_EOF
import json
from datetime import datetime, timezone

payload = {
    "generated_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
    "project_id": "$PROJECT_ID",
    "project_name": "$PROJECT_NAME",
    "repo_context": "$REPO_CONTEXT" if "$REPO_CONTEXT" else None,
    "label_filter": "$LABEL" if "$LABEL" else None,
    "count": $COUNT,
    "query_limit": $QUERY_LIMIT
}
print(json.dumps(payload))
CACHE_EOF
)
        set_cache "$CACHE_KEY" "$CACHE_PAYLOAD"
    fi
else
    # Markdown output
    md_echo ""
    md_echo "# Suggested Work: $PROJECT"
    md_echo ""
    md_echo "**Generated**: $(date '+%Y-%m-%d %H:%M:%S')"
    md_echo "**Project**: $PROJECT_NAME"
    md_echo "**Project ID**: \`$PROJECT_ID\`"
    if [[ -n "$REPO_CONTEXT" ]]; then
        md_echo "**Repo Context**: \`$REPO_CONTEXT\` (issues with this label shown first)"
    fi
    if [[ -n "$LABEL" ]]; then
        md_echo "**Label Filter**: $LABEL"
    fi
    if [[ "$CACHE_HIT" == "true" ]]; then
        md_echo "**Cache**: Hit (TTL: ${CACHE_TTL}s)"
    elif [[ "$NO_CACHE" == "true" ]]; then
        md_echo "**Cache**: Bypassed (--no-cache)"
    else
        md_echo "**Cache**: Miss (will cache for ${CACHE_TTL}s)"
    fi
    md_echo ""
    md_echo "---"
    md_echo ""
    md_echo "## Execute Now"
    md_echo ""
    md_echo "To get suggestions, ask Claude:"
    md_echo ""
    md_echo '```'
    md_echo "$EXECUTION_PROMPT"
    md_echo '```'
    md_echo ""
    md_echo "Or use \`--execute\` flag to get just the prompt: \`./suggest-work --execute | pbcopy\`"
    md_echo ""
    md_echo "---"
    md_echo ""
    md_echo "## Query for Linear MCP"
    md_echo ""
    md_echo "To get unblocked backlog issues, execute:"
    md_echo ""
    md_echo '```python'
    md_echo "mcp__linear-server__list_issues("
    md_echo "    project=\"$PROJECT_ID\","
    md_echo "    state=\"Backlog\","
    if [[ -n "$LABEL" ]]; then
        md_echo "    limit=$QUERY_LIMIT,"
        md_echo "    label=\"$LABEL\""
    else
        md_echo "    limit=$QUERY_LIMIT"
    fi
    md_echo ")"
    md_echo '```'
    md_echo ""
    md_echo "---"
    md_echo ""
    md_echo "## Filtering Instructions"
    md_echo ""
    md_echo "After receiving results, apply these filters:"
    md_echo ""
    md_echo "### 1. Exclude Blocked Issues"
    md_echo ""
    md_echo "Remove issues with any of these labels:"
    md_echo ""
    echo "$BLOCKED_LABELS" | while read -r label; do
        if [[ -n "$label" ]]; then
            md_echo "- \`$label\`"
        fi
    done
    md_echo ""
    if [[ -n "$REPO_CONTEXT" ]]; then
        md_echo "### 2. Group by Repo Label"
        md_echo ""
        md_echo "Separate issues into two groups:"
        md_echo ""
        md_echo "1. **Repo-relevant**: Issues with label \`$REPO_CONTEXT\`"
        md_echo "2. **Other**: Remaining issues"
        md_echo ""
        md_echo "### 3. Sort Each Group by Priority"
        md_echo ""
    else
        md_echo "### 2. Sort by Priority"
        md_echo ""
    fi
    md_echo "| Priority | Value | Rank |"
    md_echo "|----------|-------|------|"
    md_echo "| Urgent   | 1     | Highest |"
    md_echo "| High     | 2     | ... |"
    md_echo "| Normal   | 3     | ... |"
    md_echo "| Low      | 4     | Lowest |"
    md_echo ""
    if [[ -n "$REPO_CONTEXT" ]]; then
        md_echo "### 4. Secondary Sort"
    else
        md_echo "### 3. Secondary Sort"
    fi
    md_echo ""
    md_echo "Within same priority, sort by \`created_at\` (oldest first)."
    md_echo ""
    if [[ -n "$REPO_CONTEXT" ]]; then
        md_echo "### 5. Merge and Return Top $COUNT"
        md_echo ""
        md_echo "Return repo-relevant issues first (sorted), then other issues (sorted)."
        md_echo "Total returned: **$COUNT** issues."
    else
        md_echo "### 4. Return Top $COUNT"
        md_echo ""
        md_echo "After filtering and sorting, return the top **$COUNT** issues."
    fi
    md_echo ""
    md_echo "---"
    md_echo ""
    md_echo "## Expected Output Format"
    md_echo ""
    if [[ -n "$REPO_CONTEXT" ]]; then
        md_echo "| # | ID | Title | Priority | Repo Match | Created |"
        md_echo "|---|-------|-------|----------|------------|---------|"
        md_echo "| 1 | OMNI-XX | Issue in $REPO_CONTEXT... | Urgent | Yes | 2025-12-01 |"
        md_echo "| 2 | OMNI-YY | Another $REPO_CONTEXT issue... | High | Yes | 2025-12-03 |"
        md_echo "| 3 | OMNI-ZZ | Other project issue... | Urgent | No | 2025-12-02 |"
    else
        md_echo "| # | ID | Title | Priority | Created |"
        md_echo "|---|-------|-------|----------|---------|"
        md_echo "| 1 | OMNI-XX | Issue title... | Urgent | 2025-12-01 |"
        md_echo "| 2 | OMNI-YY | Another issue... | High | 2025-12-03 |"
    fi
    md_echo "| ... | ... | ... | ... | ... |"
    md_echo ""
    md_echo "---"
    md_echo ""
    md_echo "*Script generated by linear-insights suggest-work skill*"

    # Cache the result for future use (only if not a cache hit)
    if [[ "$CACHE_HIT" == "false" && "$NO_CACHE" == "false" ]]; then
        # Build the cacheable payload
        CACHE_PAYLOAD=$(python3 << CACHE_EOF
import json
from datetime import datetime, timezone

payload = {
    "generated_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
    "project_id": "$PROJECT_ID",
    "project_name": "$PROJECT_NAME",
    "repo_context": "$REPO_CONTEXT" if "$REPO_CONTEXT" else None,
    "label_filter": "$LABEL" if "$LABEL" else None,
    "count": $COUNT,
    "query_limit": $QUERY_LIMIT
}
print(json.dumps(payload))
CACHE_EOF
)
        set_cache "$CACHE_KEY" "$CACHE_PAYLOAD"
    fi
fi
