package taskboard

import (
	"testing"

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

func TestTaskBrowseSearchTextDefinesProfileFields(t *testing.T) {
	expr := browseSearchTextSQL()
	require.Contains(t, expr, "CONCAT('#t', t.task_number)")
	require.Contains(t, expr, "COALESCE(t.title, '')")
	require.Contains(t, expr, "COALESCE(t.description, '')")
	require.Contains(t, expr, "assignee_member.display_name")
	require.Contains(t, expr, "assignee_user.display_name")
	require.Contains(t, expr, "assignee_agent.name")
	require.Contains(t, expr, "kind_option.display_label")
	require.Contains(t, expr, "priority_option.display_label")
}

func TestBuildBrowseSearchConditionUsesCallerPlaceholder(t *testing.T) {
	condition := buildBrowseSearchCondition("$1")
	require.Contains(t, condition, browseSearchTextSQL())
	require.Contains(t, condition, " LIKE $1")
}

func TestTaskBrowseSearchLikePatternNormalizesQuery(t *testing.T) {
	require.Equal(t, "%release board%", browseSearchLikePattern("  Release   BOARD  "))
	require.Empty(t, browseSearchLikePattern(" \t\n "))
}

func TestBuildTaskProfileSearchIDsQueryOwnsWorkspaceVisibility(t *testing.T) {
	query, args, normalized, err := buildTaskProfileSearchIDsQuery(taskSearchPlan{
		WorkspaceID: " wsp-1 ",
		MemberID:    " mem-1 ",
		Query:       "  Release   BOARD  ",
	})
	require.NoError(t, err)
	require.Equal(t, "release board", normalized)
	require.Equal(t, []any{"wsp-1", "mem-1", "%release board%"}, args)
	require.Contains(t, query, "SELECT t.id")
	require.Contains(t, query, "JOIN scope_memberships search_sm")
	require.Contains(t, query, "search_sm.member_id = $2")
	require.Contains(t, query, "NULLIF(t.claimed_by_ref, '')")
	require.Contains(t, query, browseSearchTextSQL()+" LIKE $3")
	require.Contains(t, query, "ORDER BY t.id ASC")
}

func TestBuildTaskProfileSearchIDsQueryOwnsChannelScope(t *testing.T) {
	query, args, normalized, err := buildTaskProfileSearchIDsQuery(taskSearchPlan{
		WorkspaceID: "wsp-1",
		ChannelID:   "chn-1",
		Query:       "reviewer",
	})
	require.NoError(t, err)
	require.Equal(t, "reviewer", normalized)
	require.Equal(t, []any{"wsp-1", "chn-1", "%reviewer%"}, args)
	require.Contains(t, query, "tb.channel_id = $2")
	require.Contains(t, query, "JOIN scopes task_board_channel")
	require.NotContains(t, query, "JOIN scope_memberships search_sm")
	require.Contains(t, query, browseSearchTextSQL()+" LIKE $3")
}

func TestBuildTaskProfileSearchIDsQueryUsesTaskNumberFastPathForChannel(t *testing.T) {
	query, args, normalized, err := buildTaskProfileSearchIDsQuery(taskSearchPlan{
		WorkspaceID: "wsp-1",
		ChannelID:   "chn-1",
		Query:       " #T42 ",
	})
	require.NoError(t, err)
	require.Equal(t, "#t42", normalized)
	require.Equal(t, []any{"wsp-1", "chn-1", int64(42)}, args)
	require.Contains(t, query, "FROM tasks t")
	require.Contains(t, query, "JOIN task_boards tb ON tb.id = t.board_id")
	require.Contains(t, query, "tb.workspace_id = $1")
	require.Contains(t, query, "tb.channel_id = $2")
	require.Contains(t, query, "JOIN scopes task_scope")
	require.Contains(t, query, "t.task_number = $3")
	require.NotContains(t, query, "CONCAT_WS")
	require.NotContains(t, query, " LIKE ")
	require.NotContains(t, query, "JOIN scope_memberships search_sm")
}

func TestBuildTaskProfileSearchIDsQueryUsesTaskNumberFastPathForWorkspace(t *testing.T) {
	query, args, normalized, err := buildTaskProfileSearchIDsQuery(taskSearchPlan{
		WorkspaceID: "wsp-1",
		MemberID:    "mem-1",
		Query:       "t7",
	})
	require.NoError(t, err)
	require.Equal(t, "t7", normalized)
	require.Equal(t, []any{"wsp-1", "mem-1", int64(7)}, args)
	require.Contains(t, query, "JOIN scope_memberships search_sm")
	require.Contains(t, query, "search_sm.member_id = $2")
	require.Contains(t, query, "t.task_number = $3")
	require.NotContains(t, query, "CONCAT_WS")
	require.NotContains(t, query, " LIKE ")
}

func TestBuildTaskProfileSearchIDsQueryKeepsProfileSearchForNonExactTaskNumber(t *testing.T) {
	query, args, normalized, err := buildTaskProfileSearchIDsQuery(taskSearchPlan{
		WorkspaceID: "wsp-1",
		ChannelID:   "chn-1",
		Query:       "#t042",
	})
	require.NoError(t, err)
	require.Equal(t, "#t042", normalized)
	require.Equal(t, []any{"wsp-1", "chn-1", "%#t042%"}, args)
	require.Contains(t, query, browseSearchTextSQL()+" LIKE $3")
}
