package dialectsfcrm

import (
	"context"
	"net/http"
	"testing"

	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/contract"
	"github.com/nexuscrm/shared/pkg/dialect"
	"github.com/nexuscrm/shared/pkg/models"
	"github.com/nexuscrm/shared/pkg/queryspec"
)

type searchSpecCaptureQuery struct {
	captured queryspec.SearchSpec
}

func (q *searchSpecCaptureQuery) Query(context.Context, queryspec.QuerySpec, *models.UserSession) (*contract.QueryResult, error) {
	return &contract.QueryResult{}, nil
}

func (q *searchSpecCaptureQuery) SearchWithSpec(_ context.Context, spec queryspec.SearchSpec, _ *models.UserSession) ([]contract.Record, error) {
	q.captured = spec
	return []contract.Record{{
		constants.FieldID:   "001000000000001",
		constants.FieldName: "Acme",
	}}, nil
}

func (q *searchSpecCaptureQuery) GlobalSearchWithSpec(context.Context, queryspec.GlobalSearchSpec, *models.UserSession) ([]contract.SearchResult, error) {
	return nil, nil
}

func (q *searchSpecCaptureQuery) QueryHistory(context.Context, contract.HistoryQueryRequest, *models.UserSession) (*contract.HistoryQueryResult, error) {
	return nil, nil
}

func TestSOSLSubstringSearchForcesBaseTable(t *testing.T) {
	query := &searchSpecCaptureQuery{}
	accountSchema := &models.ObjectMetadata{
		APIName:    "Account",
		Label:      "Account",
		Searchable: true,
		Fields: []models.FieldMetadata{
			{APIName: constants.FieldID, Type: constants.FieldTypeString, IsSystem: true},
			{APIName: constants.FieldName, Type: constants.FieldTypeString, IsNameField: true},
		},
	}
	req := &dialect.Request{
		Version: "v63.0",
		Query: map[string][]string{
			"q": {"FIND {Acme} IN ALL FIELDS RETURNING Account(Id, Name LIMIT 5)"},
		},
		User: &models.UserSession{ID: "005000000000001"},
	}

	resp, err := SearchNeutralHandler(context.Background(), req, dialect.Deps{
		Contracts: contract.Deps{
			Query: query,
			Metadata: &fakeDescribeMetadata{schemas: map[string]*models.ObjectMetadata{
				"Account": accountSchema,
			}},
			Policy: &fakeDescribePolicy{access: map[string]*contract.EffectiveObjectAccess{
				"Account": {Object: contract.ObjectAccess{Read: true}},
			}},
		},
	})
	if err != nil {
		t.Fatalf("SearchNeutralHandler returned error: %v", err)
	}
	if resp.Status != http.StatusOK {
		t.Fatalf("status = %d, want %d; body=%#v", resp.Status, http.StatusOK, resp.Body)
	}

	if !query.captured.ForceBaseTable {
		t.Fatalf("ForceBaseTable = false, want true for SOSL substring search")
	}
	if query.captured.ObjectAPIName != "Account" {
		t.Fatalf("ObjectAPIName = %q, want Account", query.captured.ObjectAPIName)
	}
	if query.captured.Prefix {
		t.Fatalf("Prefix = true, want false for substring search")
	}
	if query.captured.Term != "Acme" {
		t.Fatalf("Term = %q, want Acme", query.captured.Term)
	}
}
