package shared

import (
	"hyapp-admin-server/internal/middleware"
	"hyapp-admin-server/internal/model"

	"github.com/gin-gonic/gin"
)

type OperationEvent struct {
	RequestID  string
	UserID     uint
	Username   string
	Action     string
	Resource   string
	ResourceID string
	Method     string
	Path       string
	IP         string
	UserAgent  string
	Status     string
	HTTPStatus int
	RiskLevel  string
	LatencyMS  int64
	Detail     string
}

type OperationLogger interface {
	CreateOperationLog(log model.OperationLog) error
	LogOperation(event OperationEvent) error
}

func OperationLog(c *gin.Context, logger OperationLogger, action string, resource string, status string, detail string) {
	OperationLogWithResourceID(c, logger, action, resource, c.Param("id"), status, detail)
}

// OperationLogWithResourceID is the explicit audit entry point for routes whose target id
// does not use the shared ":id" path parameter name.
func OperationLogWithResourceID(c *gin.Context, logger OperationLogger, action string, resource string, resourceID string, status string, detail string) {
	if logger == nil {
		return
	}
	// MarkAuditLogged keeps middleware from creating a second generic row for this write.
	middleware.MarkAuditLogged(c)
	_ = logger.LogOperation(OperationEvent{
		RequestID:  middleware.CurrentRequestID(c),
		UserID:     middleware.CurrentUserID(c),
		Username:   middleware.CurrentUsername(c),
		Action:     action,
		Resource:   resource,
		ResourceID: resourceID,
		Method:     c.Request.Method,
		Path:       c.Request.URL.Path,
		IP:         c.ClientIP(),
		UserAgent:  c.Request.UserAgent(),
		Status:     status,
		HTTPStatus: c.Writer.Status(),
		Detail:     detail,
	})
}
