package metadata

import (
	"context"
	"errors"
	"strings"
	"testing"

	"github.com/nexuscrm/kernel/pkg/ports"
	"github.com/nexuscrm/shared/pkg/models"
)

func TestMetadataRefreshRetainsValidationRuleSnapshotWhenReloadFails(t *testing.T) {
	repository := &validationRuleRefreshRepo{
		rules: []*models.ValidationRule{{
			ID:            "rule-1",
			ObjectAPIName: "Account",
			Name:          "RejectInvalid",
		}},
	}
	service := NewMetadataService(repository, nil, nil)
	if err := service.RefreshCache(context.Background()); err != nil {
		t.Fatalf("initial RefreshCache: %v", err)
	}

	repository.rules = nil
	repository.rulesErr = errors.New("corrupt validation rule")
	if err := service.RefreshCache(context.Background()); err == nil || !strings.Contains(err.Error(), "failed to load validation rules") {
		t.Fatalf("RefreshCache error = %v, want validation-rule load failure", err)
	}

	rules, err := service.GetValidationRulesForMutation(context.Background(), "Account")
	if err != nil {
		t.Fatalf("GetValidationRulesForMutation after failed refresh: %v", err)
	}
	if len(rules) != 1 || rules[0].ID != "rule-1" {
		t.Fatalf("validation rules after failed refresh = %#v, want prior safe snapshot", rules)
	}
}

func TestMetadataInitializationFailsClosedWhenValidationRulesCannotLoad(t *testing.T) {
	service := NewMetadataService(&validationRuleRefreshRepo{
		rulesErr: errors.New("corrupt validation rule"),
	}, nil, nil)

	if err := service.RefreshCache(context.Background()); err == nil || !strings.Contains(err.Error(), "failed to load validation rules") {
		t.Fatalf("RefreshCache error = %v, want validation-rule load failure", err)
	}
	if _, err := service.GetValidationRulesForMutation(context.Background(), "Account"); err == nil {
		t.Fatal("GetValidationRulesForMutation succeeded without a complete validation-rule snapshot")
	}
}

type validationRuleRefreshRepo struct {
	ports.MetadataRepository
	rules    []*models.ValidationRule
	rulesErr error
}

func (*validationRuleRefreshRepo) GetAllSchemas(context.Context) ([]*models.ObjectMetadata, error) {
	return []*models.ObjectMetadata{{APIName: "Account"}}, nil
}

func (*validationRuleRefreshRepo) GetAllRelationships(context.Context) ([]*models.Relationship, error) {
	return nil, nil
}

func (*validationRuleRefreshRepo) GetAllFlowDefinitions(context.Context) ([]*models.FlowDefinition, error) {
	return nil, nil
}

func (r *validationRuleRefreshRepo) GetAllValidationRules(context.Context) ([]*models.ValidationRule, error) {
	return r.rules, r.rulesErr
}
