package auditlog

import (
	"encoding/json"

	"hfb_sys/backend/internal/model"

	"gorm.io/datatypes"
	"gorm.io/gorm"
)

type Meta struct {
	IP        string
	UserAgent string
	RequestID string
}

type Entry struct {
	ActorType string
	ActorID   uint64
	Action    string
	BizType   string
	BizID     *uint64
	Meta      Meta
	Detail    map[string]any
}

// Append 在业务事务内写入审计日志，确保审计和业务状态一起提交或回滚。
func Append(tx *gorm.DB, entry Entry) error {
	raw, err := marshalDetail(entry.Detail, entry.Meta.RequestID)
	if err != nil {
		return err
	}
	row := model.AuditLog{
		ActorType: entry.ActorType,
		ActorID:   entry.ActorID,
		Action:    entry.Action,
		BizType:   entry.BizType,
		BizID:     entry.BizID,
		IP:        entry.Meta.IP,
		UserAgent: entry.Meta.UserAgent,
		Detail:    datatypes.JSON(raw),
	}
	return tx.Create(&row).Error
}

func marshalDetail(detail map[string]any, requestID string) ([]byte, error) {
	copied := make(map[string]any, len(detail)+1)
	for key, value := range detail {
		copied[key] = value
	}
	if requestID != "" {
		copied["request_id"] = requestID
	}
	return json.Marshal(copied)
}
