package main

import (
	"context"
	"errors"
	"testing"
)

type fakeConfigsSource struct {
	configs []map[string]any
	err     error
	gotKey  string
}

func (f *fakeConfigsSource) PublishedBlockConfigs(_ context.Context, blockKey string) ([]map[string]any, error) {
	f.gotKey = blockKey
	return f.configs, f.err
}

func TestPublishedBlockResolverRequiresCaptchaOnMatch(t *testing.T) {
	src := &fakeConfigsSource{configs: []map[string]any{
		{"username": "other", "eventTypeSlug": "30min", "captchaEnabled": true},
		{"username": "Alice", "eventTypeSlug": "30min", "captchaEnabled": true},
	}}
	r := publishedBlockResolver{source: src}

	got, err := r.CalcomBookingRequiresCaptcha(context.Background(), "alice", "30min")
	if err != nil || !got {
		t.Fatalf("RequiresCaptcha = %v, %v; want true (case-insensitive username match)", got, err)
	}
	if src.gotKey != "calcom:booking" {
		t.Fatalf("queried block key %q, want calcom:booking", src.gotKey)
	}
}

func TestPublishedBlockResolverNoRequirementWhenDisabledOrUnmatched(t *testing.T) {
	src := &fakeConfigsSource{configs: []map[string]any{
		{"username": "alice", "eventTypeSlug": "30min", "captchaEnabled": false},
		{"username": "alice", "eventTypeSlug": "60min", "captchaEnabled": true},
	}}
	r := publishedBlockResolver{source: src}

	if got, _ := r.CalcomBookingRequiresCaptcha(context.Background(), "alice", "30min"); got {
		t.Fatal("RequiresCaptcha = true; want false (disabled for 30min, 60min doesn't match)")
	}
}

func TestPublishedBlockResolverEmptyConfigUsernameMatchesAny(t *testing.T) {
	// A block may omit username (falls back to the plugin's default account);
	// the requirement then applies to the event type for any posted username —
	// erring toward requiring captcha, never stripping it.
	src := &fakeConfigsSource{configs: []map[string]any{
		{"eventTypeSlug": "30min", "captchaEnabled": true},
	}}
	r := publishedBlockResolver{source: src}

	if got, _ := r.CalcomBookingRequiresCaptcha(context.Background(), "whoever", "30min"); !got {
		t.Fatal("RequiresCaptcha = false; want true (config without username applies to any)")
	}
}

func TestPublishedBlockResolverPropagatesError(t *testing.T) {
	src := &fakeConfigsSource{err: errors.New("hostcall failed")}
	r := publishedBlockResolver{source: src}

	if _, err := r.CalcomBookingRequiresCaptcha(context.Background(), "alice", "30min"); err == nil {
		t.Fatal("expected error to propagate (caller decides fail-open policy)")
	}
}
