package audit

import (
	"context"
	"database/sql"
	"encoding/json"
)

// Action type constants.
const (
	ActionKick         = "KICK"
	ActionBan          = "BAN"
	ActionUnban        = "UNBAN"
	ActionMute         = "MUTE"
	ActionUnmute       = "UNMUTE"
	ActionRoleCreate   = "ROLE_CREATE"
	ActionRoleUpdate   = "ROLE_UPDATE"
	ActionRoleDelete   = "ROLE_DELETE"
	ActionMemberRoles  = "MEMBER_ROLES_UPDATE"
	ActionChannelCreate = "CHANNEL_CREATE"
	ActionChannelUpdate = "CHANNEL_UPDATE"
	ActionChannelDelete = "CHANNEL_DELETE"
	ActionServerUpdate  = "SERVER_UPDATE"
	ActionMessageDelete = "MESSAGE_DELETE"
	ActionBulkDelete    = "BULK_DELETE"
)

// Logger writes audit log entries to the database.
type Logger struct {
	db *sql.DB
}

// NewLogger creates a new audit logger.
func NewLogger(db *sql.DB) *Logger {
	return &Logger{db: db}
}

// Log records a single audit entry.
func (l *Logger) Log(ctx context.Context, serverID, userID, actionType, targetType, targetID, reason string, changes map[string]interface{}) error {
	if l == nil || l.db == nil {
		return nil
	}
	var changesJSON []byte
	var err error
	if len(changes) > 0 {
		changesJSON, err = json.Marshal(changes)
		if err != nil {
			return err
		}
	}
	_, err = l.db.ExecContext(ctx, `
		INSERT INTO audit_log (server_id, user_id, action_type, target_type, target_id, reason, changes)
		VALUES ($1, $2, $3, $4, $5, $6, $7)
	`, serverID, userID, actionType, targetType, targetID, reason, changesJSON)
	return err
}
