package knowledgeqa

import (
	"context"
	"sync"
	"testing"
	"time"

	"github.com/stretchr/testify/require"

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

type workerProgressTestRuntime struct {
	mu      sync.Mutex
	results []forwarder.KnowledgeQAAccountingRecoveryResult
}

func (runtime *workerProgressTestRuntime) PrepareKnowledgeQATurn(context.Context, forwarder.KnowledgeQARuntimePrepareRequest) (forwarder.KnowledgeQARuntimePrepareResult, error) {
	return forwarder.KnowledgeQARuntimePrepareResult{}, nil
}

func (runtime *workerProgressTestRuntime) ExecuteKnowledgeQATurn(context.Context, forwarder.KnowledgeQARuntimeRequest) (forwarder.KnowledgeQARuntimeResult, error) {
	return forwarder.KnowledgeQARuntimeResult{}, nil
}

func (runtime *workerProgressTestRuntime) RecoverKnowledgeQATurnAccounting(context.Context, forwarder.KnowledgeQAAccountingRecoveryRequest) (forwarder.KnowledgeQAAccountingRecoveryResult, error) {
	runtime.mu.Lock()
	defer runtime.mu.Unlock()
	if len(runtime.results) == 0 {
		return forwarder.KnowledgeQAAccountingRecoveryResult{}, nil
	}
	result := runtime.results[0]
	runtime.results = runtime.results[1:]
	return result, nil
}

func TestWorkerPublishesBoundedMonotonicExplorationProgress(t *testing.T) {
	store := &workerTestStore{}
	runtime := &workerProgressTestRuntime{results: []forwarder.KnowledgeQAAccountingRecoveryResult{
		{Found: true, Generation: 1},
		{Found: true, Generation: 2},
		{Found: true, Generation: 3},
		{Found: true, Generation: 4},
		{Found: true, Generation: 9},
	}}
	worker := &Worker{
		store: store, runtime: runtime,
		now:                  func() time.Time { return time.Date(2026, 7, 31, 8, 0, 0, 0, time.UTC) },
		progressPollInterval: time.Millisecond,
	}
	ctx, cancel := context.WithCancel(context.Background())
	done := make(chan struct{})
	go func() {
		defer close(done)
		worker.monitorKnowledgeQATurnProgress(
			ctx,
			knowledgeqastore.Session{},
			knowledgeqastore.Turn{
				ID: "kqt_1", WorkspaceID: "wsp_1", CurrentAttemptID: "kqa_1",
			},
			forwarder.KnowledgeQARuntimeRequest{
				Principal: forwarder.KnowledgeQARuntimePrincipal{
					OrganizationID: "org_1", WorkspaceID: "wsp_1",
					RequesterID: "usr_1", TurnID: "kqt_1",
				},
				IdempotencyKey: "kqa_1",
			},
		)
	}()

	require.Eventually(t, func() bool {
		return len(store.eventSnapshot()) == 4
	}, 250*time.Millisecond, time.Millisecond)
	cancel()
	<-done

	events := store.eventSnapshot()
	require.Len(t, events, 4)
	require.Equal(t, []int{1, 2, 4, 9}, []int{
		events[0].ModelCalls,
		events[1].ModelCalls,
		events[2].ModelCalls,
		events[3].ModelCalls,
	})
	for _, event := range events {
		require.Equal(t, "tool", event.Kind)
		require.Equal(t, "completed", event.Status)
		require.Equal(t, "model", event.ToolName)
		require.Empty(t, event.Summary)
	}
}
