package card_redeem_account

import (
	"context"
	"fmt"
	"kami/internal/consts"
	"kami/internal/dao"
	"kami/internal/model"
	"kami/internal/model/do"
	"kami/internal/model/entity"
	"kami/utility/config"
	"kami/utility/utils"

	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gcode"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/os/gmlock"
	"github.com/gogf/gf/v2/text/gstr"
)

func (a *sCardRedeemAccount) Add(ctx context.Context, input *model.RedeemAccountAddInput, tx gdb.TX) (err error) {
	m := dao.V1CardRedeemAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1())
	if tx != nil {
		m = m.TX(tx)
	}
	err = m.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		accountInfo, err2 := a.GetByCK(ctx, input.Cookie)
		if err2 != nil || len(accountInfo) > 0 {
			return gerror.NewCode(gcode.CodeValidationFailed, "账号已存在")
		}
		id := utils.GenerateRandomUUID()
		_, err2 = m.Insert(do.V1CardRedeemAccountInfo{
			Id:               id,
			Category:         input.Category,
			AccountStatus:    consts.RedeemAccountUsedStatusEnable,
			Status:           consts.RedeemAccountNormal,
			CreateUserId:     input.UserId,
			Cookie:           input.Cookie,
			Username:         input.Username,
			Nickname:         input.Nickname,
			Name:             input.Name,
			GroupId:          input.GroupId,
			Balance:          input.Balance,
			EffectiveBalance: 0,
			Remark:           input.Remark,
			MaxAmountLimit:   input.MaxAmountLimit,
			MaxCountLimit:    input.MaxCountLimit,
		})
		if err2 != nil {
			return err2
		}
		err2 = a.AddHistory(ctx, &model.RedeemAccountAddHistory{
			AccountId:        id,
			AccountName:      input.Name,
			Amount:           0,
			Balance:          input.Balance,
			EffectiveBalance: 0,
			OrderNo:          "",
			Remark:           fmt.Sprintf("初始余额：%.2f", input.Balance),
			OperationStatus:  consts.RedeemAccountOperationInitialize,
			Cookie:           input.Cookie,
		}, tx)
		return err2
	})
	return
}

func (a *sCardRedeemAccount) AddWithGroup(ctx context.Context, input *model.RedeemAccountAddInput, tx gdb.TX) (err error) {
	gmlock.LockFunc(fmt.Sprintf("CardRedeemLockAddWithGroup%d%s", input.GroupId, input.UserId), func() {
		data, _ := a.GetAccountByNameAndGroup(ctx, input.Name, input.GroupId, input.UserId, input.Category, tx)
		//如果存在就更新，否则就创建一个
		if data.Id == "" {
			err = a.Add(ctx, input, tx)
		} else {
			err = a.UpdateCookie(ctx, data.Id, input.Cookie, tx)
		}
	})
	return
}

// UpdateCookie 更新cookie
func (a *sCardRedeemAccount) UpdateCookie(ctx context.Context, id string, cookie string, tx gdb.TX) (err error) {
	m := dao.V1CardRedeemAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1())
	if tx != nil {
		m = m.TX(tx)
	}
	_, err = m.Where(dao.V1CardRedeemAccountInfo.Columns().Id, id).Update(do.V1CardRedeemAccountInfo{
		Cookie: cookie,
	})
	return
}

// GetAccountByNameAndGroup 判断当前名称和分组想同的记录是否存在
func (a *sCardRedeemAccount) GetAccountByNameAndGroup(ctx context.Context, name string, groupId int, createdUserId string, category consts.CardRedeemAccountCategory, tx gdb.TX) (data entity.V1CardRedeemAccountInfo, err error) {
	m := dao.V1CardRedeemAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1())
	if tx != nil {
		m = m.TX(tx)
	}
	data = entity.V1CardRedeemAccountInfo{}
	err = m.Where(dao.V1CardRedeemAccountInfo.Columns().Name, gstr.TrimAll(name)).Where(dao.V1CardRedeemAccountInfo.Columns().GroupId, groupId).
		Where(dao.V1CardRedeemAccountInfo.Columns().CreateUserId, createdUserId).Scan(&data)
	return
}

// Update 修改用户信息
func (a *sCardRedeemAccount) Update(ctx context.Context, data *model.RedeemAccountUpdateInput, tx gdb.TX) (err error) {
	m := dao.V1CardRedeemAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1())
	if tx != nil {
		m = m.TX(tx)
	}
	_, err = m.Where(dao.V1CardRedeemAccountInfo.Columns().Id, data.ID).Update(do.V1CardRedeemAccountInfo{
		Status:         data.Status,
		Name:           data.Name,
		Cookie:         data.Cookie,
		Remark:         data.Remark,
		GroupId:        data.GroupId,
		MaxAmountLimit: data.MaxAmountLimit,
		MaxCountLimit:  data.MaxCountLimit,
	})
	return
}

// Delete 删除账号
func (a *sCardRedeemAccount) Delete(ctx context.Context, id string, category consts.CardRedeemAccountCategory, tx gdb.TX) (err error) {
	m := dao.V1CardRedeemAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1())
	if tx != nil {
		m = m.TX(tx)
	}
	_, err = m.Where(dao.V1CardRedeemAccountInfo.Columns().Id, id).Where(dao.V1CardRedeemOrderInfo.Columns().Category, category).Delete()
	return
}
