package app

import (
	"context"
	"database/sql"
	"errors"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/AgentTeam/internal/coredb"
	"github.com/tidbcloud/AgentTeam/internal/store/message"
)

type recordingParticipationQueryer struct {
	query string
	args  []any
}

func TestScanAppMessageRowPreservesEditState(t *testing.T) {
	t.Parallel()

	createdAt := time.Date(2026, 6, 19, 10, 0, 0, 0, time.UTC)
	editedAt := createdAt.Add(3 * time.Minute)

	got, err := scanAppMessageRow(stubScanRow{values: []any{
		"msg_edit_scan",
		int64(7),
		"scp_edit_scan",
		"human",
		"mem_author",
		sql.NullString{String: "usr_author", Valid: true},
		sql.NullString{},
		sql.NullString{},
		sql.NullString{String: "Author", Valid: true},
		sql.NullString{},
		sql.NullString{},
		sql.NullString{},
		sql.NullString{},
		sql.NullString{String: "client-1", Valid: true},
		"",
		"edited content",
		[]byte(`{"kind":"edit"}`),
		createdAt,
		sql.NullTime{Time: editedAt, Valid: true},
		"mem_author",
		int64(2),
	}})

	require.NoError(t, err)
	require.Equal(t, "edited content", got.Content)
	require.NotNil(t, got.EditedAt)
	require.True(t, got.EditedAt.Equal(editedAt))
	require.Equal(t, "mem_author", got.EditedByMemberID)
	require.EqualValues(t, 2, got.EditRevision)
}

func (queryer *recordingParticipationQueryer) QueryRow(_ context.Context, query string, args ...any) coredb.Row {
	queryer.query = query
	queryer.args = append([]any(nil), args...)
	return recordingParticipationRow{}
}

func (queryer *recordingParticipationQueryer) Query(context.Context, string, ...any) (coredb.Rows, error) {
	return nil, errors.New("unexpected Query call")
}

type recordingParticipationRow struct{}

func (recordingParticipationRow) Scan(dest ...any) error {
	*dest[0].(*int64) = 3
	*dest[1].(*int64) = 2
	*dest[2].(*int64) = 1
	return nil
}

func TestLoadMessageParticipationStatsUsesSemanticsExcludedTypes(t *testing.T) {
	t.Parallel()

	queryer := &recordingParticipationQueryer{}

	stats, err := loadMessageParticipationStats(context.Background(), queryer, "wsp-1", "scp-1", "mem-1")

	require.NoError(t, err)
	require.Equal(t, message.MessageParticipationStats{Total: 3, Agent: 2, Human: 1}, stats)
	require.Contains(t, queryer.query, "message_type NOT IN ($3, $4, $5, $6, $7)")
	require.Equal(t, []any{
		"wsp-1",
		"scp-1",
		message.MessageTypeChannelShareCard,
		message.MessageTypeSystem,
		message.MessageTypeTaskDescriptionAttachment,
		message.MessageTypeTaskDispatch,
		message.MessageTypeThreadShareCard,
	}, queryer.args)
	require.Contains(t, queryer.query, "author_type IN ('agent', 'human')")
	require.Contains(t, queryer.query, "FROM workflow_run_effects")
	require.Contains(t, queryer.query, "FROM automation_runs")
	require.Contains(t, queryer.query, "FROM service_event_deliveries")
	require.NotContains(t, queryer.query, "workflow_authored")
}
