package auth

import (
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/core/authidentity"
)

const (
	RegistrationModeOpen       = "open"
	RegistrationModeInviteOnly = "invite_only"
)

type RegistrationPolicy struct {
	mode            string
	allowedPatterns []string
}

func NewRegistrationPolicy(mode string, allowedEmails []string) RegistrationPolicy {
	policy := RegistrationPolicy{
		mode:            normalizeRegistrationMode(mode),
		allowedPatterns: make([]string, 0, len(allowedEmails)),
	}
	for _, pattern := range allowedEmails {
		normalizedPattern, err := authidentity.NormalizeEmailAllowlistPattern(pattern)
		if err != nil {
			continue
		}
		policy.allowedPatterns = append(policy.allowedPatterns, normalizedPattern)
	}
	return policy
}

func normalizeRegistrationMode(mode string) string {
	switch strings.ToLower(strings.TrimSpace(mode)) {
	case RegistrationModeInviteOnly:
		return RegistrationModeInviteOnly
	case RegistrationModeOpen, "":
		return RegistrationModeOpen
	default:
		return strings.ToLower(strings.TrimSpace(mode))
	}
}

func (policy RegistrationPolicy) AllowsOpenRegistration() bool {
	return policy.mode != RegistrationModeInviteOnly
}

func (policy RegistrationPolicy) HasEmailAllowlist() bool {
	return len(policy.allowedPatterns) > 0
}

func (policy RegistrationPolicy) AllowsEmail(email string) bool {
	for _, pattern := range policy.allowedPatterns {
		if authidentity.EmailMatchesAllowlistPattern(email, pattern) {
			return true
		}
	}
	return false
}

func (policy RegistrationPolicy) Mode() string {
	return normalizeRegistrationMode(policy.mode)
}

func (policy RegistrationPolicy) IsZero() bool {
	return strings.TrimSpace(policy.mode) == "" && len(policy.allowedPatterns) == 0
}
