#!/usr/bin/env bash
#
# gantt-api.sh - Helper script for Mosaic Stack Gantt/Project API queries
#

set -euo pipefail

# Configuration from environment
API_URL="${MOSAIC_API_URL:-http://localhost:3000}"
WORKSPACE_ID="${MOSAIC_WORKSPACE_ID:-}"
API_TOKEN="${MOSAIC_API_TOKEN:-}"

# Check required environment variables
if [[ -z "$WORKSPACE_ID" ]]; then
    echo "Error: MOSAIC_WORKSPACE_ID environment variable not set" >&2
    exit 1
fi

if [[ -z "$API_TOKEN" ]]; then
    echo "Error: MOSAIC_API_TOKEN environment variable not set" >&2
    exit 1
fi

# Helper function to make API requests
api_request() {
    local method="$1"
    local endpoint="$2"
    local data="${3:-}"

    local url="${API_URL}${endpoint}"
    local curl_args=(
        -X "$method"
        -H "Content-Type: application/json"
        -H "X-Workspace-Id: $WORKSPACE_ID"
        -H "Authorization: Bearer $API_TOKEN"
        -s
    )

    if [[ -n "$data" ]]; then
        curl_args+=(-d "$data")
    fi

    curl "${curl_args[@]}" "$url"
}

# List all projects
list_projects() {
    local page="${1:-1}"
    local limit="${2:-50}"
    api_request GET "/projects?page=$page&limit=$limit" | jq .
}

# Get a single project with tasks
get_project() {
    local project_id="$1"
    api_request GET "/projects/$project_id" | jq .
}

# Get tasks with optional filters
get_tasks() {
    local project_id="${1:-}"
    local filters=""
    
    if [[ -n "$project_id" ]]; then
        filters="projectId=$project_id"
    fi
    
    api_request GET "/tasks?$filters" | jq .
}

# Get a single task
get_task() {
    local task_id="$1"
    api_request GET "/tasks/$task_id" | jq .
}

# Get dependency chain for a task
get_dependencies() {
    local task_id="$1"
    
    # Get the task
    local task_json
    task_json=$(get_task "$task_id")
    
    # Extract dependency IDs from metadata
    local dep_ids
    dep_ids=$(echo "$task_json" | jq -r '.metadata.dependencies // [] | .[]')
    
    if [[ -z "$dep_ids" ]]; then
        echo "Task has no dependencies"
        return
    fi
    
    echo "Dependencies for task: $(echo "$task_json" | jq -r '.title')"
    echo ""
    
    # Fetch each dependency
    while IFS= read -r dep_id; do
        if [[ -n "$dep_id" ]]; then
            local dep_task
            dep_task=$(get_task "$dep_id")
            echo "- $(echo "$dep_task" | jq -r '.title') [$(echo "$dep_task" | jq -r '.status')]"
            echo "  Due: $(echo "$dep_task" | jq -r '.dueDate // "No due date"')"
        fi
    done <<< "$dep_ids"
}

# Calculate critical path for a project
critical_path() {
    local project_id="$1"
    
    # Get all tasks for the project
    local tasks_json
    tasks_json=$(get_tasks "$project_id")
    
    # Use jq to build dependency graph and find longest path
    echo "$tasks_json" | jq -r '
        .data as $tasks |
        
        # Build adjacency list
        ($tasks | map({
            id: .id,
            title: .title,
            status: .status,
            dueDate: .dueDate,
            dependencies: (.metadata.dependencies // [])
        })) as $nodes |
        
        # Find tasks with no dependencies (starting points)
        ($nodes | map(select(.dependencies | length == 0))) as $starts |
        
        # Display structure
        "Critical Path Analysis\n" +
        "======================\n\n" +
        "Starting tasks (no dependencies):\n" +
        ($starts | map("- \(.title) [\(.status)]") | join("\n")) +
        "\n\nAll tasks with dependencies:\n" +
        ($nodes | map(
            select(.dependencies | length > 0) |
            "- \(.title) [\(.status)]\n  Depends on: \(.dependencies | join(", "))"
        ) | join("\n"))
    '
}

# Main command dispatcher
main() {
    if [[ $# -lt 1 ]]; then
        echo "Usage: $0 <command> [args...]" >&2
        echo "" >&2
        echo "Commands:" >&2
        echo "  projects              - List all projects" >&2
        echo "  project <id>          - Get project details" >&2
        echo "  tasks [project-id]    - Get tasks (optionally filtered by project)" >&2
        echo "  task <id>             - Get task details" >&2
        echo "  dependencies <id>     - Get dependency chain for task" >&2
        echo "  critical-path <id>    - Calculate critical path for project" >&2
        exit 1
    fi
    
    local command="$1"
    shift
    
    case "$command" in
        projects)
            list_projects "$@"
            ;;
        project)
            if [[ $# -lt 1 ]]; then
                echo "Error: project command requires project ID" >&2
                exit 1
            fi
            get_project "$1"
            ;;
        tasks)
            get_tasks "$@"
            ;;
        task)
            if [[ $# -lt 1 ]]; then
                echo "Error: task command requires task ID" >&2
                exit 1
            fi
            get_task "$1"
            ;;
        dependencies)
            if [[ $# -lt 1 ]]; then
                echo "Error: dependencies command requires task ID" >&2
                exit 1
            fi
            get_dependencies "$1"
            ;;
        critical-path)
            if [[ $# -lt 1 ]]; then
                echo "Error: critical-path command requires project ID" >&2
                exit 1
            fi
            critical_path "$1"
            ;;
        *)
            echo "Error: unknown command '$command'" >&2
            exit 1
            ;;
    esac
}

main "$@"
