package placement

import (
	"strings"

	brandentity "haixun-backend/internal/model/brand/domain/entity"
)

func ScoreProductForTag(searchTag string, matchTags []string) int {
	tag := strings.TrimSpace(strings.ToLower(searchTag))
	if tag == "" || len(matchTags) == 0 {
		return 0
	}
	best := 0
	for _, raw := range matchTags {
		candidate := strings.TrimSpace(strings.ToLower(raw))
		if candidate == "" {
			continue
		}
		switch {
		case tag == candidate:
			best = maxInt(best, 100)
		case strings.Contains(tag, candidate) || strings.Contains(candidate, tag):
			best = maxInt(best, 70)
		default:
			tagWords := strings.Fields(tag)
			candWords := strings.Fields(candidate)
			overlap := 0
			for _, w := range tagWords {
				for _, c := range candWords {
					if strings.Contains(c, w) || strings.Contains(w, c) {
						overlap++
						break
					}
				}
			}
			if overlap > 0 {
				best = maxInt(best, 40+overlap*10)
			}
		}
	}
	return best
}

// ScoreProductForPost ranks a SKU against the search tag and post body.
func ScoreProductForPost(productLabel string, matchTags []string, searchTag, postText string) int {
	tagScore := ScoreProductForTag(searchTag, matchTags)
	if tagScore == 0 && strings.TrimSpace(productLabel) != "" {
		tagScore = ScoreProductForTag(searchTag, []string{productLabel})
	}
	postScore := ScoreProductForTag(postText, matchTags)
	if postScore == 0 && strings.TrimSpace(productLabel) != "" {
		postScore = ScoreProductForTag(postText, []string{productLabel})
	}
	for _, token := range categoryTokens(productLabel, matchTags) {
		if strings.Contains(strings.ToLower(postText), token) {
			postScore = maxInt(postScore, 78)
		}
		if strings.Contains(strings.ToLower(searchTag), token) {
			tagScore = maxInt(tagScore, 82)
		}
	}
	switch {
	case tagScore > 0 && postScore > 0:
		return (tagScore*2 + postScore*3) / 5
	case postScore > 0:
		return postScore
	default:
		return tagScore
	}
}

// RecommendProductForPost picks the best SKU for a single post.
func RecommendProductForPost(products []brandentity.Product, searchTag, postText, defaultProductID string) *brandentity.Product {
	if len(products) == 0 {
		return nil
	}
	bestScore := 0
	var best *brandentity.Product
	for i := range products {
		score := ScoreProductForPost(products[i].Label, products[i].MatchTags, searchTag, postText)
		if score > bestScore {
			bestScore = score
			best = &products[i]
		}
	}
	if best != nil && bestScore >= 55 {
		return best
	}
	return RecommendProduct(products, searchTag, defaultProductID)
}

func categoryTokens(productLabel string, matchTags []string) []string {
	blob := strings.ToLower(strings.TrimSpace(productLabel + " " + strings.Join(matchTags, " ")))
	tokens := []string{
		"洗衣精", "洗衣粉", "洗衣劑", "洗衣液",
		"沐浴乳", "沐浴露",
		"洗髮精", "洗髮乳",
		"洗碗精", "洗碗劑",
	}
	out := make([]string, 0, 4)
	for _, token := range tokens {
		if strings.Contains(blob, token) {
			out = append(out, token)
		}
	}
	return out
}

func maxInt(a, b int) int {
	if a > b {
		return a
	}
	return b
}
