// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package convert

import (
	"context"
	"time"

	"git.imall.cloud/openim/open-im-server-deploy/pkg/common/storage/model"

	pbgroup "git.imall.cloud/openim/protocol/group"
	sdkws "git.imall.cloud/openim/protocol/sdkws"
	"github.com/openimsdk/tools/log"
)

func Db2PbGroupInfo(m *model.Group, ownerUserID string, memberCount uint32) *sdkws.GroupInfo {
	return &sdkws.GroupInfo{
		GroupID:                m.GroupID,
		GroupName:              m.GroupName,
		Notification:           m.Notification,
		Introduction:           m.Introduction,
		FaceURL:                m.FaceURL,
		OwnerUserID:            ownerUserID,
		CreateTime:             m.CreateTime.UnixMilli(),
		MemberCount:            memberCount,
		Ex:                     m.Ex,
		Status:                 m.Status,
		CreatorUserID:          m.CreatorUserID,
		GroupType:              m.GroupType,
		NeedVerification:       m.NeedVerification,
		LookMemberInfo:         m.LookMemberInfo,
		ApplyMemberFriend:      m.ApplyMemberFriend,
		NotificationUpdateTime: m.NotificationUpdateTime.UnixMilli(),
		NotificationUserID:     m.NotificationUserID,
	}
}

func Pb2DbGroupRequest(req *pbgroup.GroupApplicationResponseReq, handleUserID string) *model.GroupRequest {
	return &model.GroupRequest{
		UserID:       req.FromUserID,
		GroupID:      req.GroupID,
		HandleResult: req.HandleResult,
		HandledMsg:   req.HandledMsg,
		HandleUserID: handleUserID,
		HandledTime:  time.Now(),
	}
}

func Db2PbCMSGroup(m *model.Group, ownerUserID string, ownerUserName string, memberCount uint32) *pbgroup.CMSGroup {
	return &pbgroup.CMSGroup{
		GroupInfo:          Db2PbGroupInfo(m, ownerUserID, memberCount),
		GroupOwnerUserID:   ownerUserID,
		GroupOwnerUserName: ownerUserName,
	}
}

// Db2PbGroupMember 将数据库群成员模型转换为 protobuf 群成员信息
// 返回的 GroupMemberFullInfo 包含以下禁言相关字段：
//   - MuteEndTime: 禁言结束时间（毫秒时间戳）
//     判断是否被禁言：MuteEndTime >= 当前时间戳（毫秒）表示正在被禁言
//     判断剩余禁言时间：max(0, MuteEndTime - 当前时间戳) / 1000 得到剩余秒数
func Db2PbGroupMember(m *model.GroupMember) *sdkws.GroupMemberFullInfo {
	muteEndTime := int64(0)
	if !m.MuteEndTime.IsZero() && m.MuteEndTime.After(time.Unix(0, 0)) {
		muteEndTime = m.MuteEndTime.UnixMilli()
		// 记录从数据库读取的禁言时间，用于排查自动禁言问题
		now := time.Now()
		if muteEndTime >= now.UnixMilli() {
			// 只有在用户被禁言时才记录日志，避免日志过多
			log.ZInfo(context.Background(), "Db2PbGroupMember: found muted user in database", 
				"groupID", m.GroupID,
				"userID", m.UserID,
				"muteEndTimeFromDB", m.MuteEndTime.Format(time.RFC3339),
				"muteEndTimeTimestamp", muteEndTime,
				"now", now.Format(time.RFC3339),
				"mutedDurationSeconds", (muteEndTime-now.UnixMilli())/1000,
				"isZero", m.MuteEndTime.IsZero(),
				"afterUnixZero", m.MuteEndTime.After(time.Unix(0, 0)))
		}
	}
	return &sdkws.GroupMemberFullInfo{
		GroupID:   m.GroupID,
		UserID:    m.UserID,
		RoleLevel: m.RoleLevel,
		JoinTime:  m.JoinTime.UnixMilli(),
		Nickname:  m.Nickname,
		FaceURL:   m.FaceURL,
		// AppMangerLevel: m.AppMangerLevel,
		JoinSource:     m.JoinSource,
		OperatorUserID: m.OperatorUserID,
		Ex:             m.Ex,
		MuteEndTime:    muteEndTime,
		InviterUserID:  m.InviterUserID,
	}
}

func Db2PbGroupRequest(m *model.GroupRequest, user *sdkws.UserInfo, group *sdkws.GroupInfo) *sdkws.GroupRequest {
	var pu *sdkws.PublicUserInfo
	if user != nil {
		pu = &sdkws.PublicUserInfo{
			UserID:   user.UserID,
			Nickname: user.Nickname,
			FaceURL:  user.FaceURL,
			Ex:       user.Ex,
			UserType: user.UserType,
		}
	}
	return &sdkws.GroupRequest{
		UserInfo:      pu,
		GroupInfo:     group,
		HandleResult:  m.HandleResult,
		ReqMsg:        m.ReqMsg,
		HandleMsg:     m.HandledMsg,
		ReqTime:       m.ReqTime.UnixMilli(),
		HandleUserID:  m.HandleUserID,
		HandleTime:    m.HandledTime.UnixMilli(),
		Ex:            m.Ex,
		JoinSource:    m.JoinSource,
		InviterUserID: m.InviterUserID,
	}
}

func Db2PbGroupAbstractInfo(
	groupID string,
	groupMemberNumber uint32,
	groupMemberListHash uint64,
) *pbgroup.GroupAbstractInfo {
	return &pbgroup.GroupAbstractInfo{
		GroupID:             groupID,
		GroupMemberNumber:   groupMemberNumber,
		GroupMemberListHash: groupMemberListHash,
	}
}

func Pb2DBGroupInfo(m *sdkws.GroupInfo) *model.Group {
	return &model.Group{
		GroupID:                m.GroupID,
		GroupName:              m.GroupName,
		Notification:           m.Notification,
		Introduction:           m.Introduction,
		FaceURL:                m.FaceURL,
		CreateTime:             time.Now(),
		Ex:                     m.Ex,
		Status:                 m.Status,
		CreatorUserID:          m.CreatorUserID,
		GroupType:              m.GroupType,
		NeedVerification:       m.NeedVerification,
		LookMemberInfo:         m.LookMemberInfo,
		ApplyMemberFriend:      m.ApplyMemberFriend,
		NotificationUpdateTime: time.UnixMilli(m.NotificationUpdateTime),
		NotificationUserID:     m.NotificationUserID,
	}
}

// func Pb2DbGroupMember(m *sdkws.UserInfo) *relation.GroupMember {
//	return &relation.GroupMember{
//		UserID:   m.UserID,
//		Nickname: m.Nickname,
//		FaceURL:  m.FaceURL,
//		Ex:       m.Ex,
//	}
//}
