package knowledgeqa

import (
	"context"
	"crypto/ed25519"
	"testing"
	"time"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/forwarder"
	"github.com/tidbcloud/AgentTeam/internal/knowledgeqa/protocol"
	"github.com/tidbcloud/AgentTeam/internal/maas/capability"
	knowledgeqastore "github.com/tidbcloud/AgentTeam/internal/store/knowledgeqa"
)

func TestWorkerCommitsCompletedAnswerThroughAtomicTerminalFence(t *testing.T) {
	now := time.Date(2026, 7, 25, 8, 0, 0, 0, time.UTC)
	_, privateKey, err := ed25519.GenerateKey(nil)
	require.NoError(t, err)
	store := &workerTestStore{
		turn: knowledgeqastore.Turn{
			ID: "kqt_completed", WorkspaceID: "wsp_1", OrganizationID: "org_1",
			SessionID: "kqs_1", RequesterUserID: "usr_1", Question: "What is policy?",
			CurrentAttemptID: "kqa_completed",
		},
		session: knowledgeqastore.Session{
			ID: "kqs_1", OwnerMemberID: "mem_1", ThreadChannelID: "thr_1",
		},
	}
	runtime := &workerTestRuntime{
		prepared: forwarder.KnowledgeQARuntimePrepareResult{
			Roots: []forwarder.KnowledgeQARuntimeRoot{{
				HandleID: "kqh_1", KnowledgeBaseID: "kb_1", SourceID: "src_1",
				RootKind: "primary", RepoRole: "primary", Revision: "sha-fixed",
			}},
			RuntimeVersion: "knowledge-qa-v3", PromptVersion: "exploration-v2",
		},
		result: forwarder.KnowledgeQARuntimeResult{
			Status: "completed",
			Claims: []forwarder.KnowledgeQARuntimeClaim{{
				Text: "Grounded answer. [E1]", EvidenceIDs: []string{"E1"},
			}},
			Diagnostics: []forwarder.KnowledgeQARuntimeDiagnostic{{
				Code: "knowledge_qa.grounding.evidence_unavailable", Severity: "warning",
			}},
			Evidence: []forwarder.KnowledgeQARuntimeEvidence{{
				ID: "E1", Citation: forwarder.KnowledgeQARuntimeCitation{
					KnowledgeBaseID: "kb_1", SourceID: "src_1", RootKind: "primary",
					RepoRole: "primary", Revision: "sha-fixed", Path: "docs/policy.md",
					LineStart: 1, LineEnd: 2,
				},
			}},
			SearchedRoots: 1, Usage: map[string]any{"input_tokens": 4},
			SettlementRef:  "settlement_completed_2",
			SettlementRefs: []string{"settlement_completed_1", "settlement_completed_2"},
		},
	}
	deliveredAfterCommit := false
	messageFanout := &workerTestMessageFanout{onDeliver: func() {
		deliveredAfterCommit = store.completion.Status == "completed"
	}}
	turnUpdates := &workerTestTurnUpdates{}
	worker, err := NewWorker(WorkerOptions{
		Store: store, Policies: workerTestPolicy{effective: protocol.EffectivePolicy{
			Model: "model-a", ReasonLevel: "high", WorkloadKind: capability.WorkloadKnowledgeQA, OrganizationPolicyVersion: 1,
		}}, Runtime: runtime, Signer: capability.Signer{KeyID: "test", PrivateKey: privateKey},
		Provisioner: workerTestProvisioner{}, Messages: workerTestMessages{}, MessageFanout: messageFanout,
		TurnUpdates: turnUpdates, Now: func() time.Time { return now },
	})
	require.NoError(t, err)

	worker.execute(context.Background(), knowledgeqastore.QueuedAttempt{
		WorkspaceID: "wsp_1", TurnID: "kqt_completed", AttemptID: "kqa_completed",
	})

	require.Equal(t, "completed", store.completion.Status)
	require.Equal(t, "msg_answer", store.completion.AssistantMessageID)
	require.Equal(t, "settlement_completed_2", store.completion.SettlementRef)
	require.Equal(t, []string{"settlement_completed_1", "settlement_completed_2"}, store.completion.SettlementRefs)
	require.Len(t, store.citations, 1)
	require.Len(t, messageFanout.appMessages, 1)
	require.Equal(t, "msg_answer", messageFanout.appMessages[0].ID)
	require.Len(t, messageFanout.deliveries, 1)
	require.NotNil(t, messageFanout.deliveries[0].AppMessage)
	require.Equal(t, "msg_answer", messageFanout.deliveries[0].AppMessage.ID)
	require.True(t, deliveredAfterCommit)
	require.True(t, turnUpdates.updates[len(turnUpdates.updates)-1].MessageProjectionChanged)
	require.NotEmpty(t, store.citations[0].ID)
	require.Contains(t, store.events, protocol.RuntimeActivity{
		Kind: "diagnostic", Status: "warning",
		ToolName: "knowledge_qa.grounding.evidence_unavailable",
	})
}
