package main

import (
	"../log"
	"../mod"
	pb "../protos"
	"../utils"
	"encoding/json"
	"go.uber.org/zap"
	"time"
)

type UserCheckin30 struct {
	Vip int32
	Daily *pb.CheckinItem
	TotalTimes int64 	// 历史总签到次数
	TotalReward int64 	// 历史总领取金额 (分)
	Ext []*pb.CheckinItem 	// 额外奖励
}

func NewUserCheckin30() *UserCheckin30 {
	uc := &UserCheckin30{
		Daily: new(pb.CheckinItem),
	}

	// TODO: uc.Ext 可配置
	uc.Ext = append(uc.Ext, &pb.CheckinItem{
		Bonus:                600,
		Got:                  int32(pb.RewardStatus_NOTYET),
		Ts:                   0,
		Days:                 2,
	})
	uc.Ext = append(uc.Ext, &pb.CheckinItem{
		Bonus:                800,
		Got:                  int32(pb.RewardStatus_NOTYET),
		Ts:                   0,
		Days:                 3,
	})
	uc.Ext = append(uc.Ext, &pb.CheckinItem{
		Bonus:                1800,
		Got:                  int32(pb.RewardStatus_NOTYET),
		Ts:                   0,
		Days:                 7,
	})
	uc.Ext = append(uc.Ext, &pb.CheckinItem{
		Bonus:                2800,
		Got:                  int32(pb.RewardStatus_NOTYET),
		Ts:                   0,
		Days:                 15,
	})
	uc.Ext = append(uc.Ext, &pb.CheckinItem{
		Bonus:                5800,
		Got:                  int32(pb.RewardStatus_NOTYET),
		Ts:                   0,
		Days:                 30,
	})
	return uc
}

func (self *UserCheckin30) Saveback(guid uint64) error {
	bytes, err := json.Marshal(self)
	if err != nil {
		return err
	}

	return mod.UpdateCheckin30Status(guid, string(bytes))
}


func GetCheckin30Status(guid uint64) (*UserCheckin30, pb.ErrCode) {
	s, err := mod.GetUserCheckin30Status(guid)
	if err != nil {
		log.Error("GetCheckin30Status", zap.Uint64("guid", guid), zap.Error(err))
		return nil, pb.ErrCode_FAILED
	}

	status := &UserCheckin30{}
	if len(s) <= 0 {
		// 初始化
		status = NewUserCheckin30()
	} else {
		// parse
		err = json.Unmarshal([]byte(s), status)
		if nil != err {
			log.Error("GetCheckin30Status", zap.Uint64("guid", guid), zap.Error(err))
			return nil, pb.ErrCode_FAILED
		}
	}
	vip, err := get_user_vip(guid)
	if err != nil {
		log.Error("GetCheckin30Status", zap.Uint64("guid", guid), zap.Error(err))
		return nil, pb.ErrCode_FAILED
	}
	status.Vip = int32(vip)
	status.Daily.Bonus = int64(vip) * 100

	now := time.Now().Unix()
	diff := utils.DiffDays(status.Daily.Ts, now)

	need_save := false

	if diff <= 0 {
		status.Daily.Got = int32(pb.RewardStatus_GOTTEN)
	} else {
		status.Daily.Got = int32(pb.RewardStatus_INREADY)

		// 重置条件
		if diff > 1 /* || status.Daily.Days >= 30 */ {
			status.Daily.Days = 0
			// save back
			need_save = true
		}
	}

	// 实时调整状态
	for i := 0; i < len(status.Ext); i ++ {
		if status.Daily.Days >= status.Ext[i].Days &&
			status.Ext[i].Got == int32(pb.RewardStatus_NOTYET) {
			status.Ext[i].Got = int32(pb.RewardStatus_INREADY)
			need_save = true
		}
	}

	if need_save {
		err := status.Saveback(guid)
		if nil != err {
			log.Error("GetCheckin30Status", zap.Uint64("guid", guid), zap.Error(err))
			return nil, pb.ErrCode_FAILED
		}
	}

	return status, pb.ErrCode_OK
}

