package viral

import (
	"sort"
	"strings"

	"haixun-backend/internal/library/placement"
	missionentity "haixun-backend/internal/model/copy_mission/domain/entity"
)

func EnrichSimilarAccounts(existing []missionentity.SimilarAccount, posts []placement.ScanCandidate, limit int) []missionentity.SimilarAccount {
	if limit <= 0 {
		limit = MaxSimilarAccounts
	}
	byUser := map[string]missionentity.SimilarAccount{}
	order := []string{}
	for _, item := range existing {
		user := strings.ToLower(strings.TrimSpace(item.Username))
		if user == "" {
			continue
		}
		if _, ok := byUser[user]; !ok {
			order = append(order, user)
		}
		byUser[user] = item
	}

	type authorScore struct {
		username string
		score    int
		text     string
	}
	authors := map[string]authorScore{}
	for _, post := range posts {
		user := strings.TrimSpace(post.Author)
		if user == "" || !isValidUsername(user) {
			continue
		}
		key := strings.ToLower(user)
		prev := authors[key]
		prev.username = user
		prev.score += post.EngagementScore
		if prev.text == "" && strings.TrimSpace(post.Text) != "" {
			prev.text = strings.TrimSpace(post.Text)
		}
		authors[key] = prev
	}
	ranked := make([]authorScore, 0, len(authors))
	for _, item := range authors {
		ranked = append(ranked, item)
	}
	sort.Slice(ranked, func(i, j int) bool { return ranked[i].score > ranked[j].score })

	for _, item := range ranked {
		key := strings.ToLower(item.username)
		if _, ok := byUser[key]; ok {
			continue
		}
		reason := "本次海巡高互動作者"
		if item.text != "" {
			runes := []rune(item.text)
			if len(runes) > 80 {
				reason = string(runes[:80])
			} else {
				reason = item.text
			}
		}
		conf := "medium"
		if item.score >= 200 {
			conf = "high"
		}
		byUser[key] = missionentity.SimilarAccount{
			Username:   item.username,
			Reason:     reason,
			Source:     "scan",
			Confidence: conf,
			ProfileURL: "https://www.threads.net/@" + item.username,
		}
		order = append(order, key)
	}

	out := make([]missionentity.SimilarAccount, 0, len(order))
	for _, key := range order {
		if acc, ok := byUser[key]; ok {
			out = append(out, acc)
		}
	}
	if len(out) > limit {
		out = out[:limit]
	}
	return out
}

func AccountTagsFromSimilar(accounts []missionentity.SimilarAccount, max int) []SuggestedTag {
	if max <= 0 {
		max = 2
	}
	out := []SuggestedTag{}
	for _, acc := range accounts {
		user := strings.TrimSpace(acc.Username)
		if user == "" {
			continue
		}
		out = append(out, SuggestedTag{
			Tag:        "@" + user,
			Reason:     acc.Reason,
			SearchType: "帳號",
		})
		if len(out) >= max {
			break
		}
	}
	return out
}

func ToEntitySimilarAccounts(items []SimilarAccount) []missionentity.SimilarAccount {
	out := make([]missionentity.SimilarAccount, 0, len(items))
	for _, item := range items {
		out = append(out, missionentity.SimilarAccount{
			Username:   item.Username,
			Reason:     item.Reason,
			Source:     item.Source,
			Confidence: item.Confidence,
			ProfileURL: item.ProfileURL,
		})
	}
	return out
}
