package agent

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

	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/api/workflow/binding"
	storeagent "github.com/tidbcloud/AgentTeam/internal/store/agent"
)

type triggerShowService struct {
	binding.Service
	binding         binding.Binding
	revision        binding.Revision
	revisionRequest int64
}

func (service *triggerShowService) Get(context.Context, string, string) (binding.Binding, error) {
	return service.binding, nil
}

func (service *triggerShowService) GetRevision(_ context.Context, _, _ string, revision int64) (binding.Revision, error) {
	service.revisionRequest = revision
	return service.revision, nil
}

func (*triggerShowService) ReplayCommand(context.Context, binding.ReplayCommandInput) (binding.ReplayCommandResult, bool, error) {
	return binding.ReplayCommandResult{}, false, nil
}

func TestWorkflowTriggerShowReturnsLatestRevisionDefinition(t *testing.T) {
	gin.SetMode(gin.TestMode)
	service := &triggerShowService{
		binding: binding.Binding{
			ID: "wbd_1", PlanID: "pln_1", Revision: 4,
			LatestRevision: &binding.RevisionRef{ID: "wbr_3", Revision: 3},
			Owner:          binding.Owner{UserID: "usr_00000000000001", MemberID: "0000000owner"},
		},
		revision: binding.Revision{
			ID: "wbr_3", BindingID: "wbd_1", PlanID: "pln_1", Revision: 3,
			PlanVersionID: "plv_7",
			Source:        json.RawMessage(`{"type":"schedule","schedule":{"mode":"cron","cronExpression":"0 * * * *","timezone":"UTC","inputs":{"region":"us"}}}`),
			InputPolicy:   json.RawMessage(`{"defaults":{"attempts":2},"constants":{"tenant":"acme"}}`),
			Digest:        "sha256:revision",
		},
	}
	router := gin.New()
	auth := fakeAgentAuthenticator{agent: storeagent.AuthenticatedAgent{
		AgentID: "agt_0000000000test", WorkspaceID: "wsp_test", MemberID: "00000000test",
	}}
	registerAgentWorkflowBindingRoutes(
		router, "/api/v1/workspaces/:workspaceId/agents/:agentId/runtime", auth,
		service, publicRouteRunOwner{}, publicRouteRunWorkspace{},
	)

	response := postWorkflowPublicCommand(t, router, "/workflow/trigger", map[string]any{
		"action": "show", "triggerId": "wbd_1",
	})
	require.Equal(t, http.StatusOK, response.Code, response.Body.String())
	require.Equal(t, int64(3), service.revisionRequest)

	var body map[string]any
	require.NoError(t, json.Unmarshal(response.Body.Bytes(), &body))
	require.Contains(t, body, "trigger")
	revision := body["revision"].(map[string]any)
	require.Equal(t, "wbd_1", revision["triggerId"])
	require.Equal(t, "plv_7", revision["planVersionId"])
	require.Equal(t, "sha256:revision", revision["digest"])
	require.Contains(t, revision, "source")
	require.Contains(t, revision, "inputPolicy")
	require.NotContains(t, revision, "bindingId")
	require.NotContains(t, response.Body.String(), `"binding"`)
}
