package noble_s

import (
	"git.hilo.cn/hilo-common/domain"
	"git.hilo.cn/hilo-common/mycontext"
	"git.hilo.cn/hilo-common/resource/mysql"
	"hilo-user/_const/enum/headwear_e"
	"hilo-user/_const/enum/msg_e"
	"hilo-user/_const/enum/property_e"
	"hilo-user/domain/model/msg_m"
	"hilo-user/domain/model/noble_m"
	"hilo-user/domain/model/user_m"
	"hilo-user/myerr"
	"hilo-user/myerr/bizerr"
	"strconv"
	"time"
)

type NobleService struct {
	svc *domain.Service
}

func NewNobleService(myContext *mycontext.MyContext) *NobleService {
	svc := domain.CreateService(myContext)
	return &NobleService{svc}
}

// 下发贵族
func (s *NobleService) SendNoble(receiverUserId mysql.ID, level uint16, days int) error {
	model := domain.CreateModelContext(s.svc.MyContext)

	if level <= 0 {
		return bizerr.InvalidParameter
	}

	cfg, err := noble_m.GetConfigByLevel(model.Db, level)
	if err != nil {
		return err
	}
	if cfg.PurchasePrice <= 0 || cfg.RenewalPrice <= 0 {
		return bizerr.InvalidParameter
	}
	n := noble_m.UserNoble{UserId: receiverUserId, Level: level}
	records, err := n.FindAll(model.Db)
	if err != nil {
		return err
	}
	if len(records) > 1 {
		// DB表结构决定了不可能发生
		return bizerr.IncorrectState
	}

	if len(records) <= 0 {
		// 新增贵族
		endTime := time.Now().AddDate(0, 0, int(days))
		n = noble_m.UserNoble{UserId: receiverUserId, Level: level, EndTime: endTime}
		err = n.Create(model.Db)
		if err != nil {
			return err
		}

		nbl := noble_m.UserNobleLog{
			SenderId:   0,
			ReceiverId: receiverUserId,
			Level:      level,
			Money:      0,
			SrcType:    noble_m.SRC_APP,
			NewEndTime: endTime,
		}
		err = nbl.Create(model.Db)
		if err != nil {
			return err
		}
	} else {
		// 延长贵族
		n = records[0]
		now := time.Now()
		endTime := n.EndTime.AddDate(0, 0, int(days))
		if now.After(n.EndTime) {
			endTime = now.AddDate(0, 0, int(days))
		}
		nn := noble_m.UserNoble{
			Entity: mysql.Entity{ID: n.ID, UpdatedTime: n.UpdatedTime},
		}

		af, err := nn.UpdateEndTime(model.Db, endTime)
		if err != nil {
			return err
		}
		if af <= 0 {
			return bizerr.TransactionFailed
		}

		nbl := noble_m.UserNobleLog{
			SenderId:   0,
			ReceiverId: receiverUserId,
			Level:      level,
			Money:      0,
			SrcType:    noble_m.SRC_APP,
			OldEndTime: n.EndTime,
			NewEndTime: endTime,
		}
		err = nbl.Create(model.Db)
		if err != nil {
			return err
		}
	}
	// 头饰增加
	receiveHeadwearDuration := uint32(days) * 3600 * 24
	if cfg.HeaddressId != 0 {
		userHeadwear, err := user_m.GetUserHeadwearOrInit(model, receiverUserId, cfg.HeaddressId)
		if err != nil {
			return err
		}
		nowTime := time.Now()
		if userHeadwear.EndTime.After(nowTime) {
			nowTime = userHeadwear.EndTime
		}
		userHeadwear.EndTime = nowTime.Add(time.Duration(receiveHeadwearDuration) * time.Second)
		if err := userHeadwear.Persistent(); err != nil {
			return err
		}
		//日志错误,并不事务回调
		if _, err := addUserHeadwearLog(model, receiverUserId, cfg.HeaddressId, headwear_e.ActivityTrigger, headwear_e.AddSecond, &receiveHeadwearDuration, nil, 0); err != nil {
			model.Log.Error(err)
		}
	}
	// 增加座驾
	receivePropertyDuration := uint32(days) * 3600 * 24
	if cfg.RideId != 0 {
		userProperty, err := user_m.GetUserPropertyOrInit(model, receiverUserId, cfg.RideId)
		if err != nil {
			return err
		}
		nowTime := time.Now()
		if userProperty.EndTime.After(nowTime) {
			nowTime = userProperty.EndTime
		}
		userProperty.EndTime = nowTime.Add(time.Duration(receivePropertyDuration) * time.Second)
		if err := userProperty.Persistent(); err != nil {
			return err
		}
		//日志错误,并不事务回调
		if err := (&user_m.UserPropertyLog{
			Model:         model,
			UserId:        receiverUserId,
			PropertyId:    cfg.RideId,
			OriginType:    property_e.ActivityBillboardTrigger,
			Type:          property_e.AddSecond,
			AddSecond:     &receivePropertyDuration,
			UpdateEndTime: nil,
		}).Persistent(); err != nil {
			model.Log.Error(err)
		}
	}
	// 推送
	user, err := user_m.GetUser(model, receiverUserId)
	if err != nil {
		return err
	}
	nobleDuration := days * 3600 * 24
	if err := msg_m.NewUserRecord(model, user.ID, msg_e.AddNoble, user.Nick, user.ID, "", strconv.Itoa(int(nobleDuration)/(24*3600)), "", "", "").Persistent(); err != nil {
		return err
	}
	msg_m.SendEmasMsgAssistant(model, user.ExternalId, user.DeviceType)
	return nil
}

//增加修改日志
func addUserHeadwearLog(model *domain.Model, userId mysql.ID, headwearId mysql.ID, originType headwear_e.UserHeadwearLogOrginType, t headwear_e.UserHeadwearLogType, addSecond *uint32, UpdateEndTime *time.Time, operateUserId mysql.ID) (mysql.ID, error) {
	userHeadwearLog := user_m.UserHeadwearLog{
		UserId:        userId,
		OperateUserId: operateUserId,
		HeadwearId:    headwearId,
		OriginType:    originType,
		Type:          t,
		AddSecond:     addSecond,
		UpdateEndTime: UpdateEndTime,
	}
	if err := model.Db.Create(&userHeadwearLog).Error; err != nil {
		return 0, myerr.WrapErr(err)
	}
	return userHeadwearLog.ID, nil
}