package service

import (
	"go_dreamfactory/cmd/v2/lib/common"
	"go_dreamfactory/cmd/v2/service/observer"

	// "go_dreamfactory/modules/user"
	"go_dreamfactory/pb"
	"time"

	"github.com/sirupsen/logrus"
	"google.golang.org/protobuf/proto"
)

var (
	ptt PttService
)

type PttService interface {
	Login(sid, account string) (errdata *pb.ErrorData)
	CreateRole(nickName string, gender, figure int32) (errdata *pb.ErrorData)
	GetUser() *UserInfo
	SetUser(dbUser *pb.DBUser, dbUserExpand *pb.DBUserExpand)
	SendToClient(mainType, subType string, rsp proto.Message) error

	Ping(sid, account string)
}

type PttServiceImpl struct {
	connService ConnService
	user        *UserInfo
	obs         observer.Observer
}

type UserInfo struct {
	DbUser       *pb.DBUser
	DbUserExpand *pb.DBUserExpand
}

func NewPttService(connService ConnService, obs observer.Observer) PttService {
	ptt = &PttServiceImpl{
		connService: connService,
		obs:         obs,
	}
	return ptt
}

func GetPttService() PttService {
	return ptt
}

func (p *PttServiceImpl) GetUser() *UserInfo {
	return p.user
}

func (p *PttServiceImpl) SetUser(dbUser *pb.DBUser, dbUserExpand *pb.DBUserExpand) {
	p.user = &UserInfo{DbUser: dbUser, DbUserExpand: dbUserExpand}
}

func (p *PttServiceImpl) SendToClient(mainType, subType string, rsp proto.Message) (err error) {
	msg := &pb.UserMessage{MainType: mainType, SubType: subType}
	msg.Sec = common.BuildSecStr(p.user.DbUser.Sid, p.user.DbUser.Binduid)
	now := time.Now()
	if err = p.connService.SendMsg(msg, rsp); err != nil {
		logrus.WithField("发送错误:", err).Error(err)
		return err
	}
	p.obs.Notify(observer.EVENT_RST, now)
	return
}

// Login
func (p *PttServiceImpl) Login(sid, account string) (errdata *pb.ErrorData) {
	head := &pb.UserMessage{MainType: string("user"), SubType: "login"}
	head.Sec = common.BuildSecStr(sid, account)
	req := &pb.UserLoginReq{
		Account: account,
		Sid:     sid,
	}
	if err := p.connService.SendMsg(head, req); err != nil {
		errdata = &pb.ErrorData{
			Code: pb.ErrorCode_SystemError,
		}
		logrus.WithField("err", err).Error("Login")
		return
	}
	logrus.WithFields(logrus.Fields{common.MainType: string("user"), common.SubType: "login",
		common.Params: req}).Info("登录")
	return
}

func (p *PttServiceImpl) Ping(sid, account string) {
	defer func() {
		if err := recover(); err != nil {
			logrus.Errorf("Ping sid:%v account:%v err:%v", sid, account, err)
		}
	}()
	head := &pb.UserMessage{MainType: string("gateway"), SubType: "heartbeat"}
	head.Sec = common.BuildSecStr(sid, account)
	if err := p.connService.SendMsg(head, &pb.GatewayHeartbeatReq{}); err != nil {
		p.obs.Notify(observer.EVENT_PING, err)
		return
	}
	// logrus.Debug("Ping")
	return
}

// create role
func (p *PttServiceImpl) CreateRole(nickName string, gender, figure int32) (errdata *pb.ErrorData) {
	head := &pb.UserMessage{MainType: string("user"), SubType: "create"}
	head.Sec = common.BuildSecStr(p.user.DbUser.Sid, p.user.DbUser.Binduid)
	if err := p.connService.SendMsg(head, &pb.UserCreateReq{
		NickName: nickName,
		Figure:   figure,
		Gender:   gender,
	}); err != nil {
		errdata = &pb.ErrorData{
			Code: pb.ErrorCode_SystemError,
		}
		logrus.WithField("err", err).Error("CreateRole")
		return
	}
	return
}
