package service

import (
	"strings"

	roomv1 "hyapp.local/api/proto/room/v1"
	"hyapp/pkg/tencentim"
	"hyapp/services/room-service/internal/room/command"
	"hyapp/services/room-service/internal/room/state"
)

func normalizeGiftTargetUserIDs(targetUserID int64, targetUserIDs []int64) []int64 {
	seen := make(map[int64]bool, len(targetUserIDs)+1)
	ids := make([]int64, 0, len(targetUserIDs)+1)
	for _, userID := range targetUserIDs {
		if userID <= 0 || seen[userID] {
			continue
		}
		seen[userID] = true
		ids = append(ids, userID)
	}
	if len(ids) == 0 && targetUserID > 0 {
		ids = append(ids, targetUserID)
	}
	return ids
}

func giftTargetHostScopesFromProto(scopes []*roomv1.SendGiftTargetHostScope) []command.GiftTargetHostScope {
	result := make([]command.GiftTargetHostScope, 0, len(scopes))
	seen := make(map[int64]bool, len(scopes))
	for _, scope := range scopes {
		targetUserID := scope.GetTargetUserId()
		if targetUserID <= 0 || seen[targetUserID] {
			continue
		}
		seen[targetUserID] = true
		result = append(result, command.GiftTargetHostScope{
			TargetUserID:            targetUserID,
			TargetIsHost:            scope.GetTargetIsHost(),
			TargetHostRegionID:      scope.GetTargetHostRegionId(),
			TargetAgencyOwnerUserID: scope.GetTargetAgencyOwnerUserId(),
		})
	}
	return result
}

func giftDisplayProfileFromProto(item *roomv1.SendGiftDisplayProfile) command.GiftDisplayProfile {
	if item == nil || item.GetUserId() <= 0 {
		return command.GiftDisplayProfile{}
	}
	effectiveVIPLevel := item.GetEffectiveVipLevel()
	if effectiveVIPLevel < 0 {
		// VIP 等级只用于展示；协议异常值归零，不能污染持久命令或让送礼主链路失败。
		effectiveVIPLevel = 0
	}
	// 展示快照只裁剪空白字符，不做业务兜底；兜底顺序统一放在 giftDisplayName，避免事件字段互相不一致。
	return command.GiftDisplayProfile{
		UserID:                    item.GetUserId(),
		Username:                  strings.TrimSpace(item.GetUsername()),
		Avatar:                    strings.TrimSpace(item.GetAvatar()),
		DisplayUserID:             strings.TrimSpace(item.GetDisplayUserId()),
		PrettyDisplayUserID:       strings.TrimSpace(item.GetPrettyDisplayUserId()),
		EffectiveVIPLevel:         effectiveVIPLevel,
		GiftBroadcastAnimationURL: strings.TrimSpace(item.GetGiftBroadcastAnimationUrl()),
	}
}

func giftDisplayProfilesFromProto(items []*roomv1.SendGiftDisplayProfile) []command.GiftDisplayProfile {
	result := make([]command.GiftDisplayProfile, 0, len(items))
	seen := make(map[int64]bool, len(items))
	for _, item := range items {
		profile := giftDisplayProfileFromProto(item)
		if profile.UserID <= 0 || seen[profile.UserID] {
			continue
		}
		seen[profile.UserID] = true
		result = append(result, profile)
	}
	return result
}

func filterGiftTargetHostScopes(scopes []command.GiftTargetHostScope, targetUserIDs []int64) []command.GiftTargetHostScope {
	if len(scopes) == 0 || len(targetUserIDs) == 0 {
		return nil
	}
	allowed := giftTargetUserIDSet(targetUserIDs)
	result := make([]command.GiftTargetHostScope, 0, len(scopes))
	for _, scope := range scopes {
		if allowed[scope.TargetUserID] {
			result = append(result, scope)
		}
	}
	return result
}

func giftTargetHostScopeForExact(scopes []command.GiftTargetHostScope, targetUserID int64) (command.GiftTargetHostScope, bool) {
	if targetUserID <= 0 {
		return command.GiftTargetHostScope{}, false
	}
	for _, scope := range scopes {
		if scope.TargetUserID == targetUserID {
			return scope, true
		}
	}
	return command.GiftTargetHostScope{}, false
}

func filterGiftDisplayProfiles(profiles []command.GiftDisplayProfile, targetUserIDs []int64) []command.GiftDisplayProfile {
	if len(profiles) == 0 || len(targetUserIDs) == 0 {
		return nil
	}
	allowed := giftTargetUserIDSet(targetUserIDs)
	result := make([]command.GiftDisplayProfile, 0, len(profiles))
	for _, profile := range profiles {
		if allowed[profile.UserID] {
			result = append(result, profile)
		}
	}
	return result
}

func giftTargetUserIDSet(targetUserIDs []int64) map[int64]bool {
	result := make(map[int64]bool, len(targetUserIDs))
	for _, targetUserID := range targetUserIDs {
		if targetUserID > 0 {
			result[targetUserID] = true
		}
	}
	return result
}

func giftDisplayProfileForUser(profiles []command.GiftDisplayProfile, userID int64) command.GiftDisplayProfile {
	if userID <= 0 {
		return command.GiftDisplayProfile{}
	}
	for _, profile := range profiles {
		if profile.UserID == userID {
			return profile
		}
	}
	return command.GiftDisplayProfile{UserID: userID}
}

func giftDisplayName(profile command.GiftDisplayProfile) string {
	// Flutter 的 IM 解析已支持 sender_name/receiver_nickname；这里按用户昵称、靓号、短号依次兜底，避免跨房飘窗直接落到 User <id>。
	for _, value := range []string{profile.Username, profile.PrettyDisplayUserID, profile.DisplayUserID} {
		if trimmed := strings.TrimSpace(value); trimmed != "" {
			return trimmed
		}
	}
	return ""
}

func giftTargetUserIDsAttribute(targetUserIDs []int64) string {
	// direct IM 与 outbox 补偿必须使用相同的字符串数组协议，不能让同一事件因投递路径不同而出现 number/string 两种用户 ID。
	return tencentim.FormatUserIDsJSON(targetUserIDs)
}

func findRankItem(items []state.RankItem, userID int64) state.RankItem {
	// 送礼后通常能找到发送方榜单项；找不到时返回 user_id 占位避免空事件。
	for _, item := range items {
		if item.UserID == userID {
			return item
		}
	}

	return state.RankItem{UserID: userID}
}
