package gift_m

import (
	"git.hilo.cn/hilo-common/domain"
	"git.hilo.cn/hilo-common/resource/mysql"
	"gorm.io/gorm"
	"hilo-group/_const/enum/gift_e"
	"hilo-group/domain/model/res_m"
	"hilo-group/myerr"
	"time"
)

/**
 * 礼物操作
 **/
type GiftOperate struct {
	mysql.Entity
	*domain.Model      `gorm:"-"`
	ResGiftId          mysql.ID
	GiftN              mysql.Num
	SendUserId         mysql.ID
	ReceiveUserId      mysql.ID
	SendUserDiamond    mysql.Num
	ReceiveUserDiamond mysql.Num
	ReceiveUserBean    mysql.Num
	SceneType          gift_e.GiftOperateSceneType
	SceneUid           mysql.Str
}

// 用户收取礼物分类统计(for 礼物墙)
type GiftCountUser struct {
	mysql.Entity
	*domain.Model `gorm:"-"`
	UserId        mysql.ID
	ResGiftId     mysql.ID
	Num           mysql.Num
	addNum        mysql.Num `gorm:"-"`
}

/**
 * 送礼物
 **/
func SendGift(model *domain.Model, giftId mysql.ID, giftN mysql.Num, sendUserId mysql.ID, receiveUserId mysql.ID, sceneType gift_e.GiftOperateSceneType, sceneUid mysql.Str) (*GiftOperate, *res_m.ResGift, error) {
	resGift, err := res_m.GetGiftWithValid(model, giftId)
	if err != nil {
		return nil, nil, err
	}
	return &GiftOperate{
		Model:              model,
		ResGiftId:          giftId,
		GiftN:              giftN,
		SendUserId:         sendUserId,
		ReceiveUserId:      receiveUserId,
		SendUserDiamond:    resGift.DiamondNum * giftN,
		ReceiveUserDiamond: resGift.ReceiveDiamondNum * giftN,
		ReceiveUserBean:    resGift.BeanNum * giftN,
		SceneType:          sceneType,
		SceneUid:           sceneUid,
	}, resGift, nil
}

func GetCountGiftOperateByDay(model *domain.Model, userId uint64, beginTime, endTime time.Time) (int64, error) {
	var n int64 = 0
	if err := model.Db.Model(&GiftOperate{}).Where(&GiftOperate{
		SendUserId: userId,
	}).Where("created_time >= ? and created_time <= ?", beginTime, endTime).Distinct("Receive_User_Id").Count(&n).Error; err != nil {
		return 0, err
	}
	return n, nil
}

func GetGiftSummaryByDay(userId uint64, sceneType gift_e.GiftOperateSceneType, beginTime, endTime time.Time) (map[string]uint64, error) {
	c := GiftOperate{ReceiveUserId: userId, SceneType: sceneType}
	type summary struct {
		Date string
		Sum  uint64
	}
	records := make([]summary, 0)
	err := mysql.Db.Model(&GiftOperate{}).
		Select("DATE_FORMAT(created_time, '%Y-%m-%d') AS date, SUM(receive_user_bean) AS sum").
		Where(c).Where("created_time BETWEEN ? AND ?", beginTime, endTime).
		Group("date").Find(&records).Error
	if err != nil {
		return nil, err
	}
	result := make(map[string]uint64, len(records))
	for _, i := range records {
		result[i.Date] = i.Sum
	}
	return result, err
}

func GetGiftAllSummaryByDay(userId uint64, beginTime, endTime time.Time) (map[string]uint64, error) {
	c := GiftOperate{ReceiveUserId: userId}
	type summary struct {
		Date string
		Sum  uint64
	}
	records := make([]summary, 0)
	err := mysql.Db.Model(&GiftOperate{}).
		Select("DATE_FORMAT(created_time, '%Y-%m-%d') AS date, SUM(receive_user_bean) AS sum").
		Where(c).Where("created_time BETWEEN ? AND ?", beginTime, endTime).
		Group("date").Find(&records).Error
	if err != nil {
		return nil, err
	}
	result := make(map[string]uint64, len(records))
	for _, i := range records {
		result[i.Date] = i.Sum
	}
	return result, err
}

func (g *GiftOperate) GetConsumeByRange(beginTime, endTime time.Time) (uint32, uint64, error) {
	type summary struct {
		C       uint32
		Consume uint64
	}
	rows := make([]summary, 0)
	err := g.Db.Model(g).
		Select("COUNT(DISTINCT(send_user_id)) AS c, SUM(send_user_diamond) AS Consume").
		Where(g).Where("created_time BETWEEN ? AND ?", beginTime, endTime).
		Find(&rows).Error
	if err != nil {
		return 0, 0, err
	}
	if len(rows) <= 0 {
		return 0, 0, nil
	}

	//if beginTime.Unix() >= 1691337600 && beginTime.Unix() < 1691942400 { // 因为这周水果机被部分人刷币,所以这里做了特殊的处理
	//	reduceMap := map[string]uint64{
	//		"HTGS#a63226380": 20000000,
	//		//"HTGS#a42641278": 10000000,
	//		"@TGS#3ZZ5GZLHA": 27141539,
	//		"HTGS#a81630128": 8955410,
	//		"HTGS#a42300598": 50211301,
	//		"HTGS#a40088696": 10000000,
	//		"HTGS#a21700997": 14352310,
	//		"HTGS#a83608384": 49644203,
	//		"@TGS#33GDXTSIH": 50000000,
	//		"HTGS#a50538513": 15000000,
	//		"HTGS#a77282385": 15000000,
	//		"HTGS#a59437326": 10000000,
	//		"HTGS#a16909405": 10000000,
	//		"HTGS#a44104431": 16861206,
	//		"HTGS#a56794634": 59591313,
	//		"HTGS#a11286025": 31232311,
	//		"HTGS#a17238550": 52309338,
	//		"HTGS#a83592361": 79545067,
	//		"HTGS#a39882521": 10255093,
	//	}
	//	if reduceNum, ok := reduceMap[g.SceneUid]; ok {
	//		if g.Log != nil {
	//			g.Log.Infof("fruit diamond reduceMap,groupId:%v,reduceNum:%v", g.SceneUid, reduceNum)
	//		}
	//		if rows[0].Consume >= reduceNum {
	//			rows[0].Consume -= reduceNum
	//		} else {
	//			rows[0].Consume = 0
	//		}
	//	}
	//}
	return rows[0].C, rows[0].Consume, nil
}

type SceneConsumeSummary struct {
	SceneUid string
	C        uint32
	Consume  uint64
}

func (g *GiftOperate) BatchGetConsumeByRange(beginTime, endTime time.Time) ([]SceneConsumeSummary, error) {
	rows := make([]SceneConsumeSummary, 0)
	err := g.Db.Model(g).
		Select("scene_uid, COUNT(DISTINCT(send_user_id)) AS c, SUM(send_user_diamond) AS Consume").
		Where(g).Where("created_time BETWEEN ? AND ?", beginTime, endTime).
		Group("scene_uid").Find(&rows).Error
	if err != nil {
		return nil, err
	}
	return rows, nil
}

func (g *GiftOperate) BatchGetSupportList(beginTime, endTime time.Time) ([]uint64, error) {
	userIds := make([]uint64, 0)
	err := g.DB().Model(g).
		Select("DISTINCT(send_user_id) AS user_id").
		Where(g).Where("created_time BETWEEN ? AND ?", beginTime, endTime).Pluck("user_id", &userIds).Error
	if err != nil {
		return nil, err
	}
	return userIds, nil
}

func SumSendGift(model *domain.Model, sendUserId mysql.ID, giftId mysql.ID) (uint32, error) {
	type Result struct {
		N uint32
	}
	sum := Result{}
	if err := model.Db.Raw("SELECT SUM(o.gift_n) as n from gift_operate o where o.send_user_id = ? and o.res_gift_id = ?", sendUserId, giftId).Scan(&sum).Error; err != nil {
		return 0, myerr.WrapErr(err)
	} else {
		return sum.N, nil
	}
}

type GiftPrivateRecord struct {
	mysql.Entity
	ResGiftId     mysql.ID
	GiftN         mysql.Num
	DiamondNum    mysql.Num
	SendUserId    mysql.ID
	ReceiveUserId mysql.ID
	RefId         mysql.ID                     //其实就是diamondSendAccountDetailId
	OriginType    gift_e.GiftPrivateRecordType //来源类型
	OriginId      mysql.ID                     //来源ID
}

func (gpr *GiftPrivateRecord) Create(db *gorm.DB) error {
	return db.Create(gpr).Error
}

func (gpr *GiftPrivateRecord) Find(db *gorm.DB) ([]GiftPrivateRecord, error) {
	rows := make([]GiftPrivateRecord, 0)
	if err := db.Where(gpr).Order("created_time DESC").Find(&rows).Error; err != nil {
		return nil, err
	}
	return rows, nil
}

func (gpr *GiftPrivateRecord) Remove(db *gorm.DB) (int64, error) {
	result := db.Delete(gpr)
	return result.RowsAffected, result.Error
}

func GetGiftOperate(resGift *res_m.ResGift, giftId mysql.ID, giftN mysql.Num, sendUserId mysql.ID,
	receiveUserId mysql.ID, sceneType gift_e.GiftOperateSceneType, sceneUid mysql.Str) *GiftOperate {
	return &GiftOperate{
		ResGiftId:          giftId,
		GiftN:              giftN,
		SendUserId:         sendUserId,
		ReceiveUserId:      receiveUserId,
		SendUserDiamond:    resGift.DiamondNum * giftN,
		ReceiveUserDiamond: resGift.ReceiveDiamondNum * giftN,
		ReceiveUserBean:    resGift.BeanNum * giftN,
		SceneType:          sceneType,
		SceneUid:           sceneUid,
	}
}