package dialectsfcrm

import (
	"testing"

	soql "github.com/nexuscrm/dialect-sf-crm-soql"
)

// B-prereq (#2120): a top-level multi-column ORDER BY must reach the engine in
// full. The SOQL parser records every term on req.OrderBy while SortField holds
// only the first column; querySpecFromParsedSOQL previously forwarded SortField
// alone, so `ORDER BY A, B` silently ordered by A only. This also gates the B1
// keyset cursor, which must seek on the identical effective sort list.
func TestQuerySpecFromParsedSOQL_MapsMultiColumnOrderBy(t *testing.T) {
	parsed, err := soql.ParseSOQLWith(
		"SELECT Id FROM Account ORDER BY Industry ASC, AnnualRevenue DESC, Id ASC",
		soql.ParseOpts{AllowSemiJoin: true},
	)
	if err != nil {
		t.Fatalf("parse: %v", err)
	}

	spec := querySpecFromParsedSOQL(parsed)

	want := []struct{ field, dir string }{
		{"Industry", "ASC"},
		{"AnnualRevenue", "DESC"},
		{"Id", "ASC"},
	}
	if len(spec.OrderBy) != len(want) {
		t.Fatalf("expected %d ORDER BY terms, got %d (%+v)", len(want), len(spec.OrderBy), spec.OrderBy)
	}
	for i, w := range want {
		if spec.OrderBy[i].Field != w.field || spec.OrderBy[i].Direction != w.dir {
			t.Errorf("term %d = {%s %s}, want {%s %s}",
				i, spec.OrderBy[i].Field, spec.OrderBy[i].Direction, w.field, w.dir)
		}
	}

	// SortField/SortDirection must still carry the FIRST column verbatim — MRU
	// routing and read-target view selection consume them; the change is additive.
	if spec.SortField != "Industry" || spec.SortDirection != "ASC" {
		t.Errorf("first-column SortField/SortDirection not preserved: %q/%q", spec.SortField, spec.SortDirection)
	}
}

// A single-column ORDER BY keeps behaving identically (both OrderBy and the
// legacy SortField are populated), so no existing single-sort caller regresses.
func TestQuerySpecFromParsedSOQL_SingleColumnOrderByUnchanged(t *testing.T) {
	parsed, err := soql.ParseSOQLWith(
		"SELECT Id FROM Account ORDER BY CreatedDate DESC",
		soql.ParseOpts{AllowSemiJoin: true},
	)
	if err != nil {
		t.Fatalf("parse: %v", err)
	}

	spec := querySpecFromParsedSOQL(parsed)

	if len(spec.OrderBy) != 1 || spec.OrderBy[0].Field != "CreatedDate" || spec.OrderBy[0].Direction != "DESC" {
		t.Fatalf("single-column OrderBy mismap: %+v", spec.OrderBy)
	}
	if spec.SortField != "CreatedDate" || spec.SortDirection != "DESC" {
		t.Errorf("SortField/Direction not preserved: %q/%q", spec.SortField, spec.SortDirection)
	}
}

// No ORDER BY: spec.OrderBy stays empty (the engine then applies its default /
// keyset-default order), and SortField stays empty.
func TestQuerySpecFromParsedSOQL_NoOrderByLeavesEmpty(t *testing.T) {
	parsed, err := soql.ParseSOQLWith("SELECT Id FROM Account", soql.ParseOpts{AllowSemiJoin: true})
	if err != nil {
		t.Fatalf("parse: %v", err)
	}

	spec := querySpecFromParsedSOQL(parsed)

	if len(spec.OrderBy) != 0 {
		t.Errorf("expected empty OrderBy, got %+v", spec.OrderBy)
	}
	if spec.SortField != "" {
		t.Errorf("expected empty SortField, got %q", spec.SortField)
	}
}
