package service

import (
	"encoding/json"
	"errors"
	"fengkuangGameServerJob/dao"
	"fengkuangGameServerJob/pkg/util"
	"fmt"
	"time"
)

// NotifyService 消息通知
type NotifyService struct {
}

func NewNotifyService() *NotifyService {
	return &NotifyService{}
}

// GetPlayerRealTcpId 获取用户真实的TCP_ID(跨服合服了)
func (n *NotifyService) GetPlayerRealTcpId(playerId int) (int, error) {
	// 找出玩家对应的区服信息
	tcpInfo := dao.FindTcpInfoByPlayerId(playerId)
	if tcpInfo.TcpId == 0 {
		return 0, errors.New("未获取到用户的TCP_ID")
	}
	if tcpInfo.CrossId > 0 {
		//获取跨服对应的tcp信息,若当前跨服设置了tcp信息，则使用跨服的tcp信息
		crossTcp := dao.GetTcpByCrossId(tcpInfo.CrossId)
		if crossTcp.TcpId > 0 {
			return crossTcp.TcpId, nil
		}
	}
	return tcpInfo.TcpId, nil
}

// OrderPaid 订单支付成功后写入有序集合中
func (n *NotifyService) OrderPaid(orderSn string, playerId int) error {
	//1 参数基础校验
	if playerId <= 0 {
		return errors.New("玩家ID信息不正确")
	}
	if orderSn == "" {
		return errors.New("订单号信息不正确")
	}
	//2 获取玩家所在区服的tcpId
	//tcpId, err := dao.FindTcpIdByPlayerId(playerId)
	tcpId, err := n.GetPlayerRealTcpId(playerId)
	if err != nil {
		return err
	}
	//3 支付完成的订单写入定时任务中
	//3.1 任务标识
	tokenSign := fmt.Sprintf("%d_%s", playerId, orderSn)
	//3.2 json任务内容
	//任务的详细内容
	contentMap := map[string]interface{}{
		"player_id": playerId,
		"event":     "order",
		"body":      orderSn,
	}
	cByte, _ := json.Marshal(&contentMap)
	finalContentMap := map[string]interface{}{
		tokenSign: string(cByte),
	}
	//3.3 写入redis
	pipeTx := dao.Redis().TxPipeline()
	//增加任务的过期时间
	dao.AddZSetMsg(pipeTx, tcpId, tokenSign)
	//任务标识与任务内容写入hash
	dao.AddHashMsg(pipeTx, tcpId, finalContentMap)
	_, err = pipeTx.Exec()
	return err
}

// PackIconFin 弹出礼包icon结束通知
func (n *NotifyService) PackIconFin(packRecordId, playerId int) error {
	msg := fmt.Sprintf(`{"id":%d}`, packRecordId)
	msg = util.QuoteConversion(msg)
	return AddSingleRealTimeMsg("pack_icon", msg, playerId)
}

// AddSingleRealTimeMsg 添加单个消息到实时消息队列
func AddSingleRealTimeMsg(event, msgBody string, playerId int) (err error) {
	msg := RealTimeMsg{
		Event:    event,
		Body:     msgBody,
		PlayerId: playerId,
		Unix:     time.Now().Unix(),
	}
	msgByte, _ := json.Marshal(msg)
	pipeTx := dao.Redis().TxPipeline()
	dao.AddRealTimeMsg(pipeTx, string(msgByte))
	_, err = pipeTx.Exec()
	return
}

// ResourceChangeLog ResourceChange 资源变动日志
type ResourceChangeLog struct {
	PlayerId             int    `json:"player_id"`
	ResourceId           int    `json:"resource_id"`
	ResourceAmountChange int    `json:"resource_amount_change"`
	ResourceAmountLater  int    `json:"resource_amount_later"`
	ResourceAmountBefore int    `json:"resource_amount_before"`
	ChangeType           string `json:"change_type"`
	Remark               string `json:"remark"`
	Date                 int    `json:"date"`
	CreatedAt            string `json:"created_at"`
}

type RealTimeLog struct {
	PlayerId int       `json:"player_id"` //玩家ID
	CmdId    int       `json:"cmd_id"`    //协议id
	Date     time.Time `json:"date"`      //时间
}

// RealTimeMsg 实时消息推送
type RealTimeMsg struct {
	Event    string `json:"event"`
	Body     string `json:"body"`
	PlayerId int    `json:"player_id"` //玩家ID=0则为广播事件
	Unix     int64  `json:"unix"`
}

// ArenaRewardGain 竞技场奖励是否可领取
type ArenaRewardGain struct {
	Day  uint8 `json:"day"`
	Week uint8 `json:"week"`
}

// ArenaStatus 竞技场的状态
type ArenaStatus struct {
	Open uint8 `json:"open"`
}

// OrderInfo 订单信息
type OrderInfo struct {
	OrderSn string `json:"order_sn"`
}
