package dashboard

import (
	"cs-agent/internal/pkg/constants"
	"cs-agent/internal/pkg/dto/request"
	"cs-agent/internal/pkg/dto/response"
	"cs-agent/internal/pkg/httpx"
	"cs-agent/internal/pkg/utils"
	"cs-agent/internal/services"
	"time"

	"cs-agent/internal/pkg/httpx/params"

	"github.com/gin-gonic/gin"
	"github.com/mlogclub/simple/web"
)

func SessionAnyList(ctx *gin.Context) {
	if _, err := services.AuthService.RequirePermission(ctx, constants.PermissionSessionView); err != nil {
		httpx.WriteJSON(ctx, err)
		return
	}

	cnd := params.NewPagedSqlCnd(ctx,
		params.QueryFilter{ParamName: "userId"},
		params.QueryFilter{ParamName: "clientType"},
	).Desc("id")
	list, paging := services.LoginSessionService.FindPageByCnd(cnd)
	results := make([]response.SessionResponse, 0, len(list))
	for _, item := range list {
		username := ""
		if user := services.UserService.Get(item.UserID); user != nil {
			username = user.Username
		}
		results = append(results, response.SessionResponse{
			ID:         item.ID,
			UserID:     item.UserID,
			Username:   username,
			ClientType: item.ClientType,
			ClientIP:   item.ClientIP,
			UserAgent:  item.UserAgent,
			ExpiredAt:  item.ExpiredAt.Format(time.DateTime),
			RevokedAt:  utils.FormatTimePtr(item.RevokedAt),
			LastSeenAt: utils.FormatTimePtr(item.LastSeenAt),
		})
	}
	httpx.WriteJSON(ctx, &web.PageResult{Results: results, Page: paging})
	return
}

func SessionPostRevoke(ctx *gin.Context) {
	user, err := services.AuthService.RequirePermission(ctx, constants.PermissionSessionRevoke)
	if err != nil {
		httpx.WriteJSON(ctx, err)
		return
	}

	req := request.RevokeSessionRequest{}
	if err := params.ReadJSON(ctx, &req); err != nil {
		httpx.WriteJSON(ctx, err)
		return
	}
	if err := services.LoginSessionService.Revoke(req.ID, user.UserID, user.Username); err != nil {
		httpx.WriteJSON(ctx, err)
		return
	}
	httpx.WriteJSON(ctx, nil)
	return
}

func SessionPostRevokeByUser(ctx *gin.Context) {
	user, err := services.AuthService.RequirePermission(ctx, constants.PermissionSessionRevoke)
	if err != nil {
		httpx.WriteJSON(ctx, err)
		return
	}

	req := request.RevokeUserSessionsRequest{}
	if err := params.ReadJSON(ctx, &req); err != nil {
		httpx.WriteJSON(ctx, err)
		return
	}
	if err := services.LoginSessionService.RevokeByUser(req.UserID, user.UserID, user.Username); err != nil {
		httpx.WriteJSON(ctx, err)
		return
	}
	httpx.WriteJSON(ctx, nil)
	return
}
