package dialectsfcrm_test

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

	dialectsfcrm "github.com/nexuscrm/dialect-sf-crm"
	"github.com/nexuscrm/shared/pkg/contract"
	"github.com/nexuscrm/shared/pkg/dialect"
	"github.com/nexuscrm/shared/pkg/models"
)

func TestMetadataSearchScopeOrderNeutralHandlerUsesCuratedContractOrder(t *testing.T) {
	req := &dialect.Request{
		Version: "v63.0",
		User:    &models.UserSession{ID: "005xx"},
	}
	deps := dialect.Deps{Contracts: contract.Deps{
		SearchScope: fakeMetadataSearchScope{curated: []string{"Lead", "Account"}},
	}}

	resp, err := dialectsfcrm.MetadataSearchScopeOrderNeutralHandler(context.Background(), req, deps)
	if err != nil {
		t.Fatalf("MetadataSearchScopeOrderNeutralHandler returned error: %v", err)
	}
	if resp.Status != http.StatusOK {
		t.Fatalf("status = %d, want 200", resp.Status)
	}
	want := []string{"Lead", "Account"}
	if !reflect.DeepEqual(resp.Body, want) {
		t.Fatalf("body = %#v, want %#v", resp.Body, want)
	}
}

func TestMetadataSearchScopeOrderNeutralHandlerFallsBackToEmptyListWithoutContractOrUser(t *testing.T) {
	for _, tc := range []struct {
		name string
		req  *dialect.Request
		deps dialect.Deps
	}{
		{name: "missing contract", req: &dialect.Request{User: &models.UserSession{ID: "005xx"}}},
		{name: "missing request", req: nil, deps: dialect.Deps{Contracts: contract.Deps{SearchScope: fakeMetadataSearchScope{curated: []string{"Lead"}}}}},
		{name: "missing user", req: &dialect.Request{}, deps: dialect.Deps{Contracts: contract.Deps{SearchScope: fakeMetadataSearchScope{curated: []string{"Lead"}}}}},
	} {
		t.Run(tc.name, func(t *testing.T) {
			resp, err := dialectsfcrm.MetadataSearchScopeOrderNeutralHandler(context.Background(), tc.req, tc.deps)
			if err != nil {
				t.Fatalf("MetadataSearchScopeOrderNeutralHandler returned error: %v", err)
			}
			if resp.Status != http.StatusOK {
				t.Fatalf("status = %d, want 200", resp.Status)
			}
			if !reflect.DeepEqual(resp.Body, []string{}) {
				t.Fatalf("body = %#v, want []string{}", resp.Body)
			}
		})
	}
}

type fakeMetadataSearchScope struct {
	curated []string
}

func (f fakeMetadataSearchScope) ScopeOrder(context.Context, *models.UserSession) []contract.SearchScopeItem {
	return nil
}

func (f fakeMetadataSearchScope) CuratedObjectNames(context.Context, *models.UserSession) []string {
	return append([]string(nil), f.curated...)
}
