package msg

import (
	"strconv"
	"strings"

	"git.imall.cloud/openim/open-im-server-deploy/pkg/common/config"
	"git.imall.cloud/openim/protocol/constant"
	pbchat "git.imall.cloud/openim/protocol/msg"
	"github.com/openimsdk/tools/utils/datautil"
)

const (
	separator = "-"
)

func filterAfterMsg(msg *pbchat.SendMsgReq, after *config.AfterConfig) bool {
	result := filterMsg(msg, after.AttentionIds, after.DeniedTypes)
	// 添加调试日志
	if !result {
		// 只在过滤掉时记录，避免日志过多
	}
	return result
}

func filterBeforeMsg(msg *pbchat.SendMsgReq, before *config.BeforeConfig) bool {
	return filterMsg(msg, nil, before.DeniedTypes)
}

func filterMsg(msg *pbchat.SendMsgReq, attentionIds []string, deniedTypes []int32) bool {
	// According to the attentionIds configuration, only some users are sent
	// 注意：对于群消息，应该检查GroupID而不是RecvID
	if len(attentionIds) != 0 {
		// 单聊消息检查RecvID，群聊消息检查GroupID
		if msg.MsgData.SessionType == constant.SingleChatType {
			if !datautil.Contain(msg.MsgData.RecvID, attentionIds...) {
				return false
			}
		} else if msg.MsgData.SessionType == constant.ReadGroupChatType {
			if !datautil.Contain(msg.MsgData.GroupID, attentionIds...) {
				return false
			}
		}
	}

	if defaultDeniedTypes(msg.MsgData.ContentType) {
		return false
	}

	if len(deniedTypes) != 0 && datautil.Contain(msg.MsgData.ContentType, deniedTypes...) {
		return false
	}
	//if len(allowedTypes) != 0 && !isInInterval(msg.MsgData.ContentType, allowedTypes) {
	//	return false
	//}
	//if len(deniedTypes) != 0 && isInInterval(msg.MsgData.ContentType, deniedTypes) {
	//	return false
	//}
	return true
}

func defaultDeniedTypes(contentType int32) bool {
	if contentType >= constant.NotificationBegin && contentType <= constant.NotificationEnd {
		return true
	}
	if contentType == constant.Typing {
		return true
	}
	return false
}

// isInInterval if data is in interval
// Supports two formats: a single type or a range. The range is defined by the lower and upper bounds connected with a hyphen ("-")
// e.g. [1, 100, 200-500, 600-700] means that only data within the range
// {1, 100} ∪ [200, 500] ∪ [600, 700] will return true.
func isInInterval(data int32, interval []string) bool {
	for _, v := range interval {
		if strings.Contains(v, separator) {
			// is interval
			bounds := strings.Split(v, separator)
			if len(bounds) != 2 {
				continue
			}
			bottom, err := strconv.Atoi(bounds[0])
			if err != nil {
				continue
			}
			top, err := strconv.Atoi(bounds[1])
			if err != nil {
				continue
			}
			if datautil.BetweenEq(int(data), bottom, top) {
				return true
			}
		} else {
			iv, err := strconv.Atoi(v)
			if err != nil {
				continue
			}
			if int(data) == iv {
				return true
			}
		}
	}
	return false
}
