package cmd

import (
	"context"
	"encoding/json"
	"fmt"
	"os"
	"strings"

	"gogs.dmsc.dev/arp/arp_cli/client"
	"gogs.dmsc.dev/arp/arp_cli/config"

	"github.com/AlecAivazis/survey/v2"
	"github.com/olekukonko/tablewriter"
	"github.com/urfave/cli/v3"
)

// WorkflowCommand returns the workflow command
func WorkflowCommand() *cli.Command {
	return &cli.Command{
		Name:  "workflow",
		Usage: "Manage workflows",
		Description: `Manage ARP workflows. Workflows are automated processes defined by templates.

Workflow templates define the structure of automated workflows as DAGs (Directed Acyclic Graphs).
Workflow instances are running executions of templates.
Workflow nodes represent individual steps in a running workflow.`,
		Commands: []*cli.Command{
			// WorkflowTemplate commands
			{
				Name:  "template",
				Usage: "Manage workflow templates",
				Commands: []*cli.Command{
					{
						Name:    "list",
						Aliases: []string{"ls"},
						Usage:   "List all workflow templates",
						Flags: []cli.Flag{
							&cli.BoolFlag{
								Name:    "json",
								Aliases: []string{"j"},
								Usage:   "Output as JSON",
							},
						},
						Action: workflowTemplateList,
					},
					{
						Name:  "get",
						Usage: "Get a workflow template by ID",
						Flags: []cli.Flag{
							&cli.StringFlag{
								Name:     "id",
								Aliases:  []string{"i"},
								Usage:    "Template ID",
								Required: true,
							},
							&cli.BoolFlag{
								Name:    "json",
								Aliases: []string{"j"},
								Usage:   "Output as JSON",
							},
						},
						Action: workflowTemplateGet,
					},
					{
						Name:   "create",
						Usage:  "Create a new workflow template",
						Action: workflowTemplateCreate,
						Flags: []cli.Flag{
							&cli.StringFlag{
								Name:    "name",
								Aliases: []string{"n"},
								Usage:   "Template name",
							},
							&cli.StringFlag{
								Name:    "description",
								Aliases: []string{"d"},
								Usage:   "Template description",
							},
							&cli.StringFlag{
								Name:    "definition",
								Aliases: []string{"f"},
								Usage:   "Workflow definition (JSON string or @filename)",
							},
							&cli.BoolFlag{
								Name:  "active",
								Usage: "Set template as active",
								Value: true,
							},
						},
					},
					{
						Name:   "update",
						Usage:  "Update a workflow template",
						Action: workflowTemplateUpdate,
						Flags: []cli.Flag{
							&cli.StringFlag{
								Name:     "id",
								Aliases:  []string{"i"},
								Usage:    "Template ID",
								Required: true,
							},
							&cli.StringFlag{
								Name:    "name",
								Aliases: []string{"n"},
								Usage:   "Template name",
							},
							&cli.StringFlag{
								Name:    "description",
								Aliases: []string{"d"},
								Usage:   "Template description",
							},
							&cli.StringFlag{
								Name:    "definition",
								Aliases: []string{"f"},
								Usage:   "Workflow definition (JSON string or @filename)",
							},
							&cli.BoolFlag{
								Name:  "active",
								Usage: "Set template as active",
							},
						},
					},
					{
						Name:   "delete",
						Usage:  "Delete a workflow template",
						Action: workflowTemplateDelete,
						Flags: []cli.Flag{
							&cli.StringFlag{
								Name:     "id",
								Aliases:  []string{"i"},
								Usage:    "Template ID",
								Required: true,
							},
							&cli.BoolFlag{
								Name:    "yes",
								Aliases: []string{"y"},
								Usage:   "Skip confirmation",
							},
						},
					},
				},
			},
			// WorkflowInstance commands
			{
				Name:  "instance",
				Usage: "Manage workflow instances",
				Commands: []*cli.Command{
					{
						Name:    "list",
						Aliases: []string{"ls"},
						Usage:   "List all workflow instances",
						Flags: []cli.Flag{
							&cli.BoolFlag{
								Name:    "json",
								Aliases: []string{"j"},
								Usage:   "Output as JSON",
							},
						},
						Action: workflowInstanceList,
					},
					{
						Name:  "get",
						Usage: "Get a workflow instance by ID",
						Flags: []cli.Flag{
							&cli.StringFlag{
								Name:     "id",
								Aliases:  []string{"i"},
								Usage:    "Instance ID",
								Required: true,
							},
							&cli.BoolFlag{
								Name:    "json",
								Aliases: []string{"j"},
								Usage:   "Output as JSON",
							},
						},
						Action: workflowInstanceGet,
					},
					{
						Name:   "start",
						Usage:  "Start a new workflow instance from a template",
						Action: workflowInstanceStart,
						Flags: []cli.Flag{
							&cli.StringFlag{
								Name:     "template",
								Aliases:  []string{"t"},
								Usage:    "Template ID",
								Required: true,
							},
							&cli.StringFlag{
								Name:    "service",
								Aliases: []string{"s"},
								Usage:   "Service ID to associate with the workflow",
							},
							&cli.StringFlag{
								Name:    "context",
								Aliases: []string{"c"},
								Usage:   "Initial workflow context (JSON string)",
							},
						},
					},
					{
						Name:   "cancel",
						Usage:  "Cancel a running workflow instance",
						Action: workflowInstanceCancel,
						Flags: []cli.Flag{
							&cli.StringFlag{
								Name:     "id",
								Aliases:  []string{"i"},
								Usage:    "Instance ID",
								Required: true,
							},
						},
					},
				},
			},
			// WorkflowNode commands
			{
				Name:  "node",
				Usage: "Manage workflow nodes",
				Commands: []*cli.Command{
					{
						Name:    "list",
						Aliases: []string{"ls"},
						Usage:   "List all nodes for a workflow instance",
						Flags: []cli.Flag{
							&cli.StringFlag{
								Name:     "instance",
								Aliases:  []string{"i"},
								Usage:    "Instance ID",
								Required: true,
							},
							&cli.BoolFlag{
								Name:    "json",
								Aliases: []string{"j"},
								Usage:   "Output as JSON",
							},
						},
						Action: workflowNodeList,
					},
					{
						Name:  "get",
						Usage: "Get a workflow node by ID",
						Flags: []cli.Flag{
							&cli.StringFlag{
								Name:     "id",
								Aliases:  []string{"i"},
								Usage:    "Node ID",
								Required: true,
							},
							&cli.BoolFlag{
								Name:    "json",
								Aliases: []string{"j"},
								Usage:   "Output as JSON",
							},
						},
						Action: workflowNodeGet,
					},
					{
						Name:   "retry",
						Usage:  "Retry a failed workflow node",
						Action: workflowNodeRetry,
						Flags: []cli.Flag{
							&cli.StringFlag{
								Name:     "id",
								Aliases:  []string{"i"},
								Usage:    "Node ID",
								Required: true,
							},
						},
					},
				},
			},
		},
	}
}

// WorkflowTemplate represents a workflow template
type WorkflowTemplate struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	Description string `json:"description"`
	Definition  string `json:"definition"`
	IsActive    bool   `json:"isActive"`
	CreatedBy   *User  `json:"createdBy"`
	CreatedAt   string `json:"createdAt"`
	UpdatedAt   string `json:"updatedAt"`
}

// WorkflowInstance represents a running workflow instance
type WorkflowInstance struct {
	ID          string            `json:"id"`
	Template    *WorkflowTemplate `json:"template"`
	Status      string            `json:"status"`
	Context     string            `json:"context"`
	Service     *Service          `json:"service"`
	CreatedAt   string            `json:"createdAt"`
	UpdatedAt   string            `json:"updatedAt"`
	CompletedAt *string           `json:"completedAt"`
}

// WorkflowNode represents a node in a workflow instance
type WorkflowNode struct {
	ID          string  `json:"id"`
	NodeKey     string  `json:"nodeKey"`
	NodeType    string  `json:"nodeType"`
	Status      string  `json:"status"`
	Task        *Task   `json:"task"`
	InputData   string  `json:"inputData"`
	OutputData  string  `json:"outputData"`
	RetryCount  int     `json:"retryCount"`
	CreatedAt   string  `json:"createdAt"`
	UpdatedAt   string  `json:"updatedAt"`
	StartedAt   *string `json:"startedAt"`
	CompletedAt *string `json:"completedAt"`
}

// WorkflowTemplate CRUD operations

func workflowTemplateList(ctx context.Context, cmd *cli.Command) error {
	cfg, err := config.Load()
	if err != nil {
		return err
	}
	if err := RequireAuth(cfg); err != nil {
		return err
	}

	c := client.New(cfg.ServerURL)
	c.SetToken(cfg.Token)

	query := `query WorkflowTemplates { workflowTemplates { id name description definition isActive createdBy { id email } createdAt updatedAt } }`

	resp, err := c.Query(query, nil)
	if err != nil {
		return err
	}

	var result struct {
		WorkflowTemplates []WorkflowTemplate `json:"workflowTemplates"`
	}
	if err := json.Unmarshal(resp.Data, &result); err != nil {
		return err
	}

	if cmd.Bool("json") {
		enc := json.NewEncoder(os.Stdout)
		enc.SetIndent("", "  ")
		return enc.Encode(result.WorkflowTemplates)
	}

	if len(result.WorkflowTemplates) == 0 {
		fmt.Println("No workflow templates found.")
		return nil
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.Header([]string{"ID", "Name", "Description", "Active", "Created By", "Created At"})

	for _, t := range result.WorkflowTemplates {
		desc := t.Description
		if len(desc) > 30 {
			desc = desc[:27] + "..."
		}
		createdBy := ""
		if t.CreatedBy != nil {
			createdBy = t.CreatedBy.Email
		}
		active := "yes"
		if !t.IsActive {
			active = "no"
		}
		table.Append([]string{t.ID, t.Name, desc, active, createdBy, t.CreatedAt})
	}

	table.Render()
	return nil
}

func workflowTemplateGet(ctx context.Context, cmd *cli.Command) error {
	cfg, err := config.Load()
	if err != nil {
		return err
	}
	if err := RequireAuth(cfg); err != nil {
		return err
	}

	c := client.New(cfg.ServerURL)
	c.SetToken(cfg.Token)

	id := cmd.String("id")
	query := `query WorkflowTemplate($id: ID!) { workflowTemplate(id: $id) { id name description definition isActive createdBy { id email } createdAt updatedAt } }`

	resp, err := c.Query(query, map[string]interface{}{"id": id})
	if err != nil {
		return err
	}

	var result struct {
		WorkflowTemplate *WorkflowTemplate `json:"workflowTemplate"`
	}
	if err := json.Unmarshal(resp.Data, &result); err != nil {
		return err
	}

	if result.WorkflowTemplate == nil {
		return fmt.Errorf("workflow template not found")
	}

	if cmd.Bool("json") {
		enc := json.NewEncoder(os.Stdout)
		enc.SetIndent("", "  ")
		return enc.Encode(result.WorkflowTemplate)
	}

	t := result.WorkflowTemplate
	fmt.Printf("ID: %s\n", t.ID)
	fmt.Printf("Name: %s\n", t.Name)
	fmt.Printf("Description: %s\n", t.Description)
	fmt.Printf("Active: %v\n", t.IsActive)
	if t.CreatedBy != nil {
		fmt.Printf("Created By: %s\n", t.CreatedBy.Email)
	}
	fmt.Printf("Created At: %s\n", t.CreatedAt)
	fmt.Printf("Updated At: %s\n", t.UpdatedAt)
	fmt.Printf("\nDefinition:\n%s\n", t.Definition)

	return nil
}

func workflowTemplateCreate(ctx context.Context, cmd *cli.Command) error {
	cfg, err := config.Load()
	if err != nil {
		return err
	}
	if err := RequireAuth(cfg); err != nil {
		return err
	}

	name := cmd.String("name")
	description := cmd.String("description")
	definition := cmd.String("definition")
	isActive := cmd.Bool("active")

	if name == "" {
		prompt := &survey.Input{Message: "Template name:"}
		if err := survey.AskOne(prompt, &name, survey.WithValidator(survey.Required)); err != nil {
			return err
		}
	}

	if description == "" {
		prompt := &survey.Input{Message: "Description (optional):"}
		survey.AskOne(prompt, &description)
	}

	if definition == "" {
		prompt := &survey.Multiline{Message: "Workflow definition (JSON):"}
		if err := survey.AskOne(prompt, &definition, survey.WithValidator(survey.Required)); err != nil {
			return err
		}
	}

	// Handle file input for definition
	definition = ReadFileOrString(definition)

	c := client.New(cfg.ServerURL)
	c.SetToken(cfg.Token)

	mutation := `mutation CreateWorkflowTemplate($input: NewWorkflowTemplate!) { createWorkflowTemplate(input: $input) { id name description definition isActive createdBy { id email } createdAt updatedAt } }`

	input := map[string]interface{}{
		"name":        name,
		"description": description,
		"definition":  definition,
		"isActive":    isActive,
	}

	resp, err := c.Mutation(mutation, map[string]interface{}{"input": input})
	if err != nil {
		return err
	}

	var result struct {
		CreateWorkflowTemplate *WorkflowTemplate `json:"createWorkflowTemplate"`
	}
	if err := json.Unmarshal(resp.Data, &result); err != nil {
		return err
	}

	if result.CreateWorkflowTemplate == nil {
		return fmt.Errorf("failed to create workflow template")
	}

	fmt.Printf("Workflow template created successfully!\n")
	fmt.Printf("ID: %s\n", result.CreateWorkflowTemplate.ID)
	fmt.Printf("Name: %s\n", result.CreateWorkflowTemplate.Name)

	return nil
}

func workflowTemplateUpdate(ctx context.Context, cmd *cli.Command) error {
	cfg, err := config.Load()
	if err != nil {
		return err
	}
	if err := RequireAuth(cfg); err != nil {
		return err
	}

	id := cmd.String("id")
	name := cmd.String("name")
	description := cmd.String("description")
	definition := cmd.String("definition")

	// Check if active flag was explicitly set
	var isActive *bool
	if cmd.IsSet("active") {
		val := cmd.Bool("active")
		isActive = &val
	}

	if name == "" && description == "" && definition == "" && isActive == nil {
		fmt.Println("No updates provided. Use flags to specify what to update.")
		return nil
	}

	c := client.New(cfg.ServerURL)
	c.SetToken(cfg.Token)

	input := make(map[string]interface{})
	if name != "" {
		input["name"] = name
	}
	if description != "" {
		input["description"] = description
	}
	if definition != "" {
		input["definition"] = ReadFileOrString(definition)
	}
	if isActive != nil {
		input["isActive"] = *isActive
	}

	mutation := `mutation UpdateWorkflowTemplate($id: ID!, $input: UpdateWorkflowTemplateInput!) { updateWorkflowTemplate(id: $id, input: $input) { id name description definition isActive createdAt updatedAt } }`

	resp, err := c.Mutation(mutation, map[string]interface{}{"id": id, "input": input})
	if err != nil {
		return err
	}

	var result struct {
		UpdateWorkflowTemplate *WorkflowTemplate `json:"updateWorkflowTemplate"`
	}
	if err := json.Unmarshal(resp.Data, &result); err != nil {
		return err
	}

	if result.UpdateWorkflowTemplate == nil {
		return fmt.Errorf("workflow template not found")
	}

	fmt.Printf("Workflow template updated successfully!\n")
	fmt.Printf("ID: %s\n", result.UpdateWorkflowTemplate.ID)
	fmt.Printf("Name: %s\n", result.UpdateWorkflowTemplate.Name)

	return nil
}

func workflowTemplateDelete(ctx context.Context, cmd *cli.Command) error {
	cfg, err := config.Load()
	if err != nil {
		return err
	}
	if err := RequireAuth(cfg); err != nil {
		return err
	}

	id := cmd.String("id")
	skipConfirm := cmd.Bool("yes")

	if !skipConfirm {
		confirm := false
		prompt := &survey.Confirm{
			Message: fmt.Sprintf("Are you sure you want to delete workflow template %s?", id),
			Default: false,
		}
		if err := survey.AskOne(prompt, &confirm); err != nil {
			return err
		}
		if !confirm {
			fmt.Println("Deletion cancelled.")
			return nil
		}
	}

	c := client.New(cfg.ServerURL)
	c.SetToken(cfg.Token)

	mutation := `mutation DeleteWorkflowTemplate($id: ID!) { deleteWorkflowTemplate(id: $id) }`

	resp, err := c.Mutation(mutation, map[string]interface{}{"id": id})
	if err != nil {
		return err
	}

	var result struct {
		DeleteWorkflowTemplate bool `json:"deleteWorkflowTemplate"`
	}
	if err := json.Unmarshal(resp.Data, &result); err != nil {
		return err
	}

	if result.DeleteWorkflowTemplate {
		fmt.Printf("Workflow template %s deleted successfully.\n", id)
	} else {
		fmt.Printf("Failed to delete workflow template %s.\n", id)
	}

	return nil
}

// WorkflowInstance operations

func workflowInstanceList(ctx context.Context, cmd *cli.Command) error {
	cfg, err := config.Load()
	if err != nil {
		return err
	}
	if err := RequireAuth(cfg); err != nil {
		return err
	}

	c := client.New(cfg.ServerURL)
	c.SetToken(cfg.Token)

	query := `query WorkflowInstances { workflowInstances { id template { id name } status context service { id name } createdAt updatedAt completedAt } }`

	resp, err := c.Query(query, nil)
	if err != nil {
		return err
	}

	var result struct {
		WorkflowInstances []WorkflowInstance `json:"workflowInstances"`
	}
	if err := json.Unmarshal(resp.Data, &result); err != nil {
		return err
	}

	if cmd.Bool("json") {
		enc := json.NewEncoder(os.Stdout)
		enc.SetIndent("", "  ")
		return enc.Encode(result.WorkflowInstances)
	}

	if len(result.WorkflowInstances) == 0 {
		fmt.Println("No workflow instances found.")
		return nil
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.Header([]string{"ID", "Template", "Status", "Service", "Created At"})

	for _, i := range result.WorkflowInstances {
		templateName := ""
		if i.Template != nil {
			templateName = i.Template.Name
		}
		serviceName := ""
		if i.Service != nil {
			serviceName = i.Service.Name
		}
		table.Append([]string{i.ID, templateName, i.Status, serviceName, i.CreatedAt})
	}

	table.Render()
	return nil
}

func workflowInstanceGet(ctx context.Context, cmd *cli.Command) error {
	cfg, err := config.Load()
	if err != nil {
		return err
	}
	if err := RequireAuth(cfg); err != nil {
		return err
	}

	c := client.New(cfg.ServerURL)
	c.SetToken(cfg.Token)

	id := cmd.String("id")
	query := `query WorkflowInstance($id: ID!) { workflowInstance(id: $id) { id template { id name description } status context service { id name } createdAt updatedAt completedAt } }`

	resp, err := c.Query(query, map[string]interface{}{"id": id})
	if err != nil {
		return err
	}

	var result struct {
		WorkflowInstance *WorkflowInstance `json:"workflowInstance"`
	}
	if err := json.Unmarshal(resp.Data, &result); err != nil {
		return err
	}

	if result.WorkflowInstance == nil {
		return fmt.Errorf("workflow instance not found")
	}

	if cmd.Bool("json") {
		enc := json.NewEncoder(os.Stdout)
		enc.SetIndent("", "  ")
		return enc.Encode(result.WorkflowInstance)
	}

	i := result.WorkflowInstance
	fmt.Printf("ID: %s\n", i.ID)
	if i.Template != nil {
		fmt.Printf("Template: %s (%s)\n", i.Template.Name, i.Template.ID)
	}
	fmt.Printf("Status: %s\n", i.Status)
	if i.Service != nil {
		fmt.Printf("Service: %s (%s)\n", i.Service.Name, i.Service.ID)
	}
	fmt.Printf("Created At: %s\n", i.CreatedAt)
	fmt.Printf("Updated At: %s\n", i.UpdatedAt)
	if i.CompletedAt != nil {
		fmt.Printf("Completed At: %s\n", *i.CompletedAt)
	}
	if i.Context != "" {
		fmt.Printf("\nContext:\n%s\n", i.Context)
	}

	return nil
}

func workflowInstanceStart(ctx context.Context, cmd *cli.Command) error {
	cfg, err := config.Load()
	if err != nil {
		return err
	}
	if err := RequireAuth(cfg); err != nil {
		return err
	}

	templateID := cmd.String("template")
	serviceID := cmd.String("service")
	contextJSON := cmd.String("context")

	c := client.New(cfg.ServerURL)
	c.SetToken(cfg.Token)

	mutation := `mutation StartWorkflow($templateId: ID!, $input: StartWorkflowInput!) { startWorkflow(templateId: $templateId, input: $input) { id template { id name } status context service { id name } createdAt } }`

	input := make(map[string]interface{})
	if serviceID != "" {
		input["serviceId"] = serviceID
	}
	if contextJSON != "" {
		input["context"] = contextJSON
	}

	resp, err := c.Mutation(mutation, map[string]interface{}{"templateId": templateID, "input": input})
	if err != nil {
		return err
	}

	var result struct {
		StartWorkflow *WorkflowInstance `json:"startWorkflow"`
	}
	if err := json.Unmarshal(resp.Data, &result); err != nil {
		return err
	}

	if result.StartWorkflow == nil {
		return fmt.Errorf("failed to start workflow")
	}

	fmt.Printf("Workflow started successfully!\n")
	fmt.Printf("Instance ID: %s\n", result.StartWorkflow.ID)
	if result.StartWorkflow.Template != nil {
		fmt.Printf("Template: %s\n", result.StartWorkflow.Template.Name)
	}
	fmt.Printf("Status: %s\n", result.StartWorkflow.Status)

	return nil
}

func workflowInstanceCancel(ctx context.Context, cmd *cli.Command) error {
	cfg, err := config.Load()
	if err != nil {
		return err
	}
	if err := RequireAuth(cfg); err != nil {
		return err
	}

	id := cmd.String("id")

	c := client.New(cfg.ServerURL)
	c.SetToken(cfg.Token)

	mutation := `mutation CancelWorkflow($id: ID!) { cancelWorkflow(id: $id) { id status completedAt } }`

	resp, err := c.Mutation(mutation, map[string]interface{}{"id": id})
	if err != nil {
		return err
	}

	var result struct {
		CancelWorkflow *WorkflowInstance `json:"cancelWorkflow"`
	}
	if err := json.Unmarshal(resp.Data, &result); err != nil {
		return err
	}

	if result.CancelWorkflow == nil {
		return fmt.Errorf("workflow instance not found")
	}

	fmt.Printf("Workflow cancelled successfully!\n")
	fmt.Printf("Instance ID: %s\n", result.CancelWorkflow.ID)
	fmt.Printf("Status: %s\n", result.CancelWorkflow.Status)

	return nil
}

// WorkflowNode operations

func workflowNodeList(ctx context.Context, cmd *cli.Command) error {
	cfg, err := config.Load()
	if err != nil {
		return err
	}
	if err := RequireAuth(cfg); err != nil {
		return err
	}

	c := client.New(cfg.ServerURL)
	c.SetToken(cfg.Token)

	instanceID := cmd.String("instance")
	query := `query WorkflowInstance($id: ID!) { workflowInstance(id: $id) { id status nodes: workflowNodes { id nodeKey nodeType status task { id title } retryCount createdAt startedAt completedAt } } }`

	resp, err := c.Query(query, map[string]interface{}{"id": instanceID})
	if err != nil {
		return err
	}

	var result struct {
		WorkflowInstance *struct {
			ID     string         `json:"id"`
			Status string         `json:"status"`
			Nodes  []WorkflowNode `json:"nodes"`
		} `json:"workflowInstance"`
	}
	if err := json.Unmarshal(resp.Data, &result); err != nil {
		return err
	}

	if result.WorkflowInstance == nil {
		return fmt.Errorf("workflow instance not found")
	}

	if cmd.Bool("json") {
		enc := json.NewEncoder(os.Stdout)
		enc.SetIndent("", "  ")
		return enc.Encode(result.WorkflowInstance.Nodes)
	}

	if len(result.WorkflowInstance.Nodes) == 0 {
		fmt.Println("No nodes found for this workflow instance.")
		return nil
	}

	table := tablewriter.NewWriter(os.Stdout)
	table.Header([]string{"ID", "Key", "Type", "Status", "Task", "Retries"})

	for _, n := range result.WorkflowInstance.Nodes {
		taskTitle := ""
		if n.Task != nil {
			taskTitle = n.Task.Title
			if len(taskTitle) > 30 {
				taskTitle = taskTitle[:27] + "..."
			}
		}
		table.Append([]string{n.ID, n.NodeKey, n.NodeType, n.Status, taskTitle, fmt.Sprintf("%d", n.RetryCount)})
	}

	table.Render()
	return nil
}

func workflowNodeGet(ctx context.Context, cmd *cli.Command) error {
	cfg, err := config.Load()
	if err != nil {
		return err
	}
	if err := RequireAuth(cfg); err != nil {
		return err
	}

	c := client.New(cfg.ServerURL)
	c.SetToken(cfg.Token)

	id := cmd.String("id")
	query := `query WorkflowNode($id: ID!) { workflowNode(id: $id) { id nodeKey nodeType status task { id title } inputData outputData retryCount createdAt updatedAt startedAt completedAt } }`

	// Note: This assumes a workflowNode query exists. If not, we need to fetch via instance
	// For now, let's use a workaround by fetching the instance and finding the node
	query = `query WorkflowInstances { workflowInstances { id nodes: workflowNodes { id nodeKey nodeType status task { id title content } inputData outputData retryCount createdAt updatedAt startedAt completedAt } } }`

	resp, err := c.Query(query, nil)
	if err != nil {
		return err
	}

	var result struct {
		WorkflowInstances []struct {
			ID    string         `json:"id"`
			Nodes []WorkflowNode `json:"nodes"`
		} `json:"workflowInstances"`
	}
	if err := json.Unmarshal(resp.Data, &result); err != nil {
		return err
	}

	// Find the node
	var node *WorkflowNode
	for _, instance := range result.WorkflowInstances {
		for _, n := range instance.Nodes {
			if n.ID == id {
				node = &n
				break
			}
		}
		if node != nil {
			break
		}
	}

	if node == nil {
		return fmt.Errorf("workflow node not found")
	}

	if cmd.Bool("json") {
		enc := json.NewEncoder(os.Stdout)
		enc.SetIndent("", "  ")
		return enc.Encode(node)
	}

	fmt.Printf("ID: %s\n", node.ID)
	fmt.Printf("Key: %s\n", node.NodeKey)
	fmt.Printf("Type: %s\n", node.NodeType)
	fmt.Printf("Status: %s\n", node.Status)
	fmt.Printf("Retry Count: %d\n", node.RetryCount)
	if node.Task != nil {
		fmt.Printf("Task: %s (%s)\n", node.Task.Title, node.Task.ID)
	}
	fmt.Printf("Created At: %s\n", node.CreatedAt)
	fmt.Printf("Updated At: %s\n", node.UpdatedAt)
	if node.StartedAt != nil {
		fmt.Printf("Started At: %s\n", *node.StartedAt)
	}
	if node.CompletedAt != nil {
		fmt.Printf("Completed At: %s\n", *node.CompletedAt)
	}
	if node.InputData != "" {
		fmt.Printf("\nInput Data:\n%s\n", node.InputData)
	}
	if node.OutputData != "" {
		fmt.Printf("\nOutput Data:\n%s\n", node.OutputData)
	}

	return nil
}

func workflowNodeRetry(ctx context.Context, cmd *cli.Command) error {
	cfg, err := config.Load()
	if err != nil {
		return err
	}
	if err := RequireAuth(cfg); err != nil {
		return err
	}

	id := cmd.String("id")

	c := client.New(cfg.ServerURL)
	c.SetToken(cfg.Token)

	mutation := `mutation RetryWorkflowNode($nodeId: ID!) { retryWorkflowNode(nodeId: $nodeId) { id nodeKey status retryCount } }`

	resp, err := c.Mutation(mutation, map[string]interface{}{"nodeId": id})
	if err != nil {
		return err
	}

	var result struct {
		RetryWorkflowNode *WorkflowNode `json:"retryWorkflowNode"`
	}
	if err := json.Unmarshal(resp.Data, &result); err != nil {
		return err
	}

	if result.RetryWorkflowNode == nil {
		return fmt.Errorf("workflow node not found")
	}

	fmt.Printf("Workflow node retry initiated!\n")
	fmt.Printf("Node ID: %s\n", result.RetryWorkflowNode.ID)
	fmt.Printf("Key: %s\n", result.RetryWorkflowNode.NodeKey)
	fmt.Printf("Status: %s\n", result.RetryWorkflowNode.Status)
	fmt.Printf("Retry Count: %d\n", result.RetryWorkflowNode.RetryCount)

	return nil
}

// ReadFileOrString reads file content if input starts with @, otherwise returns as-is
func ReadFileOrString(input string) string {
	if strings.HasPrefix(input, "@") {
		filename := input[1:]
		content, err := os.ReadFile(filename)
		if err != nil {
			return input // Return original if file can't be read
		}
		return string(content)
	}
	return input
}
