use std
use ../lib_provisioning *
use ../lib_provisioning/platform *
use ../lib_provisioning/utils/service-check.nu *

# Comprehensive workflow management commands

# Get orchestrator endpoint from platform configuration or use provided default
def get-orchestrator-url [--orchestrator: string = ""] {
    if ($orchestrator | is-not-empty) {
        return $orchestrator
    }

    # Try to get from environment variable first
    if ($env.PROVISIONING_ORCHESTRATOR_URL? | is-not-empty) {
        return $env.PROVISIONING_ORCHESTRATOR_URL
    }

    # Skip slow platform discovery - just use localhost default
    # (Platform discovery via nickel export is too slow for CLI responsiveness)
    # Users can set PROVISIONING_ORCHESTRATOR_URL to override
    "http://localhost:9011"
}

# Detect if orchestrator URL is local (for plugin usage)
def use-local-plugin [orchestrator_url: string] {
    # Check if it's a local endpoint
    (detect-platform-mode $orchestrator_url) == "local"
}

# List all active workflows - interactive loop
export def "workflow list" [
    limit?: int  # Number of recent tasks to show (default: 10)
    --orchestrator: string = ""  # Orchestrator URL (optional, uses platform config if not provided)
    --status: string  # Filter by status: Pending, Running, Completed, Failed, Cancelled
] {
    let orch_url = (get-orchestrator-url --orchestrator=$orchestrator)
    let task_limit = ($limit | default 10)

    let avail = (verify-service-or-fail $orch_url "Orchestrator"
        --check-command "provisioning platform status"
        --check-alias "prvng plat st"
        --start-command "provisioning platform start orchestrator"
        --start-alias "prvng plat start orchestrator"
    )
    if $avail.status == "error" { return }

    mut continue_browsing = true

    while $continue_browsing {
        # Always use HTTP API - plugin doesn't return tasks reliably
        let response = (http get $"($orch_url)/tasks")

        if not ($response | get success) {
            _print $"Error: (($response | get error))"
            break
        }

        let tasks = ($response | get data)

        let filtered_tasks = if ($status | is-not-empty) {
            $tasks | where status == $status
        } else {
            $tasks
        }

        # Limit to specified number of recent tasks
        let limited_tasks = (
            if ($filtered_tasks | length) > $task_limit {
                $filtered_tasks | reverse | first $task_limit | reverse
            } else {
                $filtered_tasks
            }
        )

        # Format tasks as numbered table for clean display
        mut formatted = []
        mut row_num = 1
        for task in $limited_tasks {
            let status_display = if $task.status == "Failed" {
                ((ansi red) + $task.status + (ansi reset))
            } else {
                $task.status
            }
            $formatted = ($formatted | append {
                "#": $row_num,
                "Task ID": $task.id,
                "Status": $status_display,
                "Completed At": ($task.completed_at | default "N/A")
            })
            $row_num = ($row_num + 1)
        }

        # Display as native Nushell table without index column
        print ($formatted | table --index false)

        _print ""
        _print "0 = Exit, or enter task number:"
        _print ""

        # Get task number from user
        let task_num_str = (typedialog text "Task number:" --default "0")

        # Simple validation - just try to convert
        let task_num = ($task_num_str | str trim | into int)

        if $task_num == 0 {
            $continue_browsing = false
        } else if $task_num < 1 or $task_num > ($limited_tasks | length) {
            _print $"❌ Invalid task number. Choose 1-($limited_tasks | length), or 0 to exit"
            _print ""
        } else {
            let task_index = ($task_num - 1)
            let selected_task = ($limited_tasks | get $task_index)
            let task_id = $selected_task.id

            _print ""
            _print $"📊 Status for: ($task_id)"
            _print "════════════════════════════════════════════════"
            workflow status $task_id --orchestrator $orch_url
            _print ""
            _print ""
            _print "─────────────────────────────────────────────────"
            let continue_choice = (typedialog select "¿Qué deseas hacer?" ["Continuar" "Salir"])

            if $continue_choice == "Salir" {
                $continue_browsing = false
            }
        }
    }
}

# Get detailed workflow status
export def "workflow status" [
    task_id: string     # Task ID to check
    --orchestrator: string = ""  # Orchestrator URL (optional, uses platform config if not provided)
] {
    let orch_url = (get-orchestrator-url --orchestrator=$orchestrator)

    let avail = (verify-service-or-fail $orch_url "Orchestrator"
        --check-command "provisioning platform status"
        --check-alias "prvng plat st"
        --start-command "provisioning platform start orchestrator"
        --start-alias "prvng plat start orchestrator"
    )
    if $avail.status == "error" { return { error: "Orchestrator not available" } }

    # Always use HTTP API - plugin doesn't return tasks reliably
    let response = (http get $"($orch_url)/tasks/($task_id)")

    if not ($response | get success) {
        return { error: ($response | get error) }
    }

    let task = ($response | get data)

    # Convert arrays to strings for display, then transpose to vertical format
    let displayable = {
        id: $task.id,
        name: $task.name,
        command: $task.command,
        args: ($task.args | str join "\n                    "),
        dependencies: ($task.dependencies | str join "\n                    "),
        status: $task.status,
        created_at: $task.created_at,
        started_at: ($task.started_at | default "N/A"),
        completed_at: ($task.completed_at | default "N/A"),
        output: ($task.output | default ""),
        error: ($task.error | default "")
    }

    # Convert to vertical key-value table with proper headers
    print ($displayable | transpose | each {|row| {Field: $row.column0, Value: $row.column1}} | table -i false)
}

# Monitor workflow progress in real-time
export def "workflow monitor" [
    task_id: string     # Task ID to monitor
    --orchestrator: string = ""  # Orchestrator URL (optional, uses platform config if not provided)
] {
    let orch_url = (get-orchestrator-url --orchestrator=$orchestrator)

    _print $"Monitoring workflow: ($task_id)"
    _print "Press Ctrl+C to stop monitoring"
    _print ""

    while true {
        let task = (workflow status $task_id --orchestrator $orch_url)

        let err_result = (do { $task | get error } | complete)
        let task_error = if $err_result.exit_code == 0 { $err_result.stdout } else { null }
        if ($task_error | is-not-empty) {
            _print $"❌ Error getting task status: ($task_error)"
            break
        }

        let status = ($task | get status)
        let created = ($task | get created_at)
        let start_result = (do { $task | get started_at } | complete)
        let started = if $start_result.exit_code == 0 { $start_result.stdout } else { "Not started" }
        let comp_result = (do { $task | get completed_at } | complete)
        let completed = if $comp_result.exit_code == 0 { $comp_result.stdout } else { "Not completed" }

        clear
        _print $"📊 Workflow Status: ($task_id)"
        _print $"═══════════════════════════════════════════════════════════════"
        _print $"Name: (($task | get name))"
        _print $"Status: ($status)"
        _print $"Created: ($created)"
        _print $"Started: ($started)"
        _print $"Completed: ($completed)"
        _print ""

        match $status {
            "Completed" => {
                _print "✅ Workflow completed successfully!"
                let out_result = (do { $task | get output } | complete)
                let task_output = if $out_result.exit_code == 0 { $out_result.stdout } else { null }
                if ($task_output | is-not-empty) {
                    _print ""
                    _print "Output:"
                    _print "───────"
                    _print $task_output
                }
                break
            },
            "Failed" => {
                _print "❌ Workflow failed!"
                let err_result = (do { $task | get error } | complete)
                let task_error = if $err_result.exit_code == 0 { $err_result.stdout } else { null }
                if ($task_error | is-not-empty) {
                    _print ""
                    _print "Error:"
                    _print "──────"
                    _print $task_error
                }
                break
            },
            "Running" => {
                _print "🔄 Workflow is running..."
            },
            "Cancelled" => {
                _print "🚫 Workflow was cancelled"
                break
            },
            _ => {
                _print $"⏳ Status: ($status)"
            }
        }

        _print ""
        _print "Refreshing in 3 seconds... (Ctrl+C to stop)"
        sleep 3sec
    }
}

# Show workflow statistics
export def "workflow stats" [
    --orchestrator: string = ""  # Orchestrator URL (optional, uses platform config if not provided)
] {
    let orch_url = (get-orchestrator-url --orchestrator=$orchestrator)

    let avail = (verify-service-or-fail $orch_url "Orchestrator"
        --check-command "provisioning platform status"
        --check-alias "prvng plat st"
        --start-command "provisioning platform start orchestrator"
        --start-alias "prvng plat start orchestrator"
    )
    if $avail.status == "error" { return }

    let response = (http get $"($orch_url)/tasks")
    if not ($response | get success) {
        _print $"Error: (($response | get error))"
        return
    }
    let tasks = ($response | get data)

    let total = ($tasks | length)
    let completed = ($tasks | where status == "Completed" | length)
    let failed = ($tasks | where status == "Failed" | length)
    let running = ($tasks | where status == "Running" | length)
    let pending = ($tasks | where status == "Pending" | length)
    let cancelled = ($tasks | where status == "Cancelled" | length)

    {
        total: $total,
        completed: $completed,
        failed: $failed,
        running: $running,
        pending: $pending,
        cancelled: $cancelled,
        success_rate: (if $total > 0 { ($completed / $total * 100) | math round | into int } else { 0 })
    }
}

# Clean up old completed workflows
export def "workflow cleanup" [
    --orchestrator: string = ""  # Orchestrator URL (optional, uses platform config if not provided)
    --days: int = 7  # Remove workflows older than this many days
    --dry-run      # Show what would be removed without actually removing
] {
    let orch_url = (get-orchestrator-url --orchestrator=$orchestrator)

    _print $"Cleaning up workflows older than ($days) days..."

    let cutoff_date = ((date now) - ($days * 86400 | into duration --unit sec))
    let tasks = (workflow list --orchestrator $orch_url)

    let old_tasks = ($tasks | where {|task|
        let task_date = ($task.completed_at | into datetime)
        $task_date < $cutoff_date and ($task.status in ["Completed", "Failed", "Cancelled"])
    })

    if ($old_tasks | length) == 0 {
        _print "No old workflows found for cleanup."
        return
    }

    _print $"Found ($old_tasks | length) workflows for cleanup:"
    $old_tasks | select id name status completed_at | table

    if $dry_run {
        _print ""
        _print "Dry run mode - no workflows were actually removed."
        _print "Run without --dry-run to perform the cleanup."
    } else {
        _print ""
        _print "Note: Actual cleanup would require orchestrator API support for deletion."
        _print "This is a placeholder for future implementation."
    }
}

# Orchestrator health and info
export def "workflow orchestrator" [
    --orchestrator: string = "http://localhost:9011"  # Orchestrator URL
] {
    let avail = (verify-service-or-fail $orchestrator "Orchestrator"
        --check-command "provisioning platform status"
        --check-alias "prvng plat st"
        --start-command "provisioning platform start orchestrator"
        --start-alias "prvng plat start orchestrator"
    )
    if $avail.status == "error" {
        return {
            status: "unreachable",
            message: "Cannot connect to orchestrator",
            orchestrator_url: $orchestrator
        }
    }

    # Always use HTTP API for consistency
    let health_response = (http get $"($orchestrator)/health")
    let stats = (workflow stats --orchestrator $orchestrator)

    if not ($health_response | get success) {
        return {
            status: "unreachable",
            message: "Cannot connect to orchestrator",
            orchestrator_url: $orchestrator
        }
    }

    {
        status: "healthy",
        message: ($health_response | get data),
        orchestrator_url: $orchestrator,
        workflow_stats: $stats
    }
}

# Interactive workflow browser - alias to list
export def "workflow browse" [
    limit?: int  # Number of recent tasks to show (default: 10)
    --orchestrator: string = ""  # Orchestrator URL (optional)
] {
    if ($limit | is-not-empty) {
        workflow list $limit --orchestrator $orchestrator
    } else {
        workflow list --orchestrator $orchestrator
    }
}

# Submit workflows with dependency management
export def "workflow submit" [
    workflow_type: string   # server, taskserv, cluster
    operation: string       # create, delete, etc.
    target: string          # specific target (server name, taskserv name, etc.)
    infra?: string         # Infrastructure target
    settings?: string      # Settings file path
    --depends-on: list<string> = []  # Task IDs this workflow depends on
    --check (-c)           # Check mode only
    --wait (-w)            # Wait for completion
    --orchestrator: string = "http://localhost:8080"  # Orchestrator URL
] {
    match $workflow_type {
        "server" => {
            _print "Server workflow creation not yet implemented"
        },
        "taskserv" => {
            _print "Taskserv workflow not yet implemented"
        },
        "cluster" => {
            _print "Cluster workflow not yet implemented"
        },
        _ => {
            _print $"Unknown workflow type: ($workflow_type)"
        }
    }
}
