package hook

import (
	"context"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/gogf/gf/v2/os/gtimer"
	"hotgo/internal/consts"
	"hotgo/internal/library/contexts"
	"hotgo/utility/simple"
	"sync"
	"time"
)

type visitor struct {
	lastSeen *gtime.Time
}

var (
	visitors = make(map[int64]*visitor)
	mtx      sync.Mutex
)

// Run a background goroutine to remove old entries from the visitors map.
func init() {
	go cleanupVisitors()
}

// Every minute check the map for visitors that haven't been seen for
// more than 3 minutes and delete the entries.
func cleanupVisitors() {
	gtimer.AddSingleton(gctx.New(), time.Minute, func(ctx context.Context) {
		mtx.Lock()
		for memberId, v := range visitors {
			if gtime.Now().Sub(v.lastSeen) > 3*time.Minute {
				delete(visitors, memberId)
			}
		}
		mtx.Unlock()
	})
}

func allow(memberId int64) bool {
	mtx.Lock()
	defer mtx.Unlock()
	v, exists := visitors[memberId]
	if !exists {
		visitors[memberId] = &visitor{gtime.Now()}
		return true
	}

	if gtime.Now().Sub(v.lastSeen) > time.Second*3 {
		v.lastSeen = gtime.Now()
		return true
	}
	return false
}

// lastAdminActive 更新后台用户最后活跃
func (s *sHook) lastAdminActive(r *ghttp.Request) {
	if r.IsFileRequest() {
		return
	}

	var (
		ctx    = contexts.Detach(r.Context())
		member = contexts.GetUser(ctx)
	)

	if member == nil || member.App != consts.AppAdmin {
		return
	}

	if allow(member.Id) {
		simple.SafeGo(ctx, func(ctx context.Context) {
			_, err := g.Model("admin_member").
				Ctx(ctx).
				Where("id", member.Id).
				Data(g.Map{"last_active_at": gtime.Now()}).
				Update()
			if err != nil {
				g.Log().Warningf(ctx, "hook lastActive err:%+v, memberId:%v", err, member.Id)
			}
		})
	}
}
