// Package ws -----------------------------
// @file      : handler.go
// @author    : JJXu
// @contact   : wavingbear@163.com
// @time      : 2022/10/23 11:13:43
// -------------------------------------------
package ws

import (
	"context"
	"encoding/json"
	"fmt"
	"fonchain-fiee/api/account"
	"fonchain-fiee/api/accountFiee"
	"fonchain-fiee/cmd/config"
	"fonchain-fiee/pkg/common/jwt"
	"fonchain-fiee/pkg/common/m"
	"fonchain-fiee/pkg/e"
	"fonchain-fiee/pkg/service"
	"fonchain-fiee/pkg/utils/secret"
)

func AuthorizationVerify(sourceData []byte) (userInfo *accountFiee.ChatUserData, ok bool, err error) {
	var msg AuthorizationInfo
	err = json.Unmarshal(sourceData, &msg)
	if err != nil {
		return
	}
	if msg.Type != AuthorizationType {
		return
	}
	if msg.Content.Auth == "" {
		return
	}
	var ctx = context.Background()
	var accountInfo accountFiee.ChatUserData
	switch msg.Content.Domain {
	case config.AppConfig.System.Domain:
		//fiee token校验
		var fieeJwtInfo *jwt.Claims
		fieeJwtInfo, err = jwt.ParseToken(msg.Content.Auth, m.JWTSecret)
		if err != nil {
			fmt.Printf("fiee token parse err:%v\n", err)
			return
		}
		fmt.Printf("fieeJwtInfo %#v\n", fieeJwtInfo)
		accountInfo.Origin = msg.Content.Domain
		accountInfo.OriginId = int64(fieeJwtInfo.ID)
		accountInfo.Account = fieeJwtInfo.Account
		accountInfo.NickName = fieeJwtInfo.NickName
		infoReq := &accountFiee.UserByTelRequest{
			Tel:    fieeJwtInfo.Phone,
			Domain: fieeJwtInfo.Domain,
		}
		var accInfo *accountFiee.UserInfoResponse
		accInfo, err = service.AccountFieeProvider.UserByTel(ctx, infoReq)
		if err != nil {
			fmt.Printf("err:%#v\n", err)
			return
		}
		if accInfo != nil {
			accountInfo.Account = accInfo.TelNum
			accountInfo.Avatar = accInfo.GroupPhoto
			if accInfo.Name != "" {
				accountInfo.NickName = accInfo.Name
			}
		}
	case e.ErpDomain:
		//erp token校验
		msg.Content.Auth, err = secret.GetJwtFromStr(msg.Content.Auth)
		if err != nil {
			return
		}
		msg.Content.Auth, err = secret.GetJwtFromStr(msg.Content.Auth)
		if err != nil {
			return
		}
		var fontreeJwtInfo *account.DecryptJwtResponse
		fontreeJwtInfo, err = service.AccountProvider.DecryptJwt(ctx, &account.DecryptJwtRequest{Token: msg.Content.Auth, Domain: msg.Content.Domain})
		if err != nil || fontreeJwtInfo.IsOffline {
			return
		}
		fmt.Printf("fontreeJwtInfo is %#v\n", fontreeJwtInfo)
		accountInfo.Origin = msg.Content.Domain
		accountInfo.OriginId = int64(fontreeJwtInfo.ID)
		accountInfo.Account = fontreeJwtInfo.Account
		accountInfo.NickName = fontreeJwtInfo.NickName
	}

	//查询是否已经注册
	var chatUserQuery *accountFiee.GetChatUserListResp
	chatUserQuery, err = service.AccountFieeProvider.GetChatUserList(ctx, &accountFiee.GetChatUserListRequest{
		Query:    &accountFiee.ChatUserData{OriginId: accountInfo.OriginId, Origin: msg.Content.Domain},
		Page:     1,
		PageSize: 1,
	})
	//如果找不到聊天用户则创建
	if err != nil || chatUserQuery.Total == 0 {
		//注册客服
		var createUserRes *accountFiee.CreateChatUserResp
		var createChatUserReq = &accountFiee.ChatUserData{
			NickName: accountInfo.NickName,
			Account:  accountInfo.Account,
			Role:     1,
			Origin:   msg.Content.Domain,
			OriginId: accountInfo.OriginId,
		}
		if msg.Content.Domain == e.ErpDomain {
			createChatUserReq.Role = 2
		}
		createUserRes, err = service.AccountFieeProvider.CreateChatUser(ctx, createChatUserReq)
		if err != nil {
			return
		}
		userInfo = createUserRes.GetData()
		fmt.Printf("注册聊天用户:%#v\n", userInfo)
	} else {
		userInfo = chatUserQuery.List[0]
		if msg.Content.Domain == config.AppConfig.System.Domain && (accountInfo.NickName != userInfo.NickName || accountInfo.Account != userInfo.Account || accountInfo.Avatar != userInfo.Avatar) {
			_, _ = service.AccountFieeProvider.UpdateChatUser(ctx, &accountFiee.ChatUserData{
				NickName: accountInfo.NickName,
				ID:       userInfo.ID,
				Account:  accountInfo.Account,
				Avatar:   accountInfo.Avatar,
			})
			userInfo.NickName = accountInfo.NickName
			userInfo.Account = accountInfo.Account
			userInfo.Avatar = accountInfo.Avatar
		}
		fmt.Printf("获取聊天用户:%#v\n", userInfo)
	}
	ok = true
	return
}
func HandleMessage(sourceData []byte, cli *Client) {
	var msg WsInfo
	err := json.Unmarshal(sourceData, &msg)
	if err != nil {
		cli.Send <- WsErrorInvalidDataFormat(msg.From)
		return
	}
	switch msg.Type {
	default:
		cli.Send <- WsErrorUnknownMessageType(msg.From)
	case TestType:
		var newMsg = WsInfo{
			Type:    TestType,
			Content: msg.Content,
			From:    "0",
			To:      msg.From,
		}
		byteMsg, _ := json.Marshal(newMsg)
		cli.Send <- byteMsg
	case ChatType:
		if msg.From == "" {
			//客户端id不能为空
			cli.Send <- WsErrorMessage(ChatType, "null", e.ErrInvalidClientId, nil)
			return
		}
		var chatInfo ChatInfo
		_ = json.Unmarshal(sourceData, &chatInfo)
		//解析Content
		if clients, ok := cli.Room.clients[chatInfo.Content.TargetUserId]; ok {
			for _, targetObj := range clients {
				if targetObj != nil {
					targetObj.Send <- WsChatMessage(msg.From, chatInfo.Content.TargetClientId, chatInfo.Content.Msg)
				}
			}
		} else {
			//对方不在线
			cli.Send <- WsErrorMessage(ChatType, msg.From, e.ErrTargetOutLine, nil)
		}
	}
}

type ChatInfo struct {
	Type    WsType      `json:"type"`    //消息类型
	Content ChatContent `json:"content"` //消息内容
	From    string      `json:"from"`    //发送者 0为服务端,客户端填写clientId
	To      string      `json:"to"`      //接收者 接收消息的用户id
}
type ChatContent struct {
	TargetUuid     string `json:"targetUuid"`
	TargetUserId   int64  `json:"targetUserId"`
	TargetClientId string `json:"targetClientId"`
	Msg            string `json:"msg"`
}