package Wxhook

import (
	"context"
	"fmt"
	"github.com/spf13/cast"
	"github.com/suyuan32/simple-admin-common/enum/errorcode"
	"github.com/suyuan32/simple-admin-common/msg/errormsg"
	"strings"
	"wechat-api/ent/label"
	"wechat-api/hook"
	"wechat-api/internal/svc"
	"wechat-api/internal/types"

	reqv3 "github.com/imroc/req/v3"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetFriendsAndGroupsLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewGetFriendsAndGroupsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetFriendsAndGroupsLogic {
	return &GetFriendsAndGroupsLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx}
}

type GetWechatFriendListResp struct {
	Code int64 `json:"code"`
	Data []struct {
		Avatar         string `json:"avatar"`
		Cid            int64  `json:"cid"`
		City           string `json:"city"`
		Country        string `json:"country"`
		CreateTime     int64  `json:"create_time"`
		FriendWechatno string `json:"friend_wechatno"`
		Friendid       string `json:"friendid"`
		Gender         int64  `json:"gender"`
		ID             int64  `json:"id"`
		Memo           string `json:"memo"`
		ModifyTime     int64  `json:"modify_time"`
		Nickname       string `json:"nickname"`
		Phone          string `json:"phone"`
		Province       string `json:"province"`
		Remark         string `json:"remark"`
		Type           int64  `json:"type"`
		Wechatid       string `json:"wechatid"`
	} `json:"data"`
	Msg string `json:"msg"`
}

func (l *GetFriendsAndGroupsLogic) GetFriendsAndGroups(req *types.IDReq) (resp *types.BaseMsgResp, err error) {
	organizationId := l.ctx.Value("organizationId").(uint64)
	wxInfo, err := l.svcCtx.DB.Wx.Get(l.ctx, req.Id)
	if err != nil {
		l.Error("查询微信信息失败", err)
		return
	}

	if wxInfo.ServerID > 0 {
		//云托管版本
		serverInfo, err := l.svcCtx.DB.Server.Get(l.ctx, wxInfo.ServerID)
		if err != nil {
			l.Error("查询服务器信息失败", err)
			return nil, err
		}
		hookClient := hook.NewHook(serverInfo.PrivateIP, serverInfo.AdminPort, wxInfo.Port)

		friendAndChatRoomList, err := hookClient.GetFriendAndChatRoomList("0")
		if err != nil {
			l.Error("获取好友列表失败", err)
			return nil, err
		}
		newFriendIds := make(map[uint64][]string)
		newLagIds := make(map[string]struct{})
		friendCnt := cast.ToInt(friendAndChatRoomList.CountFriend)
		if friendCnt > 0 {
			for _, friend := range friendAndChatRoomList.Friend {
				id, err := l.svcCtx.DB.Contact.Create().
					SetWxWxid(wxInfo.Wxid).
					SetType(1).
					SetWxid(friend.Wxid).
					SetAccount(friend.Account).
					SetNickname(friend.Nickname).
					SetMarkname(friend.Markname).
					SetHeadimg(friend.Headimg).
					SetSex(cast.ToInt(friend.Sex)).
					SetStarrole(friend.Starrole).
					SetDontseeit(cast.ToInt(friend.Dontseeit)).
					SetDontseeme(cast.ToInt(friend.Dontseeme)).
					SetLag(friend.Lag).
					SetV3(friend.V3).
					SetOrganizationID(organizationId).
					OnConflict().
					UpdateNewValues().
					ID(l.ctx)
				if err == nil {
					lags := splitStringToIntArray(friend.Lag)
					newFriendIds[id] = lags
					for _, lag := range lags {
						if _, exists := newLagIds[lag]; !exists {
							newLagIds[lag] = struct{}{}
						}
					}
				}
			}
		}
		// 平台和微信标签映射
		if len(newLagIds) > 0 {
			wxLagIdsSet := make(map[string]string)
			wxLagIds, err := hookClient.GetContactLabelList()
			if err == nil {
				wxSysSet := make(map[string]uint64)
				for _, wxLagId := range wxLagIds.Label {
					wxLagIdsSet[wxLagId.Id] = wxLagId.Name
				}
				for lagId := range newLagIds {
					if lagId == "" {
						continue
					}
					name := wxLagIdsSet[lagId]
					label, err := l.svcCtx.DB.Label.Query().
						Where(
							label.NameEQ(name), // Filter by ID
							label.TypeEQ(1),
							label.OrganizationID(organizationId), // Additional filter by organizationId
						).
						Only(l.ctx)
					if err != nil {
						// 如果标签不存在则创建
						newLabel, err := l.svcCtx.DB.Label.Create().
							SetType(1).
							SetName(name).
							SetFrom(2).
							SetMode(2).
							SetConditions("{}").
							SetOrganizationID(organizationId).
							Save(l.ctx)
						if err == nil {
							wxSysSet[lagId] = newLabel.ID
						}
					} else {
						// 如果标签存在
						wxSysSet[lagId] = label.ID
					}
				}
				// 为新联系人打标签
				if len(newFriendIds) > 0 && len(newLagIds) > 0 {
					for id, lags := range newFriendIds {
						for _, lag := range lags {
							l.svcCtx.DB.LabelRelationship.Create().
								SetLabelID(wxSysSet[lag]).
								SetContactID(id).
								SetOrganizationID(organizationId).
								Save(l.ctx)
						}
					}
				}
			}
		}
		chatroomCnt := cast.ToInt(friendAndChatRoomList.CountChatroom)
		if chatroomCnt > 0 {
			for _, chatroom := range friendAndChatRoomList.Chatroom {
				l.svcCtx.DB.Contact.Create().
					SetWxWxid(wxInfo.Wxid).
					SetType(2).
					SetWxid(chatroom.Gid).
					SetNickname(chatroom.Gname).
					SetGid(chatroom.Gid).
					SetGname(chatroom.Gname).
					SetMarkname(chatroom.Markname).
					SetV3(chatroom.V3).
					SetOrganizationID(organizationId).
					OnConflict().
					UpdateNewValues().
					ID(l.ctx)
			}
		}

		ghCnt := cast.ToInt(friendAndChatRoomList.CountGh)
		if ghCnt > 0 {
			for _, gh := range friendAndChatRoomList.Gh {
				l.svcCtx.DB.Contact.Create().
					SetWxWxid(wxInfo.Wxid).
					SetType(3).
					SetWxid(gh.Wxid).
					SetAccount(gh.Account).
					SetNickname(gh.Nickname).
					SetMarkname(gh.Markname).
					SetV3(gh.V3).
					SetOrganizationID(organizationId).
					OnConflict().
					UpdateNewValues().
					ID(l.ctx)
			}
		}
	} else {
		// 工作手机版本
		hookClient := hook.NewHook("", "", "")
		var result GetWechatFriendListResp
		res, err := reqv3.C().DevMode().R().SetSuccessResult(&result).Post("http://chat.gkscrm.com:13086/pc/GetWechatFriendList?cid=" + wxInfo.ProcessID + "&wechatid=" + wxInfo.Wxid)
		if err != nil {
			return nil, err
		}
		if !res.IsSuccessState() {
			err = fmt.Errorf("GetFriendAndChatRoomList failed with status code %d", res.StatusCode)
			l.Error("GetWechatFriendList 请求失败", err)
			return nil, err
		}
		_ = hookClient.TriggerChatroomPush(wxInfo.Wxid)
		for _, friend := range result.Data {
			friendType := 1
			if friend.Type == 1 {
				friendType = 2
				_ = hookClient.RequestChatRoomInfo(friend.Friendid, wxInfo.Wxid)
			} else {
				friendType = 1
			}

			_, err = l.svcCtx.DB.Contact.Create().
				SetWxWxid(wxInfo.Wxid).
				SetType(friendType).
				SetWxid(friend.Friendid).
				SetAccount(friend.FriendWechatno).
				SetNickname(friend.Nickname).
				SetHeadimg(friend.Avatar).
				SetSex(cast.ToInt(friend.Gender)).
				SetOrganizationID(organizationId).
				OnConflict().
				UpdateNewValues().
				SetOrganizationID(organizationId).
				ID(l.ctx)

			if err != nil {
				l.Error("创建联系人失败", err)
				continue
			}
		}
	}

	resp = &types.BaseMsgResp{
		Msg:  errormsg.Success,
		Code: errorcode.OK,
	}

	return
}

func splitStringToIntArray(input string) []string {
	strArray := strings.Split(input, ",")
	intArray := make([]string, len(strArray))
	for i, str := range strArray {
		intArray[i] = str
	}
	return intArray
}
