package shared

import (
	"context"
	"fusenapi/model/gmodel"
	"fusenapi/utils/auth"
	"log"
	"time"

	"github.com/474420502/passer"
	sm "github.com/lni/dragonboat/v4/statemachine"
)

type CmdUpdate struct {
	UserId int64
}

// 上下文传递
type (
	ctxSM struct{}
	// ctxUserState struct{}
	ctxEntry struct{}
)

// 结构体异步传递后, 执行的注册函数, 实际上就是update的handler
var FsPasser *passer.Passer[sm.Result] = func() *passer.Passer[sm.Result] {

	fsPasser := passer.NewPasser[sm.Result]()
	fsPasser.RegisterPasser(&CmdUpdate{}, func(ctx context.Context, obj any) (sm.Result, error) {
		var result sm.Result

		cmd := obj.(*CmdUpdate)
		s := ctx.Value(ctxSM{}).(*FsStateMachine)
		e := ctx.Value(ctxEntry{}).(*sm.Entry)

		if old, ok := s.store[cmd.UserId]; ok {
			if time.Since(old.UpdateAt) <= time.Second {
				return result, nil
			}
		}

		// log.Println("update")
		models := gmodel.NewAllModels(s.gdb)
		user, err := models.FsUser.FindUserById(context.TODO(), cmd.UserId)
		if err != nil {
			log.Println(err)
		}

		userState := &UserState{
			UserId:   cmd.UserId,
			PwdHash:  auth.StringToHash(*user.PasswordHash),
			UpdateAt: time.Now(),
		}
		s.store[cmd.UserId] = userState

		err = userState.Encode(func(b []byte) error {
			e.Result.Data = b
			result.Data = b
			return nil
		})
		return result, err
	})

	return fsPasser
}()