package property_cv

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

type CvProperty struct {
	Id             uint64    `json:"id"`
	PicUrl         mysql.Str `json:"picUrl"`
	EffectUrl      mysql.Str `json:"effectUrl"`
	Using          bool      `json:"using"`
	TimeLeft       int64     `json:"timeLeft"` // 离到期还有多少秒(过期则是负数)
	SenderAvatar   string    `json:"senderAvatar"`
	ReceiverAvatar string    `json:"receiverAvatar"`
}

type CvPropertyDiamond struct {
	Id         uint64 `json:"id"`
	PicUrl     string `json:"picUrl"`
	EffectUrl  string `json:"effectUrl"`
	DiamondNum uint32 `json:"diamondNum"`
	Second     uint32 `json:"second"`
	Days       string `json:"days"`
}

func GetCvPropertyDiamond(pageSize int, pageIndex int) ([]CvPropertyDiamond, error) {
	propertyDiamonds := []CvPropertyDiamond{}
	if err := mysql.Db.Raw("select d.id, r.pic_url, r.effect_url, d.`second`, d.diamond_num from res_property r, res_property_diamond d where r.id = d.res_property_id and d.`status` = ? ORDER BY d.diamond_num ASC LIMIT ?, ?", mysql.USER, (pageIndex-1)*pageSize, pageSize).Scan(&propertyDiamonds).Error; err != nil {
		return nil, myerr.WrapErr(err)
	}
	for i, _ := range propertyDiamonds {
		propertyDiamonds[i].Days = strconv.FormatUint(uint64(propertyDiamonds[i].Second/(24*60*60)), 10)
	}
	return propertyDiamonds, nil
}

func GetPropertyById(resPropertyId mysql.ID) (CvProperty, error) {
	resProperty := res_m.ResProperty{}
	if err := mysql.Db.Model(&res_m.ResProperty{}).First(&resProperty, resPropertyId).Error; err != nil {
		return CvProperty{}, err
	}

	//获取座驾头像
	propertieAvatarMap, err := (&res_m.ResPropertyAvatar{}).GetAll(mysql.Db)
	if err != nil {
		return CvProperty{}, err
	}

	userIds := []uint64{}
	for _, value := range propertieAvatarMap {
		if value.SendUserId > 0 {
			userIds = append(userIds, value.SendUserId)
		}
		if value.ReceiverUserId > 0 {
			userIds = append(userIds, value.ReceiverUserId)
		}
	}
	//获取用户信息
	users := []user_m.User{}
	if err := mysql.Db.Model(&user_m.User{}).Where("id in (?)", userIds).Find(&users).Error; err != nil {
		return CvProperty{}, myerr.WrapErr(err)
	}
	userAvatarMap := map[mysql.ID]string{}
	for _, r := range users {
		userAvatarMap[r.ID] = r.Avatar
	}
	var senderAvatar string = ""
	var receiverAvatar string = ""

	if propertieAvatar, flag := propertieAvatarMap[resProperty.ID]; flag {
		if propertieAvatar.SendUserId > 0 {
			if avatar, flag := userAvatarMap[propertieAvatar.SendUserId]; flag {
				senderAvatar = avatar
			}
		}
		if propertieAvatar.ReceiverUserId > 0 {
			if avatar, flag := userAvatarMap[propertieAvatar.ReceiverUserId]; flag {
				receiverAvatar = avatar
			}
		}
	}
	return CvProperty{
		Id:             resProperty.ID,
		PicUrl:         resProperty.PicUrl,
		EffectUrl:      resProperty.EffectUrl,
		SenderAvatar:   senderAvatar,
		ReceiverAvatar: receiverAvatar,
	}, nil
}

func GetPropertyAll(db *gorm.DB) (map[uint64]CvProperty, error) {
	rp := res_m.ResProperty{}
	properties, err := rp.GetAll(mysql.Db)
	if err != nil {
		return nil, err
	}

	//获取座驾头像
	propertieAvatarMap, err := (&res_m.ResPropertyAvatar{}).GetAll(mysql.Db)

	userIds := []uint64{}
	for _, value := range propertieAvatarMap {
		if value.SendUserId > 0 {
			userIds = append(userIds, value.SendUserId)
		}
		if value.ReceiverUserId > 0 {
			userIds = append(userIds, value.ReceiverUserId)
		}
	}
	//获取用户信息
	users := []user_m.User{}
	if err := db.Model(&user_m.User{}).Where("id in (?)", userIds).Find(&users).Error; err != nil {
		return nil, myerr.WrapErr(err)
	}
	userAvatarMap := map[mysql.ID]string{}
	for _, r := range users {
		userAvatarMap[r.ID] = r.Avatar
	}

	result := map[uint64]CvProperty{}
	for _, r := range properties {

		var senderAvatar string = ""
		var receiverAvatar string = ""
		if propertieAvatar, flag := propertieAvatarMap[r.ID]; flag {
			if propertieAvatar.SendUserId > 0 {
				if avatar, flag := userAvatarMap[propertieAvatar.SendUserId]; flag {
					senderAvatar = avatar
				}
			}
			if propertieAvatar.ReceiverUserId > 0 {
				if avatar, flag := userAvatarMap[propertieAvatar.ReceiverUserId]; flag {
					receiverAvatar = avatar
				}
			}
		}

		result[r.ID] = CvProperty{
			Id:             r.ID,
			PicUrl:         r.PicUrl,
			EffectUrl:      r.EffectUrl,
			SenderAvatar:   senderAvatar,
			ReceiverAvatar: receiverAvatar,
		}
	}
	return result, nil
}

func GetPropertyList(db *gorm.DB, userId uint64) ([]CvProperty, error) {
	rows := make([]user_m.UserProperty, 0)
	if err := db.Where(&user_m.UserProperty{
		UserId: userId,
	}).Order("`using` DESC, updated_time DESC").Find(&rows).Error; err != nil {
		return nil, err
	}
	rp := res_m.ResProperty{}
	properties, err := rp.GetAll(mysql.Db)
	if err != nil {
		return nil, err
	}

	//获取座驾头像
	propertieAvatarMap, err := (&res_m.ResPropertyAvatar{}).GetAll(mysql.Db)

	userIds := []uint64{}
	for _, value := range propertieAvatarMap {
		if value.SendUserId > 0 {
			userIds = append(userIds, value.SendUserId)
		}
		if value.ReceiverUserId > 0 {
			userIds = append(userIds, value.ReceiverUserId)
		}
	}
	//获取用户信息
	users := []user_m.User{}
	if err := db.Model(&user_m.User{}).Where("id in (?)", userIds).Find(&users).Error; err != nil {
		return nil, myerr.WrapErr(err)
	}
	userAvatarMap := map[mysql.ID]string{}
	for _, r := range users {
		userAvatarMap[r.ID] = r.Avatar
	}

	result := make([]CvProperty, 0)
	now := time.Now()
	hasUsing := false
	for _, i := range rows {
		//  TODO: 没过期并且有设置using的,才算是,因为写入方不维护using状态的更新
		isUsing := i.Using == headwear_e.YesUsing && i.EndTime.After(now)
		var senderAvatar string = ""
		var receiverAvatar string = ""
		if propertieAvatar, flag := propertieAvatarMap[i.PropertyId]; flag {
			if propertieAvatar.SendUserId > 0 {
				if avatar, flag := userAvatarMap[propertieAvatar.SendUserId]; flag {
					senderAvatar = avatar
				}
			}
			if propertieAvatar.ReceiverUserId > 0 {
				if avatar, flag := userAvatarMap[propertieAvatar.ReceiverUserId]; flag {
					receiverAvatar = avatar
				}
			}
		}
		result = append(result, CvProperty{
			Id:             i.PropertyId,
			PicUrl:         properties[i.PropertyId].PicUrl,
			EffectUrl:      properties[i.PropertyId].EffectUrl,
			Using:          isUsing,
			TimeLeft:       i.EndTime.Unix() - now.Unix(),
			SenderAvatar:   senderAvatar,
			ReceiverAvatar: receiverAvatar,
		})
		if isUsing {
			hasUsing = true
		}
	}
	// 如果没有一个using,则找第一个没过期的充当
	if !hasUsing {
		for i, e := range result {
			if e.TimeLeft > 0 {
				result[i].Using = true
				break
			}
		}
	}
	return result, nil
}

type PropertyExt struct {
	Id             uint64
	PicUrl         mysql.Str
	EffectUrl      mysql.Str
	Using          bool
	TimeLeft       int64 // 离到期还有多少秒(过期则是负数)
	SenderAvatar   string
	ReceiverAvatar string
}

func GetExtendedProperty(db *gorm.DB) (map[uint64]PropertyExt, error) {
	rp := res_m.ResProperty{}
	properties, err := rp.GetAll(mysql.Db)
	if err != nil {
		return nil, err
	}

	//获取座驾头像
	propertieAvatarMap, err := (&res_m.ResPropertyAvatar{}).GetAll(mysql.Db)

	userIds := []uint64{}
	for _, value := range propertieAvatarMap {
		if value.SendUserId > 0 {
			userIds = append(userIds, value.SendUserId)
		}
		if value.ReceiverUserId > 0 {
			userIds = append(userIds, value.ReceiverUserId)
		}
	}
	//获取用户信息
	users := []user_m.User{}
	if err := db.Model(&user_m.User{}).Where("id in (?)", userIds).Find(&users).Error; err != nil {
		return nil, myerr.WrapErr(err)
	}
	userAvatarMap := map[mysql.ID]string{}
	for _, r := range users {
		userAvatarMap[r.ID] = r.Avatar
	}

	result := map[uint64]PropertyExt{}
	for _, r := range properties {

		var senderAvatar string = ""
		var receiverAvatar string = ""
		if propertieAvatar, flag := propertieAvatarMap[r.ID]; flag {
			if propertieAvatar.SendUserId > 0 {
				if avatar, flag := userAvatarMap[propertieAvatar.SendUserId]; flag {
					senderAvatar = avatar
				}
			}
			if propertieAvatar.ReceiverUserId > 0 {
				if avatar, flag := userAvatarMap[propertieAvatar.ReceiverUserId]; flag {
					receiverAvatar = avatar
				}
			}
		}

		result[r.ID] = PropertyExt{
			Id:             r.ID,
			PicUrl:         r.PicUrl,
			EffectUrl:      r.EffectUrl,
			SenderAvatar:   senderAvatar,
			ReceiverAvatar: receiverAvatar,
		}
	}
	return result, nil
}