package system

import (
	"context"
	"kra/internal/biz/system"
	"time"

	"kra/pkg/database/pagination"

	"gorm.io/gorm"
)

type DataAccessLogPO struct {
	ID                                uint `gorm:"primaryKey"`
	CreatedAt                         time.Time
	UpdatedAt                         time.Time
	DeletedAt                         gorm.DeletedAt `gorm:"index"`
	EventType, TargetTable, Operation string
	UserID, AuthorityID               uint
	Scope                             int
	RequestID, Method, Path, Detail   string
}

func (DataAccessLogPO) TableName() string { return "sys_data_access_logs" }

func (r *auditRecorderRepo) RecordDataAccess(ctx context.Context, v *system.DataAccessLog) error {
	return r.data.DB().WithContext(ctx).Create(&DataAccessLogPO{EventType: v.EventType, TargetTable: v.TargetTable, Operation: v.Operation, UserID: v.UserID, AuthorityID: v.AuthorityID, Scope: v.Scope, RequestID: v.RequestID, Method: v.Method, Path: v.Path, Detail: v.Detail}).Error
}
func dataAccessFromPO(v DataAccessLogPO) *system.DataAccessLog {
	return &system.DataAccessLog{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, EventType: v.EventType, TargetTable: v.TargetTable, Operation: v.Operation, UserID: v.UserID, AuthorityID: v.AuthorityID, Scope: v.Scope, RequestID: v.RequestID, Method: v.Method, Path: v.Path, Detail: v.Detail}
}
func (r *auditQueryRepo) ListDataAccess(ctx context.Context, page, size int, q *system.DataAccessLog) ([]*system.DataAccessLog, int64, error) {
	db := r.data.DB().WithContext(ctx).Model(&DataAccessLogPO{})
	if q != nil {
		if q.EventType != "" {
			db = db.Where("event_type = ?", q.EventType)
		}
		if q.TargetTable != "" {
			db = db.Where("target_table LIKE ?", "%"+q.TargetTable+"%")
		}
	}
	var total int64
	if err := db.Count(&total).Error; err != nil {
		return nil, 0, err
	}
	var pos []DataAccessLogPO
	if err := pagination.ApplyRequired(db.Order("id desc"), page, size, 100).Find(&pos).Error; err != nil {
		return nil, 0, err
	}
	out := make([]*system.DataAccessLog, 0, len(pos))
	for _, po := range pos {
		out = append(out, dataAccessFromPO(po))
	}
	return out, total, nil
}
func (r *auditQueryRepo) DeleteDataAccess(ctx context.Context, ids []uint) error {
	return r.data.DB().WithContext(ctx).Delete(&DataAccessLogPO{}, "id IN ?", ids).Error
}
