package approvalapp

import (
	"encoding/json"
	"testing"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/AgentTeam/internal/kbgovernance"
	"github.com/tidbcloud/AgentTeam/internal/store/approval"
)

func TestWikiGenerationNotificationCardsUseFrozenRequestAndScopedLinks(t *testing.T) {
	payload := kbgovernance.WikiGenerationPayload{
		SchemaVersion: kbgovernance.WikiGenerationPayloadSchema,
		WorkspaceID:   "ws_1", KnowledgeBaseID: "kb/1", SourceID: "src_1",
		SourceRevision: "rev_1", SourceCommitSHA: "commit_1", Scope: "full", Language: "zh-CN",
		Reason: "Focus on onboarding", RequesterID: "usr_member", IdempotencyKey: "wiki-1",
	}
	raw, err := json.Marshal(payload)
	require.NoError(t, err)
	instance := approval.Instance{
		ID: "appr/1", WorkspaceID: "ws_1", SubjectType: kbgovernance.WikiGenerationSubjectType,
		Payload: raw, ApplicantMemberID: "mem_member", State: approval.StatePending, Version: 1,
	}
	assignment := approval.Assignment{
		ID: "apas_1", WorkspaceID: "ws_1", ApprovalInstanceID: instance.ID,
		ApproverMemberID: "mem_admin", Status: approval.AssignmentPending,
	}
	reviewer, err := wikiGenerationNotificationContent(instance, payload, &assignment, false)
	require.NoError(t, err)
	var reviewerCard struct {
		Template string `json:"template"`
		TitleKey string `json:"titleKey"`
		Fields   []struct {
			Label string `json:"label"`
			Value string `json:"value"`
		} `json:"fields"`
		Actions []struct {
			ActionKey   string `json:"actionKey"`
			Type        string `json:"type"`
			URL         string `json:"url"`
			InputSchema struct {
				Required []string `json:"required"`
			} `json:"inputSchema"`
		} `json:"actions"`
	}
	require.NoError(t, json.Unmarshal(reviewer.CardJSON, &reviewerCard))
	require.Equal(t, "approval_action", reviewerCard.Template)
	require.Equal(t, "kb_wiki_generation_review", reviewerCard.TitleKey)
	require.Len(t, reviewerCard.Fields, 6)
	require.Equal(t, "rev_1", reviewerCard.Fields[2].Value)
	require.Equal(t, "Focus on onboarding", reviewerCard.Fields[5].Value)
	require.Len(t, reviewerCard.Actions, 3)
	require.Equal(t, "approve", reviewerCard.Actions[0].ActionKey)
	require.Equal(t, "reject", reviewerCard.Actions[1].ActionKey)
	require.Equal(t, []string{"reason"}, reviewerCard.Actions[1].InputSchema.Required)
	require.Equal(t, "open_url", reviewerCard.Actions[2].Type)
	require.Equal(t, "/kb/kb%2F1?setup=wiki&source=src_1", reviewerCard.Actions[2].URL)

	applicant, err := wikiGenerationNotificationContent(instance, payload, nil, true)
	require.NoError(t, err)
	var applicantCard struct {
		Template string `json:"template"`
		Actions  []struct {
			URL string `json:"url"`
		} `json:"actions"`
	}
	require.NoError(t, json.Unmarshal(applicant.CardJSON, &applicantCard))
	require.Equal(t, "default", applicantCard.Template)
	require.Empty(t, applicantCard.Actions)

	instance.State = approval.StateApproved
	instance.Version = 2
	applicant, err = wikiGenerationNotificationContent(instance, payload, nil, true)
	require.NoError(t, err)
	require.NoError(t, json.Unmarshal(applicant.CardJSON, &applicantCard))
	require.Equal(t, "approval_result", applicantCard.Template)
	require.Equal(t, "/kb/kb%2F1?setup=wiki&source=src_1", applicantCard.Actions[0].URL)
	require.NotContains(t, string(reviewer.CardJSON), payload.SourceCommitSHA)
}

func TestWikiGenerationNotificationTerminalTitles(t *testing.T) {
	payload := kbgovernance.WikiGenerationPayload{KnowledgeBaseID: "kb_1", SourceID: "src_1", SourceRevision: "rev_1"}
	for _, test := range []struct {
		name, state, reason, titleKey string
	}{
		{name: "queued", state: approval.StateApproved, titleKey: "kb_wiki_generation_queued"},
		{name: "rejected", state: approval.StateRejected, titleKey: "kb_wiki_generation_rejected"},
		{name: "withdrawn", state: approval.StateCancelled, titleKey: "kb_wiki_generation_withdrawn"},
		{name: "stale", state: approval.StateCancelled, reason: "stale_subject", titleKey: "kb_wiki_generation_stale"},
	} {
		t.Run(test.name, func(t *testing.T) {
			instance := approval.Instance{ID: "appr_1", State: test.state, DecisionReason: test.reason, Version: 2}
			content, err := wikiGenerationNotificationContent(instance, payload, nil, true)
			require.NoError(t, err)
			var card struct {
				TitleKey string `json:"titleKey"`
			}
			require.NoError(t, json.Unmarshal(content.CardJSON, &card))
			require.Equal(t, test.titleKey, card.TitleKey)
		})
	}
}
