package exec

import (
	"encoding/json"

	invopopjsonschema "github.com/invopop/jsonschema"
)

var workflowPlanSpec = actionSpec[workflowPlanRequest, workflowPlanResult]{
	Meta: actionMeta{
		Domain:      "workflow",
		Name:        "plan",
		Summary:     "author and version Workflow Plans",
		Description: "Create, inspect, edit, validate, compile, publish, version, read exact version source/layout, archive, and restore Workflow Plans through one closed action union; Team-linked Plans publish directly under their Team Leader.",
		Permission:  permissionAgentScopedMutation,
	},
	Examples: []actionExample[workflowPlanRequest]{
		{
			Title: "create Thread handoff Plan",
			Input: workflowPlanRequest{
				Action:      "create",
				Key:         "thread_handoff",
				DisplayName: "Thread handoff",
				Source: `apiVersion: loop.plan/v1
kind: PlanVersion
input:
  destination: {type: scope, required: true}
  planner: {type: agent, required: true}
graph:
  entry:
    nodeId: open_thread
    port: in
    input:
      destination: {ref: plan.input.destination}
      planner: {ref: plan.input.planner}
  nodes:
    - id: open_thread
      type: send_message
      input:
        destination: {type: scope, required: true}
        planner: {type: agent, required: true}
      sendMessage:
        scope: {ref: input.destination}
        text: "Workflow collaboration thread"
        completion: sent
        startThread: true
    - id: ask_planner
      type: send_message
      input:
        destination: {type: scope, required: true}
        planner: {type: agent, required: true}
      sendMessage:
        scope: {ref: input.destination}
        responder: {ref: input.planner}
        text: "Continue in this Thread"
        completion: callback
        callbackOutput:
          result: {type: string, required: true}
    - id: done
      type: end
      end: {outcome: succeeded}
  edges:
    - id: thread_opened
      source: {nodeId: open_thread, port: completed}
      target: {nodeId: ask_planner, port: in}
      bindings:
        destination: {ref: output.threadScope}
        planner: {ref: input.planner}
    - id: planner_completed
      source: {nodeId: ask_planner, port: completed}
      target: {nodeId: done, port: in}
`,
			},
		},
	},
}

var workflowTriggerSpec = actionSpec[workflowTriggerRequest, workflowTriggerResult]{
	Meta: actionMeta{
		Domain:      "workflow",
		Name:        "trigger",
		Summary:     "deploy and control automatic Workflow Triggers",
		Description: "Create, inspect, validate, update, enable, disable, or archive automatic Workflow Triggers.",
		Permission:  permissionAgentScopedMutation,
	},
	Examples: []actionExample[workflowTriggerRequest]{
		{Title: "list triggers", Input: workflowTriggerRequest{Action: "list", Limit: 20}},
	},
}

var workflowRunSpec = actionSpec[workflowRunRequest, workflowRunResult]{
	Meta: actionMeta{
		Domain:      "workflow",
		Name:        "run",
		Summary:     "start, inspect, follow, or cancel Workflow Runs",
		Description: "Start a published Plan version, inspect Runs, read redacted business logs, or cancel a Run.",
		Permission:  permissionAgentScopedMutation,
	},
	Examples: []actionExample[workflowRunRequest]{
		{Title: "show a Run", Input: workflowRunRequest{Action: "show", RunID: "wri_1"}},
	},
}

var workflowStepSpec = actionSpec[workflowStepCommand, workflowStepOutcome]{
	Meta: actionMeta{
		Domain:      "workflow",
		Name:        "step",
		Summary:     "list, inspect, or finish authorized Workflow Steps",
		Description: "Discover authorized Steps across Runs, or inspect, complete, fail, pause, or park a Step selected by Run and Step ID; the Server verifies the authenticated Agent against the frozen callback responder and its current lifecycle. Park is a repeatable keyless recovery cycle; legacy keys are optional.",
		Permission:  permissionAgentScopedMutation,
	},
	Examples: []actionExample[workflowStepCommand]{
		{Title: "list authorized Steps", Input: workflowStepCommand{Action: "list", Limit: 50}},
	},
}

func mustTypedWorkflowSchema(raw json.RawMessage) *invopopjsonschema.Schema {
	var schema invopopjsonschema.Schema
	if err := json.Unmarshal(raw, &schema); err != nil {
		panic(err)
	}
	return &schema
}
