package app

import (
	"context"
	"errors"
	"testing"
	"time"

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

func TestEnsureTaskScopeDiscussionParticipantDefaultNotificationInsertsWithoutNotificationRead(t *testing.T) {
	now := time.Date(2026, 6, 13, 8, 0, 0, 0, time.UTC)
	execer := &recordingTaskDiscussionParticipantExecer{
		execRowsAffected: []int64{1, 1},
		memberType:       "human",
	}

	err := ensureTaskScopeDiscussionParticipantDefaultUnwatched(context.Background(), execer, " task_scope_1 ", " mem_1 ", now)

	require.NoError(t, err)
	// The contract is "no notification READ" for the default-notification case, not
	// a fixed read count: the generic EnsureScopeMembership now performs a topology
	// detect read (scopes) plus the member-type read, none of which may touch
	// scope_notification_settings.
	require.NotEmpty(t, execer.queries)
	for _, query := range execer.queries {
		require.NotContains(t, query, "scope_notification_settings", "default-notification case must not read scope_notification_settings")
	}
	require.Len(t, execer.execs, 2)
	require.Contains(t, execer.execs[1], "INSERT INTO scope_notification_settings")
	require.Contains(t, execer.execs[1], "task_watch_state")
	require.Contains(t, execer.execs[1], "ON DUPLICATE KEY UPDATE")
}

type recordingTaskDiscussionParticipantExecer struct {
	execs            []string
	execRowsAffected []int64
	memberType       string
	queries          []string
}

func (execer *recordingTaskDiscussionParticipantExecer) Exec(_ context.Context, query string, _ ...any) (coredb.Result, error) {
	execer.execs = append(execer.execs, query)
	if len(execer.execRowsAffected) == 0 {
		return testExecResult{}, nil
	}
	rowsAffected := execer.execRowsAffected[0]
	execer.execRowsAffected = execer.execRowsAffected[1:]
	return testExecResult{rowsAffected: rowsAffected}, nil
}

func (execer *recordingTaskDiscussionParticipantExecer) QueryRow(_ context.Context, query string, _ ...any) coredb.Row {
	execer.queries = append(execer.queries, query)
	return taskDiscussionParticipantMemberTypeRow{memberType: execer.memberType}
}

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

type taskDiscussionParticipantMemberTypeRow struct {
	memberType string
}

func (row taskDiscussionParticipantMemberTypeRow) Scan(dest ...any) error {
	*dest[0].(*string) = row.memberType
	return nil
}
