package db

import (
	"applet/app/db/model"
	"applet/app/md"
	"applet/app/utils"
	"applet/app/utils/logx"
	"errors"
	"xorm.io/xorm"
)

// UserProfileFindByArkID is get userprofile by arkid
func UserProfileFindByArkID(Db *xorm.Engine, id interface{}) (*model.UserProfile, error) {
	var m model.UserProfile
	if has, err := Db.Where("arkid_uid = ?", id).Get(&m); err != nil || has == false {
		return nil, logx.Warn(err)
	}
	return &m, nil
}
func UserProfileFindByArkToken(Db *xorm.Engine, id interface{}) (*model.UserProfile, error) {
	var m model.UserProfile
	if has, err := Db.Where("arkid_token<>'' and arkid_token = ?", id).Get(&m); err != nil || has == false {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UserProfileFindByInviteCode is get userprofile by InviteCode
func UserProfileFindByInviteCode(Db *xorm.Engine, code string) (*model.UserProfile, error) {
	var m model.UserProfile
	if has, err := Db.Where("invite_code = ?", code).Get(&m); err != nil || has == false {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UserProfileFindByInviteCode is get userprofile by InviteCode
func UserProfileFindByCustomInviteCode(Db *xorm.Engine, code string) (*model.UserProfile, error) {
	var m model.UserProfile
	if has, err := Db.Where("custom_invite_code = ?", code).Get(&m); err != nil || has == false {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UserProfileFindByInviteCodes is get userprofile by InviteCode
func UserProfileFindByInviteCodes(Db *xorm.Engine, codes ...string) (*[]model.UserProfile, error) {
	var m []model.UserProfile
	if err := Db.In("invite_code", codes).Find(&m); err != nil {
		return nil, logx.Warn(err)
	}
	return &m, nil
}
func UserProfileFindByAll(Db *xorm.Engine) (*[]model.UserProfile, error) {
	var m []model.UserProfile
	if err := Db.Find(&m); err != nil {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UserProfileFindByCustomInviteCodes is get userprofile by CustomInviteCode
func UserProfileFindByCustomInviteCodes(Db *xorm.Engine, codes ...string) (*[]model.UserProfile, error) {
	var m []model.UserProfile
	if err := Db.In("custom_invite_code", codes).Find(&m); err != nil {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UserProfileFindByID search user_profile by userid
func UserProfileFindByID(Db *xorm.Engine, id interface{}) (*model.UserProfile, error) {
	var m model.UserProfile
	if has, err := Db.Where("uid = ?", id).Get(&m); err != nil || has == false {
		return nil, logx.Warn(err)
	}
	return &m, nil
}
func UserProfileFindAll(Db *xorm.Engine) (*[]model.UserProfile, error) {
	var m []model.UserProfile
	if err := Db.Where("invite_code='' and uid>=0").Asc("uid").Find(&m); err != nil {
		return nil, logx.Warn(err)
	}
	return &m, nil
}
func UserProfileFindByIDsToStr(Db *xorm.Engine, uids []string) (*[]model.UserProfile, error) {
	var m []model.UserProfile
	if err := Db.In("uid", uids).Find(&m); err != nil {
		return nil, logx.Warn(err)
	}
	return &m, nil
}
func UserProfileFindByIDSess(sess *xorm.Session, id interface{}) (*model.UserProfile, error) {
	var m model.UserProfile
	if has, err := sess.Where("uid = ?", id).Get(&m); err != nil || has == false {
		return nil, logx.Warn(err)
	}
	return &m, nil
}
func UserProfileFindByPID(Db *xorm.Engine, id interface{}) (*model.UserProfile, error) {
	var m model.UserProfile
	if has, err := Db.Where("parent_uid = ?", id).Get(&m); err != nil || has == false {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UserProfileOrderByNew 找最新的记录
func UserProfileOrderByNew(Db *xorm.Engine) (*model.UserProfile, error) {
	var m model.UserProfile
	if has, err := Db.Where("invite_code != ''").OrderBy("uid desc").Get(&m); err != nil || has == false {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UserProfileFindByTaobaoOpenID search user_profile ByTaobaoOpenID
func UserProfileFindByTaobaoOpenID(Db *xorm.Engine, openid interface{}) (*model.UserProfile, error) {
	var m model.UserProfile
	if has, err := Db.Where("third_party_taobao_oid = ?", openid).Get(&m); err != nil || has == false {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UserProfileFindByQQOpenID search user_profile ByTaobaoOpenID
func UserProfileFindByQQOpenID(Db *xorm.Engine, openid interface{}) (*model.UserProfile, error) {
	var m model.UserProfile
	if has, err := Db.Where("third_party_qq_openid = ?", openid).Get(&m); err != nil || has == false {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UserProfileFindByAppleToken search user_profile AppleToken
func UserProfileFindByAppleToken(Db *xorm.Engine, token interface{}) (*model.UserProfile, error) {
	var m model.UserProfile
	if has, err := Db.Where("third_party_apple_token = ?", token).Get(&m); err != nil || has == false {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UserProfileFindByWeChatOpenID search user_profile By  微信openid
func UserProfileFindByWeChatOpenID(Db *xorm.Engine, openid interface{}) (*model.UserProfile, error) {
	var m model.UserProfile
	if has, err := Db.Where("third_party_wechat_openid = ?", openid).Get(&m); err != nil || has == false {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UserProfileFindByWeChatMiniOpenID search user_profile By 小程序openid
func UserProfileFindByWeChatMiniOpenID(Db *xorm.Engine, openid interface{}) (*model.UserProfile, error) {
	var m model.UserProfile
	if has, err := Db.Where("third_party_wechat_mini_openid = ?", openid).Get(&m); err != nil || has == false {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UserProfileFindByWeChatUnionID search user_profile By 微信唯一id
func UserProfileFindByWeChatUnionID(Db *xorm.Engine, openid interface{}) (*model.UserProfile, error) {
	if openid == "" {
		return nil, errors.New("不存在")
	}
	var m model.UserProfile
	if has, err := Db.Where("third_party_wechat_unionid = ? ", openid).Get(&m); err != nil || has == false {
		return nil, logx.Warn(err)
	}
	return &m, nil
}
func UserProfileFindByAccAlipay(Db *xorm.Engine, accAlipay string, uid int) (bool, error) {
	if has, err := Db.Where("acc_alipay = ? and uid <>?", accAlipay, uid).Exist(&model.UserProfile{}); err != nil || has == false {
		return false, logx.Warn(err)
	}
	return true, nil
}

// UserProfileisExistByTaobaoOpenID is exist by Taobao
func UserProfileisExistByTaobaoOpenID(Db *xorm.Engine, openid string) (bool, error) {
	has, err := Db.Where("third_party_taobao_oid = ?", openid).Exist(&model.UserProfile{})

	if err != nil {
		return false, err
	}
	return has, nil
}
func UserProfileisThirdPartyWechatH5Openid(Db *xorm.Engine, openid string) (*model.UserProfile, error) {
	var user model.UserProfile
	has, err := Db.Where("third_party_wechat_h5_openid = ? and third_party_wechat_h5_openid<>''", openid).Get(&user)

	if err != nil || has == false {
		return nil, err
	}
	return &user, nil
}

// UserProfileisExistByQQOpenID is exist by QQ openid
func UserProfileisExistByQQOpenID(Db *xorm.Engine, openid string) (bool, error) {
	has, err := Db.Where("third_party_qq_openid = ?", openid).Exist(&model.UserProfile{})

	if err != nil {
		return false, err
	}
	return has, nil
}

// UserProfileisExistByAppleToken is exist by apple token
func UserProfileisExistByAppleToken(Db *xorm.Engine, token string) (bool, error) {
	has, err := Db.Where("third_party_apple_token = ?", token).Exist(&model.UserProfile{})

	if err != nil {
		return false, err
	}
	return has, nil
}

// UserProfileisExistByWeChatOpenID is exist by Wecaht openid
func UserProfileisExistByWeChatOpenID(Db *xorm.Engine, openid string) (bool, error) {
	has, err := Db.Where("third_party_wechat_openid = ?", openid).Exist(&model.UserProfile{})

	if err != nil {
		return false, err
	}
	return has, nil
}

// UserProfileisExistByWeChatMiniOpenID is exist by Wecaht openid
func UserProfileisExistByWeChatMiniOpenID(Db *xorm.Engine, openid string) (bool, error) {
	has, err := Db.Where("third_party_wechat_mini_openid = ?", openid).Exist(&model.UserProfile{})

	if err != nil {
		return false, err
	}
	return has, nil
}

// UserProfileisExistByWeChatUnionID is exist by Wecaht openid
func UserProfileisExistByWeChatUnionID(Db *xorm.Engine, openid string) (bool, error) {
	if openid == "" {
		return false, errors.New("不存在")
	}
	has, err := Db.Where("third_party_wechat_unionid = ? ", openid).Exist(&model.UserProfile{})

	if err != nil {
		return false, err
	}
	return has, nil
}

// UserProfileisExistByRelationIDAndSpecialID is exist by RelationIdAndSpecialId
func UserProfileisExistByRelationIDAndSpecialID(Db *xorm.Engine, SpecialID, RelationID int64) (bool, error) {
	has, err := Db.Where("acc_taobao_self_id = ? AND acc_taobao_share_id = ?", SpecialID, RelationID).Exist(&model.UserProfile{})

	if err != nil {
		return false, err
	}
	return has, nil
}

// UserProfileisExistBySpecialID is exist by SpecialId
func UserProfileisExistBySpecialID(Db *xorm.Engine, SpecialID string) (bool, error) {
	has, err := Db.Where("acc_taobao_self_id = ? ", SpecialID).Exist(&model.UserProfile{})

	if err != nil {
		return false, err
	}
	return has, nil
}

// UserProfileCountByRelationID 统计relationID数量
func UserProfileCountByRelationID(Db *xorm.Engine) (total int64, err error) {
	relate := new(model.UserProfile)
	total, err = Db.Where("acc_taobao_share_id > 0").Count(relate)
	return
}

// UserProfileCountByPUID 统计直推下级数量
func UserProfileCountByPUID(Db *xorm.Engine, puid int) (total int64, err error) {
	relate := new(model.UserProfile)
	total, err = Db.Where("parent_uid = ?", puid).Count(relate)
	return
}

// UserProfileisExistByRelationID is exist by RelationID
func UserProfileisExistByRelationID(Db *xorm.Engine, RelationID string) (bool, error) {
	has, err := Db.Where("acc_taobao_share_id = ? ", RelationID).Exist(&model.UserProfile{})

	if err != nil {
		return false, err
	}
	return has, nil
}

// UserProfileFindByIDs is in sql by ids
func UserProfileFindByIDs(Db *xorm.Engine, uids ...int) (*[]model.UserProfile, error) {
	var m []model.UserProfile
	if err := Db.In("uid", uids).Find(&m); err != nil {
		return nil, logx.Warn(err)
	}
	return &m, nil
}
func UserProfileFindByIDsStr(Db *xorm.Engine, uids []string) (*[]model.UserProfile, error) {
	var m []model.UserProfile
	if err := Db.In("uid", uids).Find(&m); err != nil {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UserProfileByPuid search user_profile by parent_uid
func UserProfileByPuid(Db *xorm.Engine, puid interface{}) (*[]model.UserProfile, error) {
	var m []model.UserProfile
	if err := Db.Where("parent_uid = ?", puid).Find(&m); err != nil {
		return nil, logx.Warn(err)
	}
	return &m, nil
}
func UserProfileByPuidWithSess(sess *xorm.Session, puid interface{}) (*[]model.UserProfile, error) {
	var m []model.UserProfile
	if err := sess.Where("parent_uid = ?", puid).Find(&m); err != nil {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UsersProfileInByIds is profiles by ids
func UsersProfileInByIds(Db *xorm.Engine, ids []int, limit, start int) (*[]model.UserProfile, error) {
	var m []model.UserProfile
	if limit == 0 && start == 0 {
		if err := Db.In("uid", ids).Find(&m); err != nil {
			return nil, logx.Warn(err)
		}
		return &m, nil
	}
	if err := Db.In("uid", ids).Limit(limit, start).Find(&m); err != nil {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UsersProfileInByUIDByisVerify is In查询 以及是否是有效用户
func UsersProfileInByUIDByisVerify(Db *xorm.Engine, ids []int, isVerify interface{}) (*[]model.UserProfile, error) {
	var m []model.UserProfile
	if err := Db.In("uid", ids).Where("is_verify = ?", isVerify).
		Find(&m); err != nil {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UsersProfileInByIdsByDesc is 根据某列 降序
func UsersProfileInByIdsByDesc(Db *xorm.Engine, ids []int, limit, start int, c string) (*[]model.UserProfile, error) {
	var m []model.UserProfile
	if limit == 0 && start == 0 {
		if err := Db.In("uid", ids).Desc(c).Find(&m); err != nil {
			return nil, logx.Warn(err)
		}
		return &m, nil
	}
	if err := Db.In("uid", ids).Desc(c).Limit(limit, start).Find(&m); err != nil {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UsersProfileInByIdsByAsc is 根据某列 升序
func UsersProfileInByIdsByAsc(Db *xorm.Engine, ids []int, limit, start int, c string) (*[]model.UserProfile, error) {
	var m []model.UserProfile
	if limit == 0 && start == 0 {
		if err := Db.In("uid", ids).Asc(c).Find(&m); err != nil {
			return nil, logx.Warn(err)
		}
		return &m, nil
	}
	if err := Db.In("uid", ids).Asc(c).Limit(limit, start).Find(&m); err != nil {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UsersProfileByAll is 查询所有分享id大于0的数据
func UsersProfileByTaobaoShateIdNotNull(Db *xorm.Engine, limit, start int) (*[]model.UserProfile, error) {
	var m []model.UserProfile
	if err := Db.Where("acc_taobao_share_id > 0").Limit(limit, start).Find(&m); err != nil {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// UserProfileIsExistByUserID is mobile exist
func UserProfileIsExistByUserID(Db *xorm.Engine, id int) (bool, error) {
	has, err := Db.Where("uid = ?", id).Exist(&model.UserProfile{})
	if err != nil {
		return false, err
	}
	return has, nil
}

// UserProfileIsExistByInviteCode is exist ?
func UserProfileIsExistByInviteCode(Db *xorm.Engine, code string) (bool, error) {
	has, err := Db.Where("invite_code = ?", code).Exist(&model.UserProfile{})
	if err != nil {
		return false, err
	}
	return has, nil
}

// UserProfileIsExistByCustomInviteCode is exist ?
func UserProfileIsExistByCustomInviteCode(Db *xorm.Engine, code string) (bool, error) {
	has, err := Db.Where("custom_invite_code = ?", code).Exist(&model.UserProfile{})
	if err != nil {
		return false, err
	}
	return has, nil
}

// UserProfileInsert is insert user
func UserProfileInsert(Db *xorm.Engine, userProfile *model.UserProfile) (int64, error) {
	affected, err := Db.Insert(userProfile)
	if err != nil {
		return 0, err
	}
	return affected, nil
}

// UserProfileUpdate is update userprofile
func UserProfileUpdate(Db *xorm.Engine, uid interface{}, userProfile *model.UserProfile, forceCols ...string) (int64, error) {
	var (
		affected int64
		err      error
	)
	if forceCols != nil {
		affected, err = Db.Where("uid=?", uid).Cols(forceCols...).Update(userProfile)
	} else {
		affected, err = Db.Where("uid=?", uid).AllCols().Omit("fin_valid,parent_uid").Update(userProfile)
	}

	if err != nil {
		return 0, logx.Warn(err)
	}
	return affected, nil
}
func UserProfileUpdateWithSess(sess *xorm.Session, uid interface{}, userProfile *model.UserProfile, forceCols ...string) (int64, error) {
	var (
		affected int64
		err      error
	)
	if forceCols != nil {
		affected, err = sess.Where("uid=?", uid).Cols(forceCols...).Update(userProfile)
	} else {
		affected, err = sess.Where("uid=?", uid).AllCols().Omit("fin_valid").Update(userProfile)
	}

	if err != nil {
		return 0, logx.Warn(err)
	}
	return affected, nil
}

// UserProfileUpdateByArkID is update userprofile
func UserProfileUpdateByArkID(Db *xorm.Engine, arkid interface{}, userProfile *model.UserProfile, forceCols ...string) (int64, error) {
	var (
		affected int64
		err      error
	)
	if forceCols != nil {
		affected, err = Db.Where("arkid_uid=?", arkid).Cols(forceCols...).Update(userProfile)
	} else {
		affected, err = Db.Where("arkid_uid=?", arkid).Update(userProfile)
	}
	if err != nil {
		return 0, logx.Warn(err)
	}
	return affected, nil
}

// UserProfileDelete is delete user profile
func UserProfileDelete(Db *xorm.Engine, uid interface{}) (int64, error) {
	return Db.Where("uid = ?", uid).Delete(model.UserProfile{})
}
func UserProfileDeleteWithSess(sess *xorm.Session, uid interface{}) (int64, error) {
	return sess.Where("uid = ?", uid).Delete(model.UserProfile{})
}
func UserProfileFindByIdWithSession(session *xorm.Session, uid int) (*model.UserProfile, error) {
	var m model.UserProfile
	if has, err := session.Where("uid = ?", uid).Get(&m); err != nil || has == false {
		return nil, logx.Warn(err)
	}
	return &m, nil
}

// 在事务中更新用户信息
func UserProfileUpdateWithSession(session *xorm.Session, uid interface{}, userProfile *model.UserProfile, forceCols ...string) (int64, error) {
	var (
		affected int64
		err      error
	)
	if forceCols != nil {
		affected, err = session.Where("uid=?", uid).Cols(forceCols...).Update(userProfile)
	} else {
		affected, err = session.Where("uid=?", uid).Omit("fin_valid").Update(userProfile)
	}
	if err != nil {
		return 0, logx.Warn(err)
	}
	return affected, nil
}

// 根据uid获取md.user
func UserAllInfoByUid(Db *xorm.Engine, uid interface{}) (*md.User, error) {
	u, err := UserFindByID(Db, uid)
	if err != nil {
		return nil, err
	}
	if u == nil {
		return nil, errors.New("user is nil")
	}
	up, err := UserProfileFindByID(Db, uid)
	if err != nil {
		return nil, err
	}
	if utils.AnyToInt64(uid) == 0 {
		userLevel, err := UserLevelInIDescByWeightLowWithOne(Db)
		if err != nil {
			return nil, err
		}
		if userLevel != nil {
			u.Level = userLevel.Id
		}
	}
	// 获取user 等级
	ul, err := UserLevelByID(Db, u.Level)
	if u.Uid == 0 {
		one, err := UserLevelInIDescByWeightLowWithOne(Db)
		if err != nil {
			return nil, err
		}
		ul = one
	}
	if err != nil {
		return nil, err
	}

	user := &md.User{
		Info:    u,
		Profile: up,
		Level:   ul,
	}
	return user, nil
}

// UpdateUserProfileFinValid 更新用户余额
func UpdateUserProfileFinValid(Db *xorm.Engine, uid interface{}, newAmount string) error {
	update, err := Db.Where("uid=?", uid).Update(&model.UserProfile{FinValid: newAmount})
	if err != nil {
		return err
	}
	if update != 1 {
		return errors.New("更新失败")
	}

	return nil
}

// UpdateUserProfileFinValidWithSess 事务更新用户余额
func UpdateUserProfileFinValidWithSess(sess *xorm.Session, uid interface{}, newAmount string) error {
	update, err := sess.Where("uid=?", uid).Update(&model.UserProfile{FinValid: newAmount})
	if err != nil {
		return err
	}
	if update != 1 {
		return errors.New("更新失败")
	}

	return nil
}
