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 TestPublicationNotificationCardsUseScopedReviewLinks(t *testing.T) {
	payload := kbgovernance.PublicationPayload{
		SchemaVersion: kbgovernance.PublicationPayloadSchema,
		WorkspaceID:   "ws_1", KnowledgeBaseID: "kb/1", WorkingRevision: "kbr_1",
		ContentDigest: "digest", RequesterID: "usr_member", IdempotencyKey: "publish-1",
	}
	raw, err := json.Marshal(payload)
	require.NoError(t, err)
	instance := approval.Instance{
		ID: "appr/1", WorkspaceID: "ws_1", SubjectType: kbgovernance.PublicationSubjectType,
		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 := publicationNotificationContent(instance, payload, &assignment, false)
	require.NoError(t, err)
	var reviewerCard struct {
		Template string `json:"template"`
		TitleKey string `json:"titleKey"`
		Actions  []struct {
			ActionKey string `json:"actionKey"`
			Type      string `json:"type"`
			URL       string `json:"url"`
		} `json:"actions"`
	}
	require.NoError(t, json.Unmarshal(reviewer.CardJSON, &reviewerCard))
	require.Equal(t, "approval_action", reviewerCard.Template)
	require.Equal(t, "kb_publication_review", reviewerCard.TitleKey)
	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, "open_url", reviewerCard.Actions[2].Type)
	require.Equal(t, "/kb/publication-reviews/appr%2F1", reviewerCard.Actions[2].URL)

	applicant, err := publicationNotificationContent(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 = publicationNotificationContent(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=review", applicantCard.Actions[0].URL)
	require.NotContains(t, string(reviewer.CardJSON), "SnapshotJSON")
}

func TestPublicationNotificationTerminalTitles(t *testing.T) {
	payload := kbgovernance.PublicationPayload{KnowledgeBaseID: "kb_1", WorkingRevision: "kbr_1"}
	for _, test := range []struct {
		name, state, reason, titleKey string
	}{
		{name: "published", state: approval.StateApproved, titleKey: "kb_publication_published"},
		{name: "rejected", state: approval.StateRejected, titleKey: "kb_publication_rejected"},
		{name: "withdrawn", state: approval.StateCancelled, titleKey: "kb_publication_withdrawn"},
		{name: "stale", state: approval.StateCancelled, reason: "stale_subject", titleKey: "kb_publication_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 := publicationNotificationContent(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)
		})
	}
}
