package message

import (
	"strings"
	"unicode"
	"unicode/utf8"
)

func MentionTokenMatchesTarget(token string, target string) bool {
	_, ok := matchedMentionTargetToken(token, []string{target})
	return ok
}

func MatchedMentionTargetToken(token string, targets []string) (string, bool) {
	return matchedMentionTargetToken(token, targets)
}

func matchedMentionTargetToken(token string, targets []string) (string, bool) {
	normalizedToken := strings.ToLower(strings.TrimSpace(token))
	if normalizedToken == "" {
		return "", false
	}

	best := ""
	for _, target := range targets {
		normalizedTarget := strings.ToLower(strings.TrimSpace(target))
		if normalizedTarget == "" {
			continue
		}
		if normalizedToken == normalizedTarget {
			if len(normalizedTarget) > len(best) {
				best = normalizedTarget
			}
			continue
		}
		if !mentionTokenAllowsCJKPrefixMatch(normalizedToken, normalizedTarget) {
			continue
		}
		if len(normalizedTarget) > len(best) {
			best = normalizedTarget
		}
	}
	return best, best != ""
}

func mentionTokenAllowsCJKPrefixMatch(token string, target string) bool {
	if !strings.HasPrefix(token, target) || len(token) == len(target) {
		return false
	}
	if !containsHanRune(target) {
		return false
	}
	suffix := token[len(target):]
	first, _ := utf8.DecodeRuneInString(suffix)
	return first != utf8.RuneError && unicode.Is(unicode.Han, first)
}

func containsHanRune(value string) bool {
	for _, r := range value {
		if unicode.Is(unicode.Han, r) {
			return true
		}
	}
	return false
}
