package middleware

import (
	"bytes"
	"encoding/json"
	"io"
	"net/http"
	"net/url"
	"strings"
	"sundynix-go/global"
	"sundynix-go/model/system"
	"sundynix-go/service"
	"sundynix-go/utils/auth"
	"sync"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

var operationService = service.GroupApp.SystemServiceGroup.OperationRecordService

var respPool sync.Pool
var bufferSize = 1024

func init() {
	respPool = sync.Pool{
		New: func() interface{} {
			return make([]byte, bufferSize)
		},
	}
}

func OperationRecord() gin.HandlerFunc {
	return func(c *gin.Context) {
		var body []byte
		var userId string
		if c.Request.Method != http.MethodGet {
			var err error
			body, err = io.ReadAll(c.Request.Body)
			if err != nil {
				global.Logger.Error("read body from request error:", zap.Error(err))
			} else {
				c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
			}
		} else {
			query := c.Request.URL.RawQuery
			query, _ = url.QueryUnescape(query)
			split := strings.Split(query, "&")
			m := make(map[string]string)
			for _, v := range split {
				kv := strings.Split(v, "=")
				if len(kv) == 2 {
					m[kv[0]] = kv[1]
				}
			}
			body, _ = json.Marshal(&m)
		}
		claims, _ := auth.GetClaims(c)
		if claims != nil && claims.BaseClaims.ID != "" {
			userId = claims.BaseClaims.ID
		} else {
			userId = c.Request.Header.Get("x-user-id")
		}
		record := system.SysOperationRecord{
			Ip:     c.ClientIP(),
			Method: c.Request.Method,
			Path:   c.Request.URL.Path,
			Agent:  c.Request.UserAgent(),
			Body:   string(body),
			UserId: userId,
		}

		if err := operationService.CreateOperationRecord(record); err != nil {
			global.Logger.Error("create operation record error:", zap.Error(err))
		}
	}
}
