package nostr

import (
	"context"
	"fmt"

	"git.devvul.com/asara/gologger"
	"git.devvul.com/asara/well-goknown/config"
	"github.com/fiatjaf/khatru"
	"github.com/nbd-wtf/go-nostr"
)

func RejectUnregisteredNpubs(ctx context.Context, event *nostr.Event) (reject bool, msg string) {
	l := gologger.Get(config.GetConfig().LogLevel).With().Caller().Logger()

	// always allow the following kinds
	// 13: nip-59 seals
	// 9734: nip-57 zap request
	// 9735: nip-57 zap receipt
	// 13194: nip-47 info event
	// 22242: nip-42 client auth
	// 23194: nip-47 request
	// 23195: nip-47 response
	// 23196: nip-47 notification
	// 30078: nip-78 addressable events
	switch event.Kind {
	case 13, 9734, 9735, 13194, 22242, 23194, 23195, 23196, 30078:
		return false, ""
	}

	// ensure pubkey has authenticated their pubkey
	authenticatedUser := khatru.GetAuthed(ctx)
	if authenticatedUser == "" {
		l.Debug().Msgf("kind: %v, pubkey not authed: %s", event.Kind, event.PubKey)
		return true, fmt.Sprintf("auth-required: interacting with this relay requires authentication")
	}

	// check if the message is by or for someone who is registered
	npubs := []string{authenticatedUser}
	// in addition to the registered users, others can use the relay for the following kinds
	// as long as a registered user is tagged in the `p` tag
	// 4: nip-04 encrypted dms
	// 6: nip-18 reposts (kind 1)
	// 7: nip-25 reactions
	// 14: nip-17 private dms
	// 16: nip-18 reposts (generic)
	// 1059: nip-59 gift wraps
	// 9802: nip-84 highlights
	// 24133: nip-46 nostr connect
	switch event.Kind {
	case 4, 6, 7, 14, 16, 1059, 9802, 24133:
		for _, npub := range event.Tags.GetAll([]string{"p"}) {
			npubs = append(npubs, npub.Value())
		}
	}

	// check if npubs are registered
	if authz := checknPubsInDb(npubs); authz == false {
		l.Debug().Msgf("kind: %v, pubkey: %s, unauthorized", event.Kind, event.PubKey)
		return true, fmt.Sprintf("restricted: this event is not from or to any registered users/npubs")
	}
	return false, ""
}