package repository

import (
	"context"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"mylomen_server/common/dto"
	"time"
)

// UserDO 游戏帐号表
type UserDO struct {
	Id uint64 `gorm:"column:id;type:bigint(20) unsigned;primary_key;AUTO_INCREMENT" json:"id"`
	Sn string `gorm:"column:sn;type:varchar(64);comment:sn;NOT NULL" json:"sn"`

	Account    *string `gorm:"column:account;type:varchar(64);comment:账号;NOT NULL" json:"account"`
	Pwd        *string `gorm:"column:pwd;type:varchar(128);comment:密码;NOT NULL" json:"pwd"`
	NickName   *string `gorm:"column:nickname;type:varchar(64);nickname:昵称" json:"nickname"`
	Avatar     *string `gorm:"column:avatar;type:varchar(128);comment:头像" json:"avatar"`
	Gender     uint    `gorm:"column:gender;type:smallint(4) unsigned;default:0;comment:性别。0:未知 ;1:男;2:女; 3:其他" json:"gender"`
	Phone      *string `gorm:"column:phone;type:varchar(16);comment:手机号码" json:"phone"`
	WxId       *string `gorm:"column:wx_id;type:varchar(16);comment:微信unionId" json:"wx_id"`
	QqId       *string `gorm:"column:qq_id;type:varchar(16);comment:qqId" json:"qq_id"`
	Email      *string `gorm:"column:email;type:varchar(64);comment:email" json:"email"`
	GoogleId   *string `gorm:"column:google_id;type:varchar(32);comment:GoogleId" json:"google_id"`
	FacebookId *string `gorm:"column:facebook_id;type:varchar(32);comment:FacebookId" json:"facebook_id"`

	VipType    uint    `gorm:"column:vip_type;type:smallint(4) unsigned;default:0;comment:会员类型:0:非会员;1:普通会员;2:永久会员;NOT NULL" json:"vip_type"`
	VipExpired *uint64 `gorm:"column:vip_expired;type:smallint(4) unsigned;default:0;comment:会员过期时间;NOT NULL" json:"vip_expired"`

	RegisterSource  *string `gorm:"column:register_source;type:varchar(16);comment:注册来源" json:"register_source"`
	LatestIp        *string `gorm:"column:latest_ip;type:varchar(32);comment:最近登录的ip" json:"latest_ip"`
	LatestLoginTime uint64  `gorm:"column:latest_login_time;type:varchar(32);comment:最近登录的时间戳" json:"latest_login_time"`

	Status     uint      `gorm:"column:status;type:smallint(4) unsigned;default:0;comment:状态。0:正常;1:冻结;NOT NULL" json:"status"`
	Deleted    bool      `gorm:"column:deleted;type:smallint(4) unsigned;default:0;comment:逻辑删除。 0:未删除;1:已删除;NOT NULL" json:"deleted"`
	Remark     *string   `gorm:"column:remark;type:varchar(64);comment:备注" json:"remark"`
	CreateTime time.Time `gorm:"column:create_time;type:timestamp;default:CURRENT_TIMESTAMP;comment:创建时间;NOT NULL" json:"create_time"`
	UpdateTime time.Time `gorm:"column:update_time;type:timestamp;default:CURRENT_TIMESTAMP;comment:更新时间;NOT NULL" json:"update_time"`
}

func (m *UserDO) TableName() string {
	return "user_base"
}

type userRepositoryImpl struct {
}

func (rp *userRepositoryImpl) FindByReq(ctx context.Context, req dto.LoginReq) *UserDO {
	if req.Account != nil {
		return rp.FindByAccount(ctx, *req.Account)
	}
	if req.Email != nil {
		return rp.FindByEmail(ctx, *req.Email)
	}
	if req.Phone != nil {
		return rp.FindByPhone(ctx, *req.Phone)
	}

	if req.WxId != nil {
		return rp.FindByWxId(ctx, *req.WxId)
	}
	if req.QqId != nil {
		return rp.FindByQqId(ctx, *req.QqId)
	}

	if req.GoogleId != nil {
		return rp.FindByGoogleId(ctx, *req.GoogleId)
	}
	if req.FacebookId != nil {
		return rp.FindByFacebookId(ctx, *req.FacebookId)
	}
	return nil
}

func (rp *userRepositoryImpl) FindById(ctx context.Context, id int64) *UserDO {
	//验证参数
	if id <= 0 {
		return nil
	}
	db, ok := ctx.Value("db").(*gorm.DB)
	if !ok {
		db = Db
	}
	var model UserDO
	sqlErr := db.Model(&model).Where("id=?", id).First(&model).Error
	if sqlErr != nil {
		return nil
	}
	return &model
}

func (rp *userRepositoryImpl) FindBySn(ctx context.Context, sn string) *UserDO {
	//验证参数
	if sn == "" || len(sn) > 16 {
		return nil
	}
	db, ok := ctx.Value("db").(*gorm.DB)
	if !ok {
		db = Db
	}
	var model UserDO
	sqlErr := db.Model(&model).Where("sn=?", sn).First(&model).Error
	if sqlErr != nil {
		return nil
	}
	return &model
}

func (rp *userRepositoryImpl) FindByAccount(ctx context.Context, account string) *UserDO {
	//验证参数
	if account == "" || len(account) > 32 {
		return nil
	}
	db, ok := ctx.Value("db").(*gorm.DB)
	if !ok {
		db = Db
	}
	var model UserDO
	sqlErr := db.Model(&model).Where("account=?", account).First(&model).Error
	if sqlErr != nil {
		return nil
	}
	return &model
}

func (rp *userRepositoryImpl) FindByEmail(ctx context.Context, email string) *UserDO {
	//验证参数
	if email == "" || len(email) > 64 {
		return nil
	}
	db, ok := ctx.Value("db").(*gorm.DB)
	if !ok {
		db = Db
	}
	var model UserDO
	sqlErr := db.Model(&model).Where("email=?", email).First(&model).Error
	if sqlErr != nil {
		return nil
	}
	return &model
}

func (rp *userRepositoryImpl) FindByPhone(ctx context.Context, phone string) *UserDO {
	//验证参数
	if phone == "" || len(phone) > 16 {
		return nil
	}
	db, ok := ctx.Value("db").(*gorm.DB)
	if !ok {
		db = Db
	}
	var model UserDO
	sqlErr := db.Model(&model).Where("phone=?", phone).First(&model).Error
	if sqlErr != nil {
		return nil
	}
	return &model
}

func (rp *userRepositoryImpl) FindByWxId(ctx context.Context, wxId string) *UserDO {
	//验证参数
	if wxId == "" || len(wxId) > 16 {
		return nil
	}
	db, ok := ctx.Value("db").(*gorm.DB)
	if !ok {
		db = Db
	}
	var model UserDO
	sqlErr := db.Model(&model).Where("wx_id=?", wxId).First(&model).Error
	if sqlErr != nil {
		return nil
	}
	return &model
}

func (rp *userRepositoryImpl) FindByQqId(ctx context.Context, qqId string) *UserDO {
	//验证参数
	if qqId == "" || len(qqId) > 32 {
		return nil
	}
	db, ok := ctx.Value("db").(*gorm.DB)
	if !ok {
		db = Db
	}
	var model UserDO
	sqlErr := db.Model(&model).Where("qq_id=?", qqId).First(&model).Error
	if sqlErr != nil {
		return nil
	}
	return &model
}

func (rp *userRepositoryImpl) FindByGoogleId(ctx context.Context, googleId string) *UserDO {
	//验证参数
	if googleId == "" || len(googleId) > 32 {
		return nil
	}
	db, ok := ctx.Value("db").(*gorm.DB)
	if !ok {
		db = Db
	}
	var model UserDO
	sqlErr := db.Model(&model).Where("google_id=?", googleId).First(&model).Error
	if sqlErr != nil {
		return nil
	}
	return &model
}

func (rp *userRepositoryImpl) FindByFacebookId(ctx context.Context, facebookId string) *UserDO {
	//验证参数
	if facebookId == "" || len(facebookId) > 32 {
		return nil
	}
	db, ok := ctx.Value("db").(*gorm.DB)
	if !ok {
		db = Db
	}
	var model UserDO
	sqlErr := db.Model(&model).Where("facebook_id=?", facebookId).First(&model).Error
	if sqlErr != nil {
		return nil
	}
	return &model
}

// Create 创建用户
func (rp *userRepositoryImpl) Create(ctx context.Context, data *UserDO) error {
	db, ok := ctx.Value("db").(*gorm.DB)
	if !ok {
		db = Db
	}

	data.Deleted = false

	return db.Clauses(clause.OnConflict{
		Columns:   []clause.Column{{Name: "email"}},
		DoUpdates: clause.AssignmentColumns([]string{"deleted"}),
	}).Create(data).Error
}

// UpdateById 根据ID更新用户
func (rp *userRepositoryImpl) UpdateById(ctx context.Context, data *UserDO) error {
	db, ok := ctx.Value("db").(*gorm.DB)
	if !ok {
		db = Db
	}

	sqlErr := db.Model(data).Where("id=?", data.Id).Updates(data).Error

	if sqlErr != nil {
		return sqlErr
	}
	return nil
}