#!/usr/bin/env bash
set -euo pipefail

# Mosaic Brain CLI - Interface to Mosaic Stack Ideas/Brain API
# Usage: brain.sh <command> [options]

# Load configuration
CONFIG_FILE="${HOME}/.config/mosaic/brain.conf"
if [[ -f "$CONFIG_FILE" ]]; then
    # shellcheck source=/dev/null
    source "$CONFIG_FILE"
fi

# Configuration with defaults
API_URL="${MOSAIC_API_URL:-http://localhost:3001}"
WORKSPACE_ID="${MOSAIC_WORKSPACE_ID:-}"
API_TOKEN="${MOSAIC_API_TOKEN:-}"

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

# Helper functions
error() {
    echo -e "${RED}Error: $1${NC}" >&2
    exit 1
}

success() {
    echo -e "${GREEN}$1${NC}"
}

warn() {
    echo -e "${YELLOW}$1${NC}"
}

check_config() {
    [[ -z "$WORKSPACE_ID" ]] && error "MOSAIC_WORKSPACE_ID not set"
    [[ -z "$API_TOKEN" ]] && error "MOSAIC_API_TOKEN not set"
}

# API call helper
api_call() {
    local method="$1"
    local endpoint="$2"
    local data="${3:-}"
    
    local url="${API_URL}${endpoint}"
    local args=(
        -X "$method"
        -H "Authorization: Bearer ${API_TOKEN}"
        -H "Content-Type: application/json"
        -H "x-workspace-id: ${WORKSPACE_ID}"
        -s
        -w "\n%{http_code}"
    )
    
    if [[ -n "$data" ]]; then
        args+=(-d "$data")
    fi
    
    local response
    response=$(curl "${args[@]}" "$url")
    
    # Extract HTTP status code from last line
    local http_code
    http_code=$(echo "$response" | tail -n1)
    local body
    body=$(echo "$response" | sed '$d')
    
    # Check for errors
    if [[ "$http_code" -ge 400 ]]; then
        local error_msg
        error_msg=$(echo "$body" | jq -r '.message // .error // "API request failed"' 2>/dev/null || echo "API request failed")
        error "HTTP $http_code: $error_msg"
    fi
    
    echo "$body"
}

# Commands

cmd_capture() {
    local content=""
    local title=""
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            --title)
                title="$2"
                shift 2
                ;;
            *)
                content="$1"
                shift
                ;;
        esac
    done
    
    [[ -z "$content" ]] && error "Content required for capture"
    
    local payload
    payload=$(jq -n \
        --arg content "$content" \
        --arg title "$title" \
        '{content: $content} + (if $title != "" then {title: $title} else {} end)')
    
    response=$(api_call POST "/api/ideas/capture" "$payload")
    echo "$response" | jq -r '.id // empty' > /dev/null || error "Failed to capture idea"
    
    local idea_id
    idea_id=$(echo "$response" | jq -r '.id')
    success "✓ Idea captured: $idea_id"
    echo "$response" | jq '.'
}

cmd_create() {
    local content=""
    local title=""
    local tags=""
    local category=""
    local status=""
    local priority=""
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            --content)
                content="$2"
                shift 2
                ;;
            --title)
                title="$2"
                shift 2
                ;;
            --tags)
                tags="$2"
                shift 2
                ;;
            --category)
                category="$2"
                shift 2
                ;;
            --status)
                status="$2"
                shift 2
                ;;
            --priority)
                priority="$2"
                shift 2
                ;;
            *)
                content="$1"
                shift
                ;;
        esac
    done
    
    [[ -z "$content" ]] && error "Content required"
    
    # Build JSON payload using jq for safety
    local payload
    payload=$(jq -n \
        --arg content "$content" \
        --arg title "$title" \
        --arg category "$category" \
        --arg status "$status" \
        --arg priority "$priority" \
        --arg tags "$tags" \
        '{content: $content} + 
         (if $title != "" then {title: $title} else {} end) +
         (if $category != "" then {category: $category} else {} end) +
         (if $status != "" then {status: $status} else {} end) +
         (if $priority != "" then {priority: $priority} else {} end) +
         (if $tags != "" then {tags: ($tags | split(",") | map(gsub("^\\s+|\\s+$";"")))} else {} end)'
    )
    
    response=$(api_call POST "/api/ideas" "$payload")
    echo "$response" | jq -r '.id // empty' > /dev/null || error "Failed to create idea"
    
    local idea_id
    idea_id=$(echo "$response" | jq -r '.id')
    success "✓ Idea created: $idea_id"
    echo "$response" | jq '.'
}

cmd_list() {
    local limit="20"
    local tags=""
    local status=""
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            --limit)
                limit="$2"
                shift 2
                ;;
            --tags)
                tags="$2"
                shift 2
                ;;
            --status)
                status="$2"
                shift 2
                ;;
            *)
                shift
                ;;
        esac
    done
    
    local query="?limit=$limit"
    [[ -n "$tags" ]] && query+="&tags=$tags"
    [[ -n "$status" ]] && query+="&status=$status"
    
    response=$(api_call GET "/api/ideas${query}")
    echo "$response" | jq '.'
}

cmd_get() {
    local idea_id="$1"
    [[ -z "$idea_id" ]] && error "Idea ID required"
    
    response=$(api_call GET "/api/ideas/${idea_id}")
    echo "$response" | jq '.'
}

cmd_update() {
    local idea_id=""
    local title=""
    local content=""
    local tags=""
    local add_tags=""
    local remove_tags=""
    local status=""
    local category=""
    
    idea_id="$1"
    shift
    [[ -z "$idea_id" ]] && error "Idea ID required"
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            --title)
                title="$2"
                shift 2
                ;;
            --content)
                content="$2"
                shift 2
                ;;
            --tags)
                tags="$2"
                shift 2
                ;;
            --add-tags)
                add_tags="$2"
                shift 2
                ;;
            --remove-tags)
                remove_tags="$2"
                shift 2
                ;;
            --status)
                status="$2"
                shift 2
                ;;
            --category)
                category="$2"
                shift 2
                ;;
            *)
                shift
                ;;
        esac
    done
    
    # Build update payload using jq for safety
    local payload
    payload=$(jq -n \
        --arg title "$title" \
        --arg content "$content" \
        --arg status "$status" \
        --arg category "$category" \
        --arg tags "$tags" \
        '(if $title != "" then {title: $title} else {} end) +
         (if $content != "" then {content: $content} else {} end) +
         (if $status != "" then {status: $status} else {} end) +
         (if $category != "" then {category: $category} else {} end) +
         (if $tags != "" then {tags: ($tags | split(",") | map(gsub("^\\s+|\\s+$";"")))} else {} end)'
    )
    
    response=$(api_call PATCH "/api/ideas/${idea_id}" "$payload")
    echo "$response" | jq -r '.id // empty' > /dev/null || error "Failed to update idea"
    
    success "✓ Idea updated: $idea_id"
    echo "$response" | jq '.'
}

cmd_delete() {
    local idea_id="$1"
    [[ -z "$idea_id" ]] && error "Idea ID required"
    
    response=$(api_call DELETE "/api/ideas/${idea_id}")
    success "✓ Idea deleted: $idea_id"
}

cmd_query() {
    local query="$*"
    [[ -z "$query" ]] && error "Query text required"
    
    local payload
    payload=$(jq -n --arg query "$query" '{query: $query}')
    
    response=$(api_call POST "/api/brain/query" "$payload")
    echo "$response" | jq '.'
}

cmd_search() {
    local search_term=""
    local limit="20"
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            --limit)
                limit="$2"
                shift 2
                ;;
            *)
                search_term="$1"
                shift
                ;;
        esac
    done
    
    [[ -z "$search_term" ]] && error "Search term required"
    
    local query="?q=$(echo "$search_term" | jq -sRr @uri)&limit=$limit"
    response=$(api_call GET "/api/brain/search${query}")
    echo "$response" | jq '.'
}

cmd_tags() {
    # Get all ideas and extract unique tags
    response=$(api_call GET "/api/ideas?limit=1000")
    echo "$response" | jq -r '.data[]?.tags[]? // empty' | sort -u
}

# Main
main() {
    [[ $# -eq 0 ]] && error "Command required. Use: capture, create, list, get, update, delete, query, search, tags"
    
    check_config
    
    local command="$1"
    shift
    
    case "$command" in
        capture)
            cmd_capture "$@"
            ;;
        create)
            cmd_create "$@"
            ;;
        list)
            cmd_list "$@"
            ;;
        get)
            cmd_get "$@"
            ;;
        update)
            cmd_update "$@"
            ;;
        delete)
            cmd_delete "$@"
            ;;
        query)
            cmd_query "$@"
            ;;
        search)
            cmd_search "$@"
            ;;
        tags)
            cmd_tags "$@"
            ;;
        *)
            error "Unknown command: $command"
            ;;
    esac
}

main "$@"
