package taskboard

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

	"github.com/stretchr/testify/require"
)

func TestEnsureTaskScopeParticipantNotificationDefaultInsertsWithoutNotificationReadBeforeWrite(t *testing.T) {
	now := time.Date(2026, 6, 13, 8, 0, 0, 0, time.UTC)
	execer := &scriptedTaskboardQueryExecer{
		execResults: []scriptedTaskboardExecResult{
			{tag: testExecResult{rowsAffected: 1}},
			{tag: testExecResult{rowsAffected: 1}},
		},
		rowResults: []scriptedTaskboardRowResult{
			{values: []any{"task", sql.NullString{}, ""}},
		},
	}

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

	require.NoError(t, err)
	require.Len(t, execer.queries, 3)
	require.Contains(t, execer.queries[0], "SELECT scope.type")
	require.Contains(t, execer.queries[0], "LEFT JOIN scopes parent")
	require.Contains(t, execer.queries[1], "updated_at = CASE")
	require.Contains(t, execer.queries[1], "ELSE updated_at")
	require.Contains(t, execer.queries[2], "INSERT INTO scope_notification_settings")
	require.Contains(t, execer.queries[2], "task_watch_state")
	for _, query := range execer.queries {
		require.NotContains(t, query, "FROM scope_notification_settings")
	}
}

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

	now := time.Date(2026, 6, 14, 9, 10, 0, 0, time.UTC)
	execer := &scriptedTaskboardQueryExecer{
		execResults: []scriptedTaskboardExecResult{
			{tag: testExecResult{rowsAffected: 1}},
			{tag: testExecResult{rowsAffected: 1}},
		},
		rowResults: []scriptedTaskboardRowResult{
			{values: []any{"human"}},
			{values: []any{"task", sql.NullString{}, ""}},
		},
	}

	err := TxStore{}.ensureTaskDiscussionScopeParticipants(
		context.Background(),
		execer,
		"wsp_1",
		"task_scope_1",
		"mem_actor",
		Task{},
		[]taskDiscussionMentionTarget{
			{MemberID: " mem_actor "},
			{MemberID: "mem_actor"},
		},
		now,
	)

	require.NoError(t, err)
	require.Len(t, execer.queries, 4)
	require.Contains(t, execer.queries[0], "SELECT type")
	require.Contains(t, execer.queries[1], "SELECT scope.type")
	require.Contains(t, execer.queries[1], "LEFT JOIN scopes parent")
	require.Contains(t, execer.queries[2], "UPDATE scope_memberships")
	require.Contains(t, execer.queries[3], "INSERT INTO scope_notification_settings")
	require.Contains(t, execer.queries[3], "task_watch_state")
	require.Equal(t, "mute", execer.args[3][2])
}

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

	for _, test := range []struct {
		memberType string
		want       string
	}{
		{memberType: "human", want: "mute"},
		{memberType: "agent", want: "no-wake"},
	} {
		t.Run(test.memberType, func(t *testing.T) {
			execer := &scriptedTaskboardQueryExecer{
				rowResults: []scriptedTaskboardRowResult{{values: []any{test.memberType}}},
			}

			got, err := taskScopeDefaultUnwatchedNotificationStateForMember(context.Background(), execer, "mem_1")

			require.NoError(t, err)
			require.Equal(t, test.want, got)
		})
	}
}
