package exec

import (
	"context"
	"encoding/json"
	"io"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/desktop/internal/wire/apiclient"
)

func TestWorkflowStepExplicitSelectorDoesNotRequireActiveDelivery(t *testing.T) {
	var request workflowStepTransportRequest
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		require.Equal(t, "/api/v1/workspaces/wsp_1/agents/agt_1/runtime/workflow/step", r.URL.Path)
		request = workflowStepTransportRequest{}
		require.NoError(t, json.NewDecoder(r.Body).Decode(&request))
		if request.Action == "list" {
			_, _ = io.WriteString(w, `{"steps":[{"runId":"wri_1","stepId":"wfx_1","status":"awaiting","runStatus":"waiting"}]}`)
			return
		}
		_, _ = io.WriteString(w, `{
			"runId":"wri_1","stepId":"wfx_1","status":"awaiting","runStatus":"waiting",
			"input":{},"outputContract":[],"replayed":false
		}`)
	}))
	t.Cleanup(server.Close)

	// Workflow is deliberately nil: a later wake or daemon restart no longer
	// needs the original delivery snapshot to recover an authorized callback.
	authorized := runtimeAuthorization{Server: &apiclient.Client{
		ServerURL: server.URL, RouteWorkspaceID: "wsp_1", AgentID: "agt_1", LocalAgentID: "agt_1",
		AuthToken: "token", HTTPClient: server.Client(),
	}}
	result, err := (workflowHandler{}).step(context.Background(), actionScopedJSON[workflowStepCommand]{
		Authorized: authorized,
		Body: workflowStepCommand{
			Action: "get", RunID: "wri_1", StepID: "wfx_1",
		},
	})
	require.NoError(t, err)
	require.NotNil(t, result.Data.step)
	require.Equal(t, "wri_1", request.WorkflowRunID)
	require.Equal(t, "wfx_1", request.WorkflowStepID)
	require.Equal(t, "get", request.Action)

	list, err := (workflowHandler{}).step(context.Background(), actionScopedJSON[workflowStepCommand]{
		Authorized: authorized,
		Body:       workflowStepCommand{Action: "list", Limit: 25},
	})
	require.NoError(t, err)
	require.Nil(t, list.Data.step)
	require.Len(t, list.Data.list.Steps, 1)
	require.Equal(t, "wfx_1", list.Data.list.Steps[0].StepID)
	require.Equal(t, "", request.WorkflowRunID)
	require.Equal(t, "", request.WorkflowStepID)
	require.Equal(t, 25, request.Limit)
	require.Equal(t, "list", request.Action)

	output := workflowObject(`{"result":"done"}`)
	_, err = (workflowHandler{}).step(context.Background(), actionScopedJSON[workflowStepCommand]{
		Authorized: authorized,
		Body: workflowStepCommand{
			Action: "complete", RunID: "wri_1", StepID: "wfx_1",
			Output: &output, IdempotencyKey: "complete-wfx-1",
		},
	})
	require.NoError(t, err)
	require.Equal(t, "complete", request.Action)
	require.Equal(t, "wri_1", request.WorkflowRunID)
	require.Equal(t, "wfx_1", request.WorkflowStepID)
	require.JSONEq(t, `{"result":"done"}`, string(request.Output))
	require.Equal(t, "complete-wfx-1", request.IdempotencyKey)

	_, err = (workflowHandler{}).step(context.Background(), actionScopedJSON[workflowStepCommand]{
		Authorized: authorized,
		Body: workflowStepCommand{
			Action: "fail", RunID: "wri_2", StepID: "wfx_2",
			Code: "blocked", Message: "cannot continue", IdempotencyKey: "fail-wfx-2",
		},
	})
	require.NoError(t, err)
	require.Equal(t, "fail", request.Action)
	require.Equal(t, "wri_2", request.WorkflowRunID)
	require.Equal(t, "wfx_2", request.WorkflowStepID)
	require.Equal(t, "blocked", request.Code)
	require.Equal(t, "cannot continue", request.Message)
	require.Equal(t, "fail-wfx-2", request.IdempotencyKey)
}
